【发布时间】:2016-12-26 21:49:41
【问题描述】:
看来 PDO 的ISO 8601 格式化时间戳有问题。
我使用Microsoft® ODBC Driver 13 (Preview) for SQL Server®从运行 PHP 7.0.8 的 64 位 Ubuntu 16.04 连接
这是我的简单表格:
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);
致命错误:未捕获的 PDOException:SQLSTATE[22018]:转换规范的字符值无效:0 [Microsoft][SQL Server 的 ODBC 驱动程序 13]转换规范的字符值无效(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);
但我正在编写一个每晚在大约 200 万条记录上运行的脚本,所以我真的宁愿不承担运行数百万条 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 不,但我整个周末都休息了,所以今天我要再试一次。
-
祝你好运!告诉我进展如何
-
@JeffPuckettII 你能解决这个问题吗?这不仅发生在日期上,还发生在所有绑定参数上。
-
@Frondor 对于这个特定的问题,我正在导入安全(预清理)数据,所以我完全跳过了绑定。不是用户输入的解决方案,所以不,我还没有解决它。我只是尽量避免微软支持不佳的垃圾。
标签: php sql-server pdo odbc iso8601