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')
Related
Trying to get a simply query going through and its not working - newbie here.
Other php files and queries do run well.
$sql = "select sum(rese_nshw) as noshows from tnht_eseo where edta_data = '19.10.01'" ;
$sumParse = oci_parse($conn, $sql);
oci_define_by_name($sumParse, "noshows", $total);
oci_execute($sumParse);
while(oci_fetch($sumParse)){
echo "noshows:". $total;
}
what's wrong ? just outputs blank.
Running the SQL query in Oracle directly, it outputs 6 as NOSHOWS for this query.
If EDTA_DATA is date (datatype), don't compare it to a string as '19.10.01' is a string. Oracle will implicitly try to convert it to appropriate date, but that doesn't have to work always. Besides 19.10.01 can be anything (2019 Oct 01, or 19 Oct 2001, or ...), depends on NLS settings.
Take control over it; see whether using date literal helps (it always has yyyy-mm-dd format):
where edta_data = date '2019-10-01'
Furthermore, if edta_data contains time component (hours, minutes, seconds), then the simplest option is to truncate it, e.g.
where trunc(edta_data) = date '2019-10-01'
but it'll prevent Oracle from using index on that column (if it exists). It can be fixed, no problem; but - first see whether anything of above helps.
You have to use Upper Case as defined here:
column_name The column name used in the query.
Use uppercase for Oracle's default, non-case sensitive column names.
Use the exact column name case for case-sensitive column names.
from: https://www.php.net/manual/en/function.oci-define-by-name.php
Then:
oci_define_by_name($sumParse, "NOSHOWS", $total);
I was trying to make a SQL statement in PHP, to convert a string into a time(6). But I have tried everything, for the last 12 hours, and have not made an inch of progress. I have tried these statements, all yield the same error.
UPDATE scheduling SET start='03:42PM' WHERE activityid=2;
UPDATE scheduling SET start=CONVERT(TIME(6),'03:42PM');
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'15:42'));
The error is
Syntax Error: unexpected '03:42PM'(single quoted text)"
I do not know how to fix this, the table exists, and i have sucesfully got other info using statements like SELECT activityid=2 FROM xxxxxx.scheudling
I guess I have two questions, either answer would work.
In my PHP document, how would I convert a string I get in from an Android Studio volley to a date. (I get the variable correctly, with $start=$_Post("start"), so that works, but I cant convert it into a time. I looked online, and tried everything that looked like it work work.
Conversion through SQL Code, I already tried CAST and CONVERT, neither works. My start column is type TIME(6).
I recommend testing expressions using a SELECT statement.
Firstly, the MySQL CONVERT function arguments are flipped around backwards.
The syntax is CONVERT(expr,type)
And type is supplied as a keyword, not a string literal. For example:
SELECT CONVERT('235',SIGNED)
To convert to a TIME datatype
SELECT CONVERT( '15:42' ,TIME(6)) // => 15:42:00.000000
The 'PM' part of the string literal will be ignored.
SELECT CONVERT( '03:42PM' ,TIME(6)) // => 03:42:00.000000
We can use the STR_TO_DATE function to return a TIME value from a string that contains the AM/PM indicator
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
And there's no need to cast that to TIME(6), we can do this:
UPDATE scheduling
SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p')
WHERE activityid = 2
The STR_TO_DATE function is documented here:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date
The format patterns for STR_TO_DATE are documented here, under DATE_FORMAT:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
FOLLOWUP
Demonstration:
setup
USE test;
CREATE TABLE scheduling (activityid INT PRIMARY KEY, start TIME(6));
-- 0 row(s) affected
INSERT INTO scheduling (activityid) VALUES (2);
-- 1 row(s) affected
execute the update statement in the answer above
UPDATE scheduling SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p') WHERE activityid = 2 ;
-- 1 row(s) affected
results
SELECT * FROM scheduling WHERE activityid = 2;
-- activityid start
-- ---------- ---------------
-- 2 15:42:00.000000
SECOND FOLLOWUP
Use same sql_mode setting reported by OP:
SET ##sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
Test:
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
returns
(NULL)
But this more complicated expression:
SELECT TIME(STR_TO_DATE(CONCAT(CURRENT_DATE(),' ', '03:42PM' ),'%Y-%m-%d %h:%i%p'))
returns
15:42:00
The more complicated expression is a workaround to avoid behavior imposed by the STRICT_TRANS_TABLES and NO_ZERO_DATE in the sql_mode.
I am trying to get some data, and in the table, there is a field named "sysload". However, it is a var(string) type. The data in it is like "0.0, 0.2, 0.5",three numbers split by comma. However, in the sql, I only need the last number(in this example:0.5) to compare in "where". So how can I use it ? My code:
$termquery=mysql_query("SELECT a.terminal FROM terminal_server_log a
inner join
(
SELECT terminal, MAX(timestamp) timestamp
FROM terminal_server_log
group by terminal
) b on (b.terminal=a.terminal and a.timestamp=b.timestamp)
WHERE explode(',', sysload)[2]>$number");
The last line is the most important one, i want to compare with '$number', but it seems i cannot use 'explode'. Thanks
You can probably use regular expressions to match the last element of your sysload column: https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-instr
Look also at CAST() function, as the extracted substring should be converted to a numeric value to allow comparison with a number.
PHP functions will not work inside SQL queries.
You can remove this filter from your query and filter at the php side, or you can make a custom explode function using some mysql string functions.
In this link has an example: (I didn't check if it's working)
Equivalent of explode() to work with strings in MySQL
I am having a bit of trouble writing a mysqli query that queries between dates.
The column in my mysql database is a datetime column.
The query I have written in php looks like this
$sessions = mysqli_query($db,"SELECT s.idSession, s.idUser,
FROM rempad.Session AS s WHERE s.idUser = 12 AND s.start BETWEEN '2013-04-28' AND '2013-05-28'");
I have tried escaping the dates like \'2013-04-28\'
I have also tried casting as datetime like: DATETIME(s.start) BETWEEN DATETIME('2013-04-28') AND ...
But that doesn't work.
I have tested the SQL syntax in Mysql workbench so I know that the query returns values, but I can't seem to get it right in php.
Any ideas? I can't find any examples online.
Thanks in advance
L
I tried it and it worked as:
query($db,"SELECT s.idSession, s.idUser
FROM rempad.Session s WHERE s.idUser = 12 AND s.start BETWEEN '2013-04-28' AND '2013-05-28'");
Removed a comma and 'as' after table name.
i am using mysqlclient,
in one of my query, as shown below
sprintf (query, "select user from pcloud_session where id = '%s'", sid);
here some time this sid is with % sign in it like the example
2Cq%yo4i-ZrizGGQGQ71eJQ0
but when there is this % this query always fail, i think i have to escape this %, but how ?
i tried with \ and %% , but both of this not working, please help me here
UPDATE:
When using session.hash_bits_per_character = 6, in php session ,the default charset contains a character (comma) that will always be urlencoded(here it is %2C). This results in cookie values having this %2C in it, but session db having a comma instead of it. any idea about fixing this problem ?.. sorry for the confusion
Thanks
There's no need to escape a literal '%' in MySQL query text.
When you say the query "always fail", is it the call to the mysql_query function that is returning an error? Does it return a SQL Exception code, or is it just not returning the resultset (row) you expect?
For debugging, I suggest you echo out the contents of the query string, after the call to sprintf. We'd expect the contents of the string to be:
select user from pcloud_session where id = '2Cq%yo4i-ZrizGGQGQ71eJQ0'
And I don't see anything wrong with that SQL construct (assuming the id column exists in pcloud_session and is of character datatype. Even if id was defined as an integer type, that statement wouldn't normally throw an exception, the string literal would just be interpreted as integer value of 2.)
There should be no problem including a '%' literal into the target format of an sprintf. And there should be no problem including a '%' literal within MySQL query text.
(I'm assuming, of course, that sid is populated by a call to mysql_real_escape_string function.)
Again, I suggest you echo out the contents of query, following the call to sprintf. I also suggest you ensure that no other code is mucking with the contents of that string, and that is the actual string being passed as an argument to mysql_query function. (If you are using the mysql_real_query function, then make sure you are passing the correct length.)
UPDATE
Oxi said: "It does not return a SQL Exception code, it just does not return the result[set] I expect. I did print the query, it prints with % in it."
#Oxi
Here's a whole bunch of questions that might help you track down the problem.
Have you run a test of that query text from the mysql command line client, and does that return the row(s) you expect?
Is that id column defined as VARCHAR (or CHAR) with a length of (at least) 24 characters? Is the collation on the column set as case insensitive, or is it case sensitive?
show create table pcloud_session ;
(I don't see any characters in there that would cause a problem with characterset translation, although that could be a source of a problem, if your application is not matching the database charactarset encoding.)
Have you tested queries using a LIKE predicate against that id column?
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq\%yo4i-%' ESCAPE '\\'
ORDER BY id LIMIT 10 ;
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq%'
ORDER BY id LIMIT 10 ;
Are you getting no rows returned when you expect one row? Are you getting too many rows returned, or are you getting a different row than the one you expect?
That is an oddball value for an id column. At first, it looks almost as if the value is represented in a base-64 encoding, but it's not any standard encoding, since it includes the '%' and the '-' characters.
If you're going to do this in C without an interface library, you must use mysql_real_escape_string to do proper SQL escaping.
There shouldn't be anything intrinsically wrong with using '%inside of a string, though, as the only context in which it has meaning is either directly inprintftype functions or as an argument toLIKE` inside of MySQL.
This proves to be really annoying, but it's absolutely necessary. It's going to make your code a lot more complicated which is why using low-level MySQL in C is usually a bad idea. The C++ wrapper will give you a lot more support.
You really shouldn't escape the string yourself. The safest option is to let the MySQL API handle it for you.
For a string of maximum length n, start by allocating a string of length 2*n+1:
int sidLength = strlen(sid);
// worst-case, we need to escape every character, plus a byte for the ASCIIZ
int maxSafeSidLength = sidLength * 2 + 1;
char *safeSid = malloc(maxSafeSidLength);
// copy "sid" to "safeSid", escaping as appropriate
mysql_real_escape_string(mysql, safeSid, sid, sidLength);
// build the query
// ...
free(safeSid);
There's a longer example at the mysql_real_escape_string page on dev.mysql.com, in which they build the entire query string, but the above approach should work for supplying safeSid to sprintf.