简短版本:sqlsrv驱动程序(Native Client包装器)“吃掉”触发器生成的约束违规错误; mssql驱动程序( ntwdlib 包装器)报告它们就好了。
夹具:
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_NUMBER
和ERROR_SEVERITY
。
问题:什么事?你使用这个PHP驱动程序吗?您是否使用DML触发器的视图?驱动程序是否报告注定的事务?
请不要试图在没有第一手经验的情况下收获赏金。
答案 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
。
答案 2 :(得分:0)
您是否尝试过10或更低的严重程度?顺便说一句,我总是运气好SQL驱动程序和PHP。在2005年和2008年。如果这不起作用,请尝试使用其他服务器以确保它不是您的服务器配置。