How to query a JSON column using the -> operator in mariadb - php

I'm trying to get schedules comparing the json column data with following code in a Laravel project:
$schedules = Schedule::where('schedule_with->company_person', $contact_company_person->id)->get();
This generates SQL query like below:
select * from `schedules` where `schedule_with`->'$."company_person"' = 1;
While this works for MYSQL 5.7 and above but not working for MARIADB 10.5. But MARIADB already supports JSON column from 10.2 onward.
For MARIADB, following query works:
select * from schedules where JSON_Value(schedule_with, "$.company_person") = 3;
Is there some config changes required in Laravel to make it work?
I know it can be achieved with raw query, I'm curious about what am I missing?
Thank you,

No, there is no configuration change you can do to enable this.
To quote MariaDB's documentation on differences between 10.5 and MySQL (8):
MariaDB 10.5 does not support MySQL's JSON operators (-> and ->>).
"No ifs, no buts".
I guess you could do it with a regular expression replacement that edits the SQL that Laravel generates just before the SQL is executed, but that is both rather hard to execute and it seems too hacky to be worth it. A raw where query, by comparison, is not that unsightly:
$table->whereRaw('JSON_VALUE(schedule_with, ?) = ?', ['$.company_person', 3])

Related

Migrating from MySQL to MS SQL

I have a PHP (CODEIGNITER) application which is generally deployed on Apache/MySQL combination. I recently deployed it on IIS8 and MS SQL 11.0.2100.60
I migrated the tables and data by using ODBC connection to migrate to Access database and then again another ODBC connection to migrate to MS SQL. I modified the configurations of my PHP application (PHP.ini, database.php, db_driver.php) to make sure it connects properly and works on IIS.
I am having problem with SQL Syntax now. When I try to run the application it does not give me database connection error (which it was giving earlier) but when I try to log in to the application (it has user authentication) - I get the following error:
Error Number: 42000
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Incorrect syntax near '`'.
SELECT * from ctbl_events WHERE 2017-01-11 <= startdate AND `enddate` >= 2017-01-11 and status=0 ORDER BY `ctbl_events`.`id`
Filename: C:\inetpub\wwwroot\GMS\system\database\DB_driver.php
Line Number: 330
does this mean problem is with ` symbol and if yes would I have to manually go and modify all the SQL queries in my application (would be a gigantic task) or is there any way to handle this.
As far as I know, SQL Server does not support using backticks to escape table or column names (you can use brackets instead). You can easily try this by running a simple query like
select * from `ctbl_events`
If that doesn't work, you will almost certainly have to update all the queries to replace the backticks with brackets.
Second reason the query is probably failing is the dates in your query must be enclosed in quotes, and match SQL Server's date format (this is configurable, so you may need to experiment a little).
So, the query you're trying to run should look a little like this:
SELECT * from ctbl_events
WHERE '2017-01-11' <= startdate
AND [enddate] >= '2017-01-11'
and status=0
ORDER BY [ctbl_events].[id]
Though in this case, you don't really need the brackets around table or column names - it's best to agree a standard for this and stick to it.

PDOStatement::nextRowSet() is broken in MySQL 5.6.16 on Windows

This question without an accepted answer raises a catastrophic problem with MySQL that I am experiencing on MySQL version 5.6.16 on Windows in a modified form.
The problem is easily reproducible: I include it here (copied from the above-linked question, but with changes applicable to my code):
$pdo = /* connection stuff here */
$sql = "call test();"; // call stored procedure - see below
$statement = $connection->query($sql);
do {
$rowset = $statement->fetchAll(PDO::FETCH_ASSOC);
if($rowset) {
// Do stuff with $rowset
}
} while($statement->nextRowset());
Here is the definition of the stored procedure test:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`$$
CREATE PROCEDURE `test`()
BEGIN
SELECT 1; SELECT 2; SELECT 3; SELECT 4;
END$$
DELIMITER ;
The only difference between my code, and the above-linked code, is that I pack the SQL query into a stored procedure.
In my case, the while statement returns true four times, rather than three times (it should be just three times). After the fourth time, fetchAll(...) throws a SQLSTATE[HY000]: General error error.
Unfortunately, this problem is catastrophic. There is no other way with PDO to iterate to following rowsets other than using the nextRowSet() function. Therefore, I may revert to a previous version of MySQL in order to work around this issue.
I have found two links that seem to indicate this issue, listed here:
https://bugs.php.net/bug.php?id=67130 and
http://permalink.gmane.org/gmane.comp.php.devel/81518
I would appreciate a confirmation that this is, indeed, a bug with version 5.6.16 of MySQL on Windows. Even more, I would appreciate a workaround. Thanks.
I had same problem with PDO::nextRowset(), as it returns true even there are no more rowsets available, therefore when calling fetchAll(), it raises exception HY000. (tested on PHP 5.5.12 windows, Mysql 5.5.17 linux)
A workaround for this problem is to check number of columns with method PDO::columnCount() before fetching rowset. If it is non-zero, you have a valid rowset, and thus you could call PDO::fetchAll().
Even if PDO::nextRowset() reports true, columnCount() will report number of columns before moving to next rowset.
Example:
while ($objQuery->columnCount()) {
$tab[] = $objQuery->fetchAll(\PDO::FETCH_ASSOC);
$objQuery->nextRowset();
}
If the problem is being caused by multiple result sets, then maybe the best work around would be to find ways of avoiding multiple result sets in a single query.
For example, if the expected results are in the same format (which I expect they probably are because you intend to use the same code to deal with all of them) then you could potentially use UNION to compound the four queries together.
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4;
Failing that, you can execute a separate query for each SELECT and hand the result off to a function to do the processing.

Alternative to mssql_guid_string in PHP?

I found a couple of results similar to what I'm about to ask but unfortunately none of them provided a solution or direction to the problem I'm facing.
I'm reviewing a large SQL Server 2008 database and I'm running some blanket queries such as running a SELECT TOP(5) on every table to get an idea of the contents.
I've encountered some Binary(16) objects in the results in PHP and of course PHP isn't able to print a readable version of the id easily. I don't have the option of adding the MSSQL extension to make use of the mssql_guid_string function and I can't perform the convert in SQL as the select needs to be as generic as possible to work for every table. I'm doing a foreach on a list of tables to return the data and print it.
So my question is: Does anyone know of an alternative to mssql_guid_string in PHP??
The pseudo of what I'm trying to do would be;
1. SELECT TOP(5) * FROM table1
2. WHILE $row = sqlsrv_fetch_array{...
3. foreach $row as $col print $col
The id's in SQL look something like this -> 0xB0826E8A84CA6C418254E28BC0F749CF
When printed in PHP they look like this -> X÷Eòv˜H½XšÔÛé«Ù
Any help/thoughts would be greatly appreciated.
Steve
From the PHP side you can dump to hexadecimal and add a prefix:
echo '0x' . strtoupper(bin2hex($col));
From SQL Server you can probably cast to string (no idea about that).

MySQL Syntax Error When Using Data From MSSQL Imported Tables

I have imported a number of tables (structure and data) from an MSSQL DB into mysql - all data is in UTF8
I can pull data from the old tables, but when I use any of the data from the imported tables in a query from PHP I get a syntax error like this:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''data' at line 1
for this query
SELECT * FROM tableName WHERE field='data'
This only happens if executing the query from PHP, if I echo out the query from php and then copy, paste and execute the query from phpmyadmin then it runs fine.
Any ideas???
I'm using PHP 5.2.17 running on Apache 1.3.42 and MySQL 4.1.22-standard
If you using query like this then query should be :
E.G
"SELECT * FROM tableName WHERE field='data'";
or
'SELECT * FROM tableName WHERE field="data"';
Please check for "Field" data-type whether is Varchar or sumthing else!

mysql template in php

I come across this sql code in a php software.
What does the #section_filter mean?
Is that a valid mysql syntax? or just a templating system?
$filterid = ac_sql_select_one("
SELECT
id
FROM
#section_filter
WHERE
userid = '$ary[userid]'
AND
sectionid = 'article'
AND
conds = '$conds_esc'
");
Thanks
It is a valid sql syntax but the problem i suspect is that hash # character creates comments in sql queries hence this query might not execute.
Another possiblity is that the program that you saw this query in should be able to dynamically replace the #section_filter with some table name before it gets to mysql engine and then the query should run fine. This is the highest possibility in my view.
The # symbol is one way to express a comment in MySQL. So, this isn't a valid SQL statement as written, since the line:
#section_filter
would be completely ignored.

Categories