似乎PDO与ISO 8601格式化的时间戳有问题。如何使用PDO绑定ISO8601 TSQL DATETIME参数?
我是从64位Ubuntu的连接使用16.04的Microsoft® ODBC Driver 13 (Preview) for SQL Server®
这里是我的简单的表运行PHP 7.0.8:
CREATE TABLE dtest (
"stamp" DATETIME
);
作品:
$pdoDB = new PDO('odbc:Driver=ODBC Driver 13 for SQL Server;
Server='.DATABASE_SERVER.';
Database='.DATABASE_NAME,
DATABASE_USERNAME,
DATABASE_PASSWORD
);
$pdoDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO dtest (stamp) VALUES ('2011-03-15T10:23:01')";
$stmt = $pdoDB->prepare($sql);
$params = [];
$stmt->execute($params);
不工作:
$sql = "INSERT INTO dtest (stamp) VALUES (?)";
$stmt = $pdoDB->prepare($sql);
$params = ['2011-03-15T10:23:01'];
$stmt->execute($params);
Fatal error: Uncaught PDOException: SQLSTATE[22018]: Invalid character value for cast specification: 0 [Microsoft][ODBC Driver 13 for SQL Server]Invalid character value for cast specification (SQLExecute[0] at /build/php7.0-lPMnpS/php7.0-7.0.8/ext/pdo_odbc/odbc_stmt.c:260)
这工作如果我删除了T
所以'2011-03-15T10:23:01'
成为'2011-03-15 10:23:01'
$sql = "INSERT INTO dtest (stamp) VALUES (?)";
$stmt = $pdoDB->prepare($sql);
$params = ['2011-03-15 10:23:01'];
$stmt->execute($params);
但我正在写在夜间运行在约2万条记录的脚本,所以我倒是真的而不忍心运行数百万的开销str_replace('T', ' ', $param)
我也试过用bindParam
,但是它给出了同样的错误:
$sql = "INSERT INTO dtest (stamp) VALUES (:tdate)";
$stmt = $pdoDB->prepare($sql);
$date = '2011-03-15T10:23:01';
$stmt->bindParam(':tdate',$date,PDO::PARAM_STR);
$stmt->execute();
是否有无论如何绑定和执行这个参数?我有点疑惑的错误信息,因为它似乎来自SQL Server,就好像PDO做得很好,但这没有意义,因为它能够处理不带参数化的类型转换。
我也试过SQL转换:
作品:
$sql = "INSERT INTO dtest (stamp) VALUES (CONVERT(DATETIME, '2011-03-15T10:23:02', 126))";
$stmt = $pdoDB->prepare($sql);
$params = [];
$stmt->execute($params);
不起作用:
$sql = "INSERT INTO dtest (stamp) VALUES (CONVERT(DATETIME, ?, 126))";
$stmt = $pdoDB->prepare($sql);
$params = ['2011-03-15T10:23:02'];
$stmt->execute($params);
嗨,这有什么好运? – MonkeyZeus
@MonkeyZeus nope,但我整个周末都休息了,所以今天我会再试一次。 –
祝你好运!让我知道它是怎么回事 – MonkeyZeus