0

I am struggling trying to update a row in an Azure SQL database. What I am trying to do is to update a row with some input variables along with a fresh datestamp. If I input the following (for test purposes), my database is updated, but the date is way off:

"UPDATE TABLENAME set COL1 = ".$_POST[VAL1].", COL2 = ".$_POST[VAL2].", COL3 = 2020-03-20 WHERE COL0 = 'VAL0'"

giving me a datestamp looking like this: 1905-06-21T00:00:00.0000000 I have been trying just around a hundred ways of formatting the date() variable, putting it in my SQL statement like this:

"UPDATE TABLENAME set COL1 = ".$_POST[VAL1].", COL2 = ".$_POST[VAL2].", COL3 = ".date()." WHERE COL0 = 'VAL0'"

Needless to say, COL3 is my datestamp column. But I cannot get the database to accept my datestamp formatting. I have tried YYYY-mm-dd xyz1234 in countless variants inside date(), but to no avail. The database has the following collation set: SQL_Latin1_General_CP1_CI_AS. Any pointers?

Alex Howansky
  • 50,515
  • 8
  • 78
  • 98
KMBN
  • 73
  • 2
  • 6
  • Your code is vulnerable to [**SQL injection**](https://en.wikipedia.org/wiki/SQL_injection) attacks. You should use prepared statements with bound parameters, via either [**mysqli**](https://secure.php.net/manual/en/mysqli.prepare.php) or [**PDO**](https://secure.php.net/manual/en/pdo.prepared-statements.php). [**This post**](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) has some good examples. Doing so will also address your quoting issues. – Alex Howansky Mar 22 '19 at 15:06
  • Take a look at [this](https://learn.microsoft.com/en-us/sql/t-sql/functions/date-and-time-data-types-and-functions-transact-sql?view=sql-server-2017) – Scamtex Mar 22 '19 at 15:26

1 Answers1

1

First, about your incorrect date value. It is correct, because when you miss '' around 2020-03-20, SQL Server makes implicit data type conversion. Next example demonstrates this:

Implicit conversion:

DECLARE @date datetime

SELECT @date = 2020-03-20
SELECT @date

SELECT DATEADD(day, 2020-03-20, 0)

Output:

1905-06-21 00:00:00.000

Second, if you want to pass date and time values, just use appropriate format - 'yyyy-MM-dd', 'yyyyMMdd hh:nn:ss' or 'yyyy-MM-ddThh:nn:ss':

"UPDATE TABLENAME set COL1 = ".$_POST[VAL1].", COL2 = ".$_POST[VAL2].", COL3 = '2020-03-20' WHERE COL0 = 'VAL0'"

I don't know how you make your connection to SQL Server, but try to use prepared statements.

Update (Retrieve and send date and time values from and to SQL Server):

Based on driver that you use to connect to SQL Server, you may retrieve date and time values as text or as PHP datetime object (if you use PHP Driver for SQL Server), but you need to send these values as text. In your case values are returned as text. So you need to generate universal datetime value (in 'yyyy-MM-ddThh:nn:ss' for example) as text.

Next example shows some valid and invalid combinations for UPDATE T-SQL statement for your datetime column. It is tested with PHP Driver for SQL Server 4.0.3.

<?php
# Value from database as text
$row['COL3'] = '2019-03-29T11:35:30.0000000';

# Valid statement
$tsql = "UPDATE TABLENAME SET COL3 = '".substr($row['COL3'], 0, 19)."' ";

# Valid statement - date("Y-m-d\Th:i:s") will return current datetime
$tsql = "UPDATE TABLENAME SET COL3 = '".date("Y-m-d\Th:i:s")."' ";

# Invalid statement - date("d-m-Y h:i:s", $row['COL3']) expects int as second parameter, 
# generates warning and returns '01-01-1970 12:33:39' as result  
$tsql = "UPDATE TABLENAME SET COL3 = '".date("d-m-Y h:i:s", $row['COL3'])."' ";
?>
Zhorov
  • 28,486
  • 6
  • 27
  • 52
  • @KMBN Can you execute your statement correctly with `''` arounf date value? – Zhorov Mar 25 '19 at 08:08
  • "Just use appropriate format." Heh, yes. But that is the problem. For now, I have declared a variable when the page loads, to see what it looks like when I load it. `'yyyy-MM-ddThh:nn:ss'` was NOT the solution, as it doubled everything, like the time being `0808:3535` instead of `08:35`. What seems to work better in the variable is `date("Y-m-dTh:i:s.nnn")`, which makes it look like this: `2019-03-25CET09:02:09.333`. If I use this formatting in my SQL query, I just get SQLSTATE: 42000 code: 102 message: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Incorrect syntax near '09', though. – KMBN Mar 25 '19 at 08:11
  • ...and yes, I was going to reply to the missing `''`part, but my reply was too long. Right now, the query string looks like this: `$tsql= "UPDATE TABLENAME set COL1 = ".$_POST[VAL1].", COL2 = ".$_POST[VAL2].", COL3 = ".date('Y-m-dTh:i:s.nnn')." WHERE COL0 = 'VAL0'"`, and now I get this `SQLSTATE: 42000 code: 102 message: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Incorrect syntax near '09'`, `09` being the seconds value in the datestamp. – KMBN Mar 25 '19 at 08:15
  • If I change $tsql= "UPDATE TABLENAME set COL1 = ".$_POST[VAL1].", COL2 = ".$_POST[VAL2].", COL3 = ".date('Y-m-dTh:i:s.nnn')." WHERE COL0 = 'VAL0'"`` to `$tsql= "UPDATE TABLENAME set COL1 = ".$_POST[VAL1].", COL2 = ".$_POST[VAL2].", COL3 = '2020-02-02T02:02:02' WHERE COL0 = 'VAL0'"` my database gets its date column updated with the value `02-02-2020 02:02:02`. So the tricky part is getting the `date()` inside the statement to work the same way. – KMBN Mar 25 '19 at 08:24
  • Heureka! It works! I was missing the `''` **around** the values. It works with `"UPDATE TABLENAME set COL1 = '".$_POST[VAL1]."', COL2 = '".$_POST[VAL2]."', COL3 = '".date('Y-m-d\Th:i:s')."' WHERE COL0 = 'VAL0'"`. But: I still get this error code, when I post: `SQLSTATE: 42000 code: 8114 message: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Error converting data type varchar to numeric`. My columns' date types are as follows: COL0=varchar COL1=decimal COL2=int COL3=datetime So while the table is actually updated correctly, I don't quite understand why there is an error message. – KMBN Mar 25 '19 at 08:58
  • Perhaps you can explain why my output seems to be causing trouble as well. On the same page,I want an output saying when the data was last updated and with which values. So I have `$COL1 = $row['COL1']; $COL2 = $row['COL2']; $COL3 = date("d-m-Y h:i:s", $row['COL3']);` and then later `echo ("values updated on ".$COL3. " with ".$COL1." and ".$COL2);` But no matter what combination of `d`, `m`, `Y` etc. I use, my datestamp is stuck on 01/01/1970. The datestamp in the DB is: `26-03-2019 11:27:41` (in VS) and `2019-03-26T11:42:42.0000000` in Azure table editor. – KMBN Mar 26 '19 at 10:59
  • That is exactly my problem. Though the value in `COL3` in the database is `2019-03-29T11:35:30.0000000`, when I execute my tsql query (and get other values from non-date fields just fine), I don't seem to get the datestamp. I have `$latestupdate = date("d-m-Y h:i:s", $row['COL3']);` and later in the code `echo ("values were updated ".$latestupdate);`, but no value is output. Obviously, the issue is how dates are handled between PHP and SQL, but I don't know what I am missing in my code to deal with it. I feel like I have tried almost everything, though I know I haven't. – KMBN Mar 29 '19 at 10:44