首页 文章

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

提问于
浏览
-3

短版本:从触发器生成的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_NUMBERERROR_SEVERITYERROR_STATE 重新抛出捕获的错误 .

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

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

如果没有亲身体验这里描述的情况,请不要尝试收获赏金 .

3 回答

  • 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;
    

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

  • 0

    严重级别为17表示"Insufficient Resources" . 请尝试使用16代替 . (Error Message Severity Levels

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

    严重级别 - 0到25之间的数字.Stort故事是,如果严重性级别在0-10范围内,则消息是信息性的或警告,而不是错误 . SQL代码中的编程错误导致的错误的严重性级别在11-16之间 . 严重级别17-25表示SQL Server中的资源问题,硬件问题或内部问题,如果严重性为20或更高,则终止连接 . 对于长篇故事,请参阅有关一些有趣花絮的更多关于严重性级别的部分 . 对于系统消息,您可以在master..sysmessages中找到严重性级别,但对于某些消息,SQL Server使用的不同于sysmessages中的严重性级别 .

    另见:Error Handling in SQL 2005 and Later

  • 0

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

相关问题