短版本:从触发器生成的sqlsrv驱动程序(Native Client wrapper)"eats"约束违规错误; mssql驱动程序(ntwdlib包装器)报告它们就好了 .
-
SQL Server 2005
-
PHP 5.3.1
-
用于PHP 1.1的SQL Server驱动程序
灯具:
CREATE TABLE t (
t INT NOT NULL PRIMARY KEY
);
CREATE VIEW v AS
SELECT CURRENT_TIMESTAMP AS v
;
CREATE TRIGGER vt ON v
INSTEAD OF INSERT
AS BEGIN
BEGIN TRY
INSERT INTO t SELECT 1 UNION ALL SELECT 1;
END TRY
BEGIN CATCH
RAISERROR('fubar!', 17, 0);
END CATCH
END;
通过Management Studio运行 INSERT INTO v SELECT CURRENT_TIMESTAMP;
(0 row(s) affected)
Msg 3616, Level 16, State 1, Line 1
Transaction doomed in trigger. Batch has been aborted.
Msg 50000, Level 17, State 0, Procedure vt, Line 8
fubar!
通过sqlsrv_query运行时没有报告错误:
$conn = sqlsrv_connect(...);
var_dump(sqlsrv_query($conn, 'INSERT INTO v SELECT CURRENT_TIMESTAMP'));
var_dump(sqlsrv_errors());
输出
resource(11) of type (SQL Server Statement)
NULL
应用程序(似乎)没有办法发现触发器失败,而不是通过后面的语句失败 .
问题:怎么了?你使用这个PHP驱动程序吗?您是否使用DML触发器的视图?驱动程序报告注定的事务吗?
编辑2010-02-17 11:50:问题的第一个版本错误地声称我看到带有触发器的工件包含一个简单的 INSERT
. 好吧,它只发生在违反约束的DML在 TRY
块内 . 对困惑感到抱歉 .
编辑2010-03-03:只是为了让你们对 RAISERROR
中的严重性级别过于依赖,真正的代码试图用 ERROR_NUMBER
, ERROR_SEVERITY
和 ERROR_STATE
重新抛出捕获的错误 .
此外,请注意提出的问题:
问题:怎么了?你使用这个PHP驱动程序吗?您是否使用DML触发器的视图?驱动程序报告注定的事务吗?
如果没有亲身体验这里描述的情况,请不要尝试收获赏金 .
3 回答
我在过去遇到过这个问题,它不仅仅是复杂的PHP . 出于某种原因,我无法弄清楚并在任何文档中找到,您需要为非系统管理员指定严重性为最大值18 . 试试这个:
注意:我在上面的代码中仅将严重性从17更改为18 .
严重级别为17表示"Insufficient Resources" . 请尝试使用16代替 . (Error Message Severity Levels)
来自规范参考:Error Handling in SQL 2000 – a Background
另见:Error Handling in SQL 2005 and Later
您是否尝试过10或以下的严重程度?顺便说一句,我总是运气好SQL驱动程序和PHP . 在2005年和2008年 . 如果这不起作用,请尝试使用其他服务器以确保它不是您的服务器配置 .