short version: the sqlsrv driver (Native Client wrapper) "eats" constraint violation errors generated from triggers; the mssql driver (ntwdlib wrapper) reports them just fine.
- SQL Server 2005
- PHP 5.3.1
- SQL Server Driver for PHP 1.1
fixture:
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;
running INSERT INTO v SELECT CURRENT_TIMESTAMP;
through Management Studio yields
(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!
no error is reported when I run it through sqlsrv_query:
$conn = sqlsrv_connect(...);
var_dump(sqlsrv_query($conn, 'INSERT INTO v SELECT CURRENT_TIMESTAMP'));
var_dump(sqlsrv_errors());
outputs
resource(11) of type (SQL Server Statement)
NULL
the application has (it seems) no way to find out that the trigger failed other than through later statements failing.
The question: What's up? Do you use this PHP driver? Do you use views with DML triggers? Does the driver report doomed transactions?
edit 2010-02-17 11:50: the first version of the question incorrectly claimed that I saw the artifact with the trigger containing a simple INSERT
. well, it only happens when the constraint-violating DML is inside a TRY
block. sorry for the confusion.
edit 2010-03-03: just so that you guys don't get too attached to the severity level in RAISERROR
, the real code tries to rethrow the caught error with ERROR_NUMBER
, ERROR_SEVERITY
and ERROR_STATE
.
furthermore, please pay attention to the questions asked:
The question: What's up? Do you use this PHP driver? Do you use views with DML triggers? Does the driver report doomed transactions?
please don't try to harvest the bounty without having firsthand experience with the situation described here.