-4

短いバージョン: sqlsrv ドライバー (ネイティブ クライアント ラッパー) は、トリガーから生成された制約違反エラーを「処理」します。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;

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ブロック内にある場合にのみ発生します。混乱させて申し訳ありません。

2010-03-03 を編集: の重大度レベルに執着しすぎないようにRAISERROR、実際のコードは と でキャッチされたエラーを再スローしようとERROR_NUMBERERROR_SEVERITYますERROR_STATE

さらに、以下の質問に注意してください。

質問:どうしたの? この PHP ドライバーを使用しますか? DML トリガーでビューを使用していますか? ドライバーは運命の取引を報告しますか?

ここに記載されている状況を直接経験せずに賞金を収穫しようとしないでください.

4

3 に答える 3

0

重大度17は、「リソースが不十分」であることを示します。代わりに16を使用してみてください。(エラーメッセージの重大度レベル

正規のリファレンスから:SQL 2000でのエラー処理–背景

重大度レベル– 0〜25の数値。重大度レベルが0〜10の範囲にある場合、メッセージは情報または警告であり、エラーではありません。SQLコードのプログラミングエラーに起因するエラーの重大度は、11〜16の範囲です。重大度レベル17〜25は、SQL Serverのリソースの問題、ハードウェアの問題、または内部の問題を示し、重大度が20以上の場合、接続は終了します。長い話については、いくつかの興味深い情報について、重大度レベルの詳細のセクションを参照してください。システムメッセージの場合、で重大度レベルを見つけることができますmaster..sysmessagesが、一部のメッセージの場合、SQLServerはにあるものとは異なる重大度レベルを採用しますsysmessages

関連項目:SQL2005以降でのエラー処理

于 2010-03-03T03:57:33.720 に答える
0

重大度10以下を試しましたか?ちなみに、私はいつもSQLドライバーとPHPで幸運に恵まれてきました。2005年と2008年。これが機能しない場合は、別のサーバーを試して、サーバー構成ではないことを確認してください。

于 2010-03-03T12:18:11.530 に答える
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 に変更しただけです。

于 2010-03-03T03:44:51.517 に答える