SQL Server 2005, драйвер SQL для PHP v1.1 ест ошибки «транзакция обречена на триггер» - PullRequest
0 голосов
/ 16 февраля 2010

короткая версия: драйвер sqlsrv (оболочка Native Client) «ест» ошибки нарушения ограничений, генерируемые триггерами; драйвер mssql ( ntwdlib оболочка) сообщает о них просто отлично.

  • SQL Server 2005
  • PHP 5.3.1
  • Драйвер SQL Server для PHP 1.1

крепление:

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? Сообщает ли драйвер об обреченных транзакциях ?

edit 2010-02-17 11: 50 : в первой версии вопроса неверно утверждалось, что я видел артефакт с триггером, содержащим простое INSERT. ну, это происходит только тогда, когда DML, нарушающий ограничение, находится внутри блока TRY. извините за путаницу.

edit 2010-03-03: просто, чтобы вы, ребята, не слишком привязывались к уровню серьезности в RAISERROR, реальный код пытается сбросить обнаруженную ошибку с помощью ERROR_NUMBER, ERROR_SEVERITY и ERROR_STATE.

Кроме того, обратите внимание на задаваемые вопросы:

Вопрос: Что случилось? Вы используете этот драйвер PHP? Используете ли вы представления с триггерами DML? Сообщает ли драйвер об обреченных транзакциях ?

пожалуйста, не пытайтесь получить награду, не имея непосредственного опыта в ситуации, описанной здесь.

Ответы [ 3 ]

0 голосов
/ 03 марта 2010

Уровень серьезности 17 означает «Недостаточно ресурсов». Попробуйте использовать 16 вместо. ( Уровни серьезности сообщений об ошибках )

Из канонической справки: Обработка ошибок в SQL 2000 - фон

Уровень серьезности - число от 0 до 25. История о том, что если уровень серьезности находится в диапазоне 0-10, сообщение является информационным или предупреждение, а не ошибка. ошибки в результате ошибок программирования в ваш код SQL имеет уровень серьезности в диапазон 11-16. Уровни серьезности 17-25 указать проблемы с ресурсами, оборудование проблемы или внутренние проблемы в SQL Сервер, и если серьезность составляет 20 или выше соединение разрывается. Для длинной истории, смотрите раздел Подробнее об уровнях серьезности для некоторых интересные лакомые кусочки Для системы сообщения вы можете найти серьезность уровень в master..sysmessages, но для некоторые сообщения SQL Server использует другой уровень серьезности, чем то, что в sysmessages.

Также см .: Обработка ошибок в SQL 2005 и более поздних версиях

0 голосов
/ 03 марта 2010

Вы пробовали уровень серьезности 10 или ниже? Кстати, мне всегда везло с драйвером SQL и PHP. В 2005 и 2008 годах. Если это не сработает, попробуйте другой сервер, чтобы убедиться, что это не ваш сервер.

0 голосов
/ 03 марта 2010

Я сталкивался с этой проблемой в прошлом, это не просто сложность 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 в приведенном выше коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...