SQL Server 2005,PHP v1.1的SQL驱动程序吃掉了“触发器中的事务失败”错误

时间:2010-02-16 20:22:14

标签: php sql-server-2005 sql-server-native-client

简短版本:sqlsrv驱动程序(Native Client包装器)“吃掉”触发器生成的约束违规错误; 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触发器的视图?驱动程序是否报告注定的事务

edit 2010-02-17 11:50 :问题的第一个版本错误地声称我看到包含简单INSERT的触发器的工件。好吧,只有当违反约束的DML在TRY块内时才会发生。抱歉混淆。

编辑 2010-03-03:为了让你们对RAISERROR中的严重性级别过于依赖,真正的代码试图用{重新抛出捕获的错误{1}},ERROR_NUMBERERROR_SEVERITY

此外,请注意提出的问题:

问题:什么事?你使用这个PHP驱动程序吗?您是否使用DML触发器的视图?驱动程序是否报告注定的事务

请不要试图在没有第一手经验的情况下收获赏金。

3 个答案:

答案 0 :(得分:0)

我过去遇到过这个问题,复杂的不只是PHP。出于某种原因,我无法弄清楚并在任何文档中找到,您需要为非系统管理员指定严重性为最大值18。试试这个:

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!', 18, 0);
END CATCH
END;

note :我在上面的代码中仅将严重性从17更改为18。

答案 1 :(得分:0)

严重级别为17表示“资源不足”。请尝试使用16代替。 (Error Message Severity Levels

来自规范参考:Error Handling in SQL 2000 – a Background

  

严重程度 - 从0到0的数字   25.严重的故事是,如果严重程度在0-10范围内,   消息是信息性的或者是   警告,而不是错误。错误   由编程错误导致的   您的SQL代码具有严重性级别   范围11-16。严重程度为17-25   表明资源问题,硬件   SQL中的问题或内部问题   服务器,如果严重性为20或   更高,连接终止。   从长远来看,请参阅本节   更多关于某些人的严重程度   有趣的花絮。对于系统   消息,您可以找到严重性   master..sysmessages中的等级,但是   SQL Server使用的一些消息   不同的严重程度   在sysmessages

另见:Error Handling in SQL 2005 and Later

答案 2 :(得分:0)

您是否尝试过10或更低的严重程度?顺便说一句,我总是运气好SQL驱动程序和PHP。在2005年和2008年。如果这不起作用,请尝试使用其他服务器以确保它不是您的服务器配置。