PDO SQLSRV查询未执行完毕:循环插入日期数据异常求助
解决PDO结合SQL Server循环插入日期未执行完毕的问题
看起来你在尝试用PDO执行SQL Server的循环插入脚本时遇到了执行中断的问题,我来帮你一步步排查并解决:
第一步:先验证SQL脚本本身的正确性
首先把你的SQL逻辑单独拎出来,在SQL Server管理工具(比如SSMS)里运行,排除SQL语法或逻辑问题:
DELETE FROM TEST; DECLARE @TempDate AS DATE = '2017-01-01'; DECLARE @EndDate AS DATE = '2018-01-01'; WHILE @TempDate <= @EndDate BEGIN -- 替换成你表中实际的日期列名 INSERT INTO TEST (DateColumn) VALUES (@TempDate); SET @TempDate = DATEADD(DAY, 1, @TempDate); END
如果这段SQL能正常插入366条记录(包含2018-01-01),那问题就出在PDO的配置或执行逻辑上。
第二步:优化PDO的错误处理与超时设置
你的脚本里只设置了查询超时,但没开启错误捕获,很可能执行中出现了错误但你没看到。修改代码,开启异常模式并延长超时:
try { $dsn = "sqlsrv:Server=MyServer,1433;Database=MyDB;"; $db = new PDO($dsn, "sa", "MyPassword"); // 开启严格错误模式,捕获所有PDO异常 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 延长查询超时到5分钟(300秒),确保足够完成插入 $db->setAttribute(PDO::SQLSRV_ATTR_QUERY_TIMEOUT, 300); $sql = " DELETE FROM TEST; DECLARE @TempDate AS DATE = '2017-01-01'; DECLARE @EndDate AS DATE = '2018-01-01'; WHILE @TempDate <= @EndDate BEGIN INSERT INTO TEST (DateColumn) VALUES (@TempDate); SET @TempDate = DATEADD(DAY, 1, @TempDate); END "; $stmt = $db->prepare($sql); $stmt->execute(); echo "插入成功,共插入 " . $stmt->rowCount() . " 条记录"; } catch (PDOException $e) { die("执行失败: " . $e->getMessage()); }
这样一旦出现错误,你就能直接看到具体原因,比如连接问题、权限不足或者SQL语法细节错误。
第三步:替代方案——用PHP生成日期再批量插入
如果SQL端的循环还是不稳定,换用PHP控制日期生成,再批量插入,这种方式更易调试:
try { $dsn = "sqlsrv:Server=MyServer,1433;Database=MyDB;"; $db = new PDO($dsn, "sa", "MyPassword"); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 先清空表 $db->exec("DELETE FROM TEST"); $startDate = new DateTime('2017-01-01'); $endDate = new DateTime('2018-01-01'); $endDate->modify('+1 day'); // 确保包含2018-01-01 // 批量插入优化,每100条提交一次 $insertSql = "INSERT INTO TEST (DateColumn) VALUES "; $values = []; $params = []; $batchSize = 100; $totalCount = 0; $period = new DatePeriod($startDate, new DateInterval('P1D'), $endDate); foreach ($period as $date) { $values[] = "(?)"; $params[] = $date->format('Y-m-d'); $totalCount++; // 达到批量大小就执行插入 if ($totalCount % $batchSize === 0) { $fullSql = $insertSql . implode(', ', $values); $stmt = $db->prepare($fullSql); $stmt->execute($params); // 重置临时数组 $values = []; $params = []; } } // 插入剩余的记录 if (!empty($values)) { $fullSql = $insertSql . implode(', ', $values); $stmt = $db->prepare($fullSql); $stmt->execute($params); } echo "插入成功,共插入 " . $totalCount . " 条记录"; } catch (PDOException $e) { die("执行失败: " . $e->getMessage()); }
第四步:检查XAMPP环境配置
- 验证SQLSRV扩展:通过
phpinfo()查看是否加载了pdo_sqlsrv和sqlsrv扩展,如果没有,需要下载对应PHP版本的SQLSRV驱动,放到XAMPP的ext目录,然后在php.ini中添加:
重启Apache生效。extension=sqlsrv extension=pdo_sqlsrv - 延长PHP执行超时:XAMPP默认的
max_execution_time可能是30秒,不够完成插入。可以在脚本开头添加:
或者直接修改ini_set('max_execution_time', 300); // 设置为5分钟php.ini中的max_execution_time值。
内容的提问来源于stack exchange,提问作者pantan
相关产品推荐
相关产品推荐

