質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

受付中

SQL Server 2008 から 2012 変更でのRAISERROR文の修正について

ponpopo
ponpopo

総合スコア8

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

1回答

0リアクション

0クリップ

3598閲覧

投稿2019/10/26 00:58

編集2019/10/28 02:11

前提・実現したいこと

SQL Server 2008 から 2012 変更でのトリガーの修正

2008から2012へ変更の為、互換性レベルを上げてアタッチしました。
読み込みや一部のテーブルの更新には問題がなかったのですが、いくつかのテーブルでINSERTとUPDATEのエラーが出てしまい
トリガーのRAISERROR文が原因である事が分かりました。

最初に発生していたエラー

メッセージ 102、レベル 15、状態 1、プロシージャ SEIZOU_更新トリガ、行 8
'44444' 付近に不適切な構文があります。
メッセージ 102、レベル 15、状態 1、プロシージャ SEIZOU_更新トリガ、行 17
'44444' 付近に不適切な構文があります。

トリガーではNULLのチェックをしています(「該当のソースコード」参照)
また、テーブル構造は下記のようになっています。

SID int 主キー
登録日 datetime 主キー
枝番 int NULL許容する
場所 varchar(5) NULL許容する

アドバイス頂きたいのは下記です
・主キー、NULL許容しない項目の場合、トリガーで処理をする必要がないと言えるでしょうか?
(このようなチェックだけのトリガー自体を消す方が早いように思える為)

・上記のような項目以外で、わざと値のチェックとエラーを出すような場合
「試したこと」に書いたような文で動作はしますが
旧文とエラーNoの扱いが違う為、’44444’のようなエラー番号を出したい場合、全く同じことができていないように思えます。
もう少し良い書き方はあるでしょうか?

該当のソースコード

SQL

ALTER TRIGGER [dbo].[SEIZOU_更新トリガ] ON [dbo].[SEIZOU] FOR UPDATE AS /* * 'SID' に Null 値を許可しない */ IF (SELECT Count(*) FROM inserted WHERE SID IS NULL) > 0 BEGIN RAISERROR 44444 '''SID'' フィールドでは Null 値は使えません。' ←エラー箇所 ROLLBACK TRANSACTION END ELSE /* * '登録日' に Null 値を許可しない */

試したこと

一先ず、下記のように変更してみました。

SQL

IF (SELECT Count(*) FROM inserted WHERE SID IS NULL) > 0 BEGIN RAISERROR 44444 '''SID'' フィールドでは Null 値は使えません。' ROLLBACK TRANSACTION END ``````SQL IF (SELECT Count(*) FROM inserted WHERE SID IS NULL) > 0 BEGIN RAISERROR('44444 ''SID'' フィールドでは Null 値は使えません。',16,1); ROLLBACK TRANSACTION END

上記の書き換えで、NULL値以外の更新で「'44444' 付近に不適切な構文」のエラーは出なくなりました。
改めてNULL更新の確認をすると下記のエラーが表示されます。

メッセージ 515、レベル 16、状態 2、行 3
テーブル '生産管理システム.dbo.SEIZOU' の列 'SID' に値 NULL を挿入できません。この列では NULL 値が許可されていません。UPDATE は失敗します。

※トリガーの判定に行かない

##追記:2019/10/28
回答から:
RAISERROR(Transact-SQL)
RAISERROR issue since migration to SQL Server 2012

(※ソースコードの変更点のコードを見やすく分けました)RAISERROR文は
RAISERROR( msg_str, severity ,state) の形が例文にもあるので引数の順番は大丈夫だと思うのですが
Serverityの値に細かい決まりがあった事と、例文ではTRY~CATCHの中で使っているようですので原文をどう書き直せばいいか考えてみます。

また、sys.messages カタログビューに一度登録して、RAISERROR ( msg_id ,severity ,state}のようにする方法があるようですが
こっちの方が意図した方法のような気がしました。こっちの方が書き直すのが難しそうですが…

THROW文は特にTRY~CATCHを使わなければいけないようですので、書いたことがないですが余裕ができたときに試せればと思います。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。