短版:sqlsrv 驱动程序(本机客户端包装器)“吃掉”触发器生成的约束违规错误;mssql 驱动程序(ntwdlib包装器)报告它们就好了。
- SQL 服务器 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;
INSERT INTO v SELECT CURRENT_TIMESTAMP;
通过 Management Studio运行收益率
(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 触发器的视图?司机是否报告注定的交易?
如果没有亲身经历过这里描述的情况,请不要试图收获赏金。