Using character # in SQL query request with PHP - php

I am using PHP for sending query request to GoogleBigQuery sql database.
The request would be similar like this:
SELECT namedcoord, COUNT(*)
FROM (
select REGEXP_REPLACE(REGEXP_EXTRACT(SPLIT(V2Locations,';'),r'^[2-5]#(.*?#.*?#.*?#.*?#.*?#.*?)#'), '^(.*?)#.*?#.*?#.*?#(.*?)#(.*?)', '\1;\2;\3') as namedcoord
from [gdelt-bq:gdeltv2.gkg]
where DATE>20150302000000 and DATE < 20150304000000 and V2Persons like '%Tsipras%'
)
where namedcoord is not null
group by namedcoord
ORDER BY 2 DESC
LIMIT 100
However, PHP can't handle the character # because it's treated as comment syntax.
Does anyone can help solve this problem?

Related

PHP Yii2 MYSQL query giving wrong output

I'm executing a PHP yii2 query to get records from the database but it's not working. But I directly executed the query in the MYSQL console then it gives me the expected output.
Normal SQL
SELECT * FROM `tbl_inbox` WHERE sender_id=778 AND recipient_id=736 OR sender_id=778 AND recipient_id=736 ORDER BY timestamp DESC LIMIT 1
Above query giving me expected result but when i change to Yii2 like :
$message=Inbox::find()->select(['message'])->where(['sender_id'=>$sender_id,'recipient_id'=>$recipient_id])->orWhere(['sender_id'=>$recipient_id,'recipient_id'=>$sender_id])->andWhere(['ad_id'=>$ad_id,'category'=>$category])->orderBy(['timestamp'=>SORT_DESC])->one();
It gives me the wrong result.
What is my logic :
I have a chat on my website and I need to get the last message order by timestamp. But sender_id and the recipient will be visa versa.
How to fix ?
There are significant differences between the normal SQL version of the query and the Yii version.
1) Selected fields
The normal SQL query selects all fields, but Yii version selects only message field.
This is because the normal SQL has SELECT * FROM ... but in Yii query you are calling select(['message']). If you want to select all fields you can leave the select() method call out or you can use select('*').
2) Your conditions are different
Considering operator priority your conditions in normal SQL are:
(sender_id=778 AND recipient_id=736)
OR (sender_id=778 AND recipient_id=736)
But in your Yii version of query:
(
(sender_id=778 AND recipient_id=736)
OR (sender_id=736 AND recipient_id=778)
) AND (
ad_id=$ad_id AND category=$category
)
In your normal SQL the both sides of OR condition are same but in your Yii version the values for sender/recipient are swapped in the second argument of OR operator.
Also there is extra part added by this call andWhere(['ad_id'=>$ad_id,'category'=>$category])
$message=Inbox::find()->select(['message'])->where(['sender_id'=>$sender_id,'recipient_id'=>$recipient_id])->orWhere(['sender_id'=>$recipient_id])->orWhere(['recipient_id'=>$sender_id])->andWhere(['ad_id'=>$ad_id,'category'=>$category])->orderBy(['timestamp'=>SORT_DESC])->one();
try this
I'm getting following sql
SELECT `message` FROM `user` WHERE ((((`sender_id`='2333') AND (`recipient_id`='23222')) OR (`sender_id`='23222')) OR (`recipient_id`='23333')) AND ((`ad_id`='10') AND (`category`='1')) ORDER BY `timestamp` DESC
you can check raw sql easily, then it will be mostly straight forward how Yii Query builder works.
use following code:
$rawSql = Inbox::find()
...
->createCommand()->getRawSql();
I would change your code into this:
$message=Inbox::find()
->select(['message'])
->where([
'and',
[
'or',
['sender_id'=>$sender_id,'recipient_id'=>$recipient_id],
['sender_id'=>$recipient_id,'recipient_id'=>$sender_id]
],
['ad_id'=>$ad_id,'category'=>$category]
])
->orderBy(['timestamp'=>SORT_DESC])->one();

MYSQLi SELECT statement malformed or misordered

Using the following table "technotes":
And, using the following SQLi Query:
SELECT *
FROM
`technotes`
WHERE
`techgroup` LIKE '%dispatch%' OR
`techgroup` LIKE '%30243542%' AND
`expires` >= '2014-12-18' AND
`viewed` NOT LIKE '%30243542%'
What was expected was that alertid's: 23324325 & 23546576 (1st and last one) would be returned. But instead i am getting record 1,3,4,5 being returned. I am missing something in the order of operation or some other component in the SQLi select statement is malformed but not sure what. Can someone advise what I have left out or need to change so this works properly?
Try this:
SELECT * FROM
`technotes`
WHERE
(`techgroup` LIKE '%dispatch%' OR `techgroup` LIKE '%30243542%')
AND `expires` >= '2014-12-18'
AND (`viewed` NOT LIKE '%30243542%' OR ISNULL(`viewed`) )

Query failed where runnig bigger time period (mssql server 2005 under php only)

I have a weird problem.
I'm running a query:
SELECT IMIE, NAZWISKO, PESEL2, ADD_DATE, CONVERT(varchar, ADD_DATE, 121) AS XDATA, ID_ZLECENIA_XXX, * FROM XXX_KONWERSJE_HISTORIA AS EKH1
INNER JOIN XXX_DANE_PACJENTA EDP1 ON EKH1.ID_ZLECENIA_XXX=EDP1.ORDER_ID_XXX
WHERE EKH1.ID_KONWERSJE = (
SELECT MIN(ID_KONWERSJE)
FROM XXX_KONWERSJE_HISTORIA AS EKH2
WHERE EKH1.ID_ZLECENIA_XXX = EKH2.ID_ZLECENIA_XXX
)
AND EDP1.RECNO = (
SELECT MAX(RECNO)
FROM XXX_DANE_PACJENTA EDP2
WHERE EDP2.ORDER_ID_XXX = EDP1.ORDER_ID_XXX
)
AND EKH1.ID_ZLECENIA_XXX LIKE '%140000393%'
AND ADD_DATE>'20140419' AND ADD_DATE<='20140621 23:59:59.999'
ORDER BY EKH1.ID_KONWERSJE, EKH1.ID_ZLECENIA_XXX DESC
And the query works ok if I use a date limit around 2 months (63 days - it gives me 1015 results). If I extend the date limit query simply fails (Query failed blabla).
This happens under windows 64 bit php (apache, Xamp).
When I run this query directly from MS SQL SERWER Management Studio everything works fine, no matter what date limit I choose.
What is going on? Is there a limit of some kind under apache/php? (There is no information like "query time excessed", only "query failed")
And the query works ok if I use a date limit around 2 months (63 days
- it gives me 1015 results). If I extend the date limit query simply fails (Query failed blabla). ...
What is going on? Is there a limit of
some kind under apache/php? (There is no information like "query time
excessed", only "query failed")
This could happen because selectivity of ADD_DATE>'20140419' AND ADD_DATE<='20140621 23:59:59.999' is medium/low (there are [too] many rows that satisfy this predicate) and SQL Server have to scan (yes, scan) XXX_KONWERSJE_HISTORIA to many times to check following predicate:
WHERE EKH1.ID_KONWERSJE = (
SELECT ...
FROM XXX_KONWERSJE_HISTORIA AS EKH2
WHERE EKH1.ID_ZLECENIA_XXX = EKH2.ID_ZLECENIA_XXX
)
How many times have to scan SQL Server XXX_KONWERSJE_HISTORIA table to verify this predicate ? You can look at the properties of Table Scan [XXX_KONWERSJE_HISTORIA] data access operator: 3917 times
What you can do for the beginning ? You should create the missing index (see that warning with green above the execution plan):
USE [OptimedMain]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[ERLAB_KONWERSJE_HISTORIA] ([ID_ZLECENIA_ERLAB])
INCLUDE ([ID_KONWERSJE])
GO
When I run this query directly from MS SQL SERWER Management Studio
everything works fine, no matter what date limit I choose.
SQL Server Management Studio has execution timeout set to 0 by default (no execution timeout).
Note: if this index will solve the problem then you should try (1) to create an index on ADD_DATE with all required (CREATE INDEX ... INCLUDE(...)) columns and (2) to create unique clustered indexes on these tables.
Try to set these php configurations in your php script via ini_set
ini_set('memory_limit', '512M');
ini_set('mssql.timeout', 60 * 20);
Not sure it will help you out.

Problematic DateTime Comparison SQL Query Not Working

I have a problem with executing ODBC query. I am trying to achieve something simple.
SELECT t.* FROM table t WHERE DateTime > '#2014-05-05 00:00:00#'
I have tried to execute with or without hashes (#) and quotes around the datetime, but no success with that. Also, instead of using >, < and other comparison operators I have tried to use BETWEEN.
In addition several formats "dd/mm/yyyy", "mm/dd/yyyy", "dd.mm.yyyy", etc. plus standard sql format (iso) were tested and the result is the same.
The approach looks like:
$sql = "SELECT t.* FROM table t WHERE DateTime > '#...#'";
$result = odbc_fetch_array(odbc_exec($odbc_connection, $sql));
After this execution I receive some 5-10 symbol binary error, but no error message (with odb_error and odbc_errormsg), in addition to the:
No tuples available at this result index
(The topic: ODBC error in PHP: “No tuples available at this result index” is not helping)
Could it be some ODBC issue (old version etc.) or we should cast another black magic through odbc_exec?
Maybe ODBC have trouble with reserved word datetime.
I don't know how to escape quotes in PHP, try
SELECT t.* FROM table t WHERE t."DateTime" > '20140505'";
You should use ODBC syntax for datetimes which is { ts '1998-05-02 01:23:56.123' }. You can omit the partial seconds. See here.
Have you tried using the TO_DATE() function? You can specify the format you are using.
SELECT t.* FROM table t WHERE DateTime > TO_DATE('2014-05-05 00:00:00','YYYY-MM-DD HH24:MI:SS')

Zend_Db_Adapter_Oracle: Select with ORDER BY, LIMIT & WHERE

I'm trying to select some records from an Oracle 11g Database. The Statement is used to implement some kind of "filter" function for an HTML Table.
Requirements: limit for paging and order the filtered results.
The query is created with Zend_Db_Select
*Works like a charm:*
$select->where('APPLICATIONS LIKE ?', '%MYAPP1%');
$select->where('APPLICATIONS NOT LIKE ?', '%GENESIS%');
$select->limit(20);
= 1 matching result (which is ok!)
The problem occurs when I try to order the filtered result:
$select->order('PATH ASC');
= 3 matching results ??
I think it has something to do with the query generated by Zend DB Select, it looks like this:
SELECT z2.*
FROM (
SELECT z1.*, ROWNUM AS "zend_db_rownum"
FROM (
SELECT "APPS".* FROM "APPS" WHERE (APPLICATIONS LIKE '%MYAPP1%') AND (APPLICATIONS NOT LIKE '%GENESIS%') ORDER BY "PATH" ASC
) z1
) z2
WHERE z2."zend_db_rownum" BETWEEN 1 AND 20
If I run the query without order everything is fine.
If I run the query without limit everything is fine.
If I run the query with order + limit -> wrong result.
If I take the statement and put the order after "BETWEEN 1 AND 20" it works like I want. But how to say Zend DB Select to change it?
Important: I'm doing the query against an Oracle VIEW, if I do it against a "table" it works too.
Obviously Oracle's interpretation of the query is not what the Zend framework intents:
Oracle seems to associate the ROWNUM with the row number count on the inner query before ordering, so the alias zend_db_rownum delivers wrong numbers in the where clause of the outer query.
Since we're not in control of the way the Zend framework generates the SQL in response to the limit() instruction, the only workaround I can think of is skipping the Zend limit() instruction, and instead doing something along the lines of:
$select->where('APPLICATIONS LIKE ?', '%MYAPP1%');
$select->where('APPLICATIONS NOT LIKE ?', '%GENESIS%');
$select->order('PATH ASC');
$sql = $select->__toString();
$sql = "select * from (" . $sql . ") where ROWNUM between 1 and 20";
$stmt = $db->query( $sql, array());
$result = $stmt->fetchAll();
Of course, this workaround is only legitimate in case you're not developing cross-DB, so your code doesn't have to be DB agnostic.
Meaning, you will restrict your solution to Oracle if you use my suggested workaround.
If you checked that there is no error in SQL generation, and really no different conditions in WHERE clause, it may be Oracle server bug. To check it, try it on different Oracle server version or different Oracle server patch level.

Categories