私は仕事で議論に巻き込まれ、見落としている可能性のある落とし穴についてアドバイスが必要です。
削除されたレコードを監査テーブルにコピーするためにトリガーが使用されるシナリオを想像してみてください。トリガーはSELECT *を使用します。誰もが指さして叫び、これがどれほど悪いかを私たちに教えます。
ただし、メインテーブルの構造に変更が加えられ、監査テーブルが見落とされた場合、トリガーによってエラーが生成され、監査テーブルにも変更が必要であることを通知します。
このエラーは、DEVサーバーでのテスト中に検出されます。ただし、プロダクションがDEVと一致することを確認する必要があるため、プロダクションシステムでSELECT *を許可します(トリガーのみ)。
だから私の質問は:私はSELECT *を削除するようにプッシュされていますが、この性質の開発エラー、アイデア、またはこのベストプラクティスを自動的にキャプチャしていることを確認する他の方法がわかりませんか?
以下の例をまとめました:
--Create Test Table
CREATE TABLE dbo.Test(ID INT IDENTITY(1,1), Person VARCHAR(255))
--Create Test Audit Table
CREATE TABLE dbo.TestAudit(AuditID INT IDENTITY(1,1),ID INT, Person VARCHAR(255))
--Create Trigger on Test
CREATE TRIGGER [dbo].[trTestDelete] ON [dbo].[Test] AFTER DELETE
NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TestAudit([ID], [Person])
SELECT *
FROM deleted
END
--Insert Test Data into Test
INSERT INTO dbo.Test VALUES
('Scooby')
,('Fred')
,('Shaggy')
--Perform a delete
DELETE dbo.Test WHERE Person = 'Scooby'
更新(言い換え質問):
私はDBAであり、ベストプラクティスドキュメントに貢献することで、開発者が十分に考え抜かれた展開スクリプトを提供しないようにする必要があります。SELECT *は、開発者が監査テーブル(これはセーフティネットです)を見落とすと、DEVでエラーが発生するため、開発プロセスの早い段階でエラーがキャッチされます。しかし、SQL憲法のどこかで-2番目の改正では、「あなたはSELECT *を使わないでください」と書かれています。そのため、セーフティネットを排除する必要があります。
セーフティネットをどのように置き換えますか、またはこれをトリガーのベストプラクティスと見なす必要がありますか?
更新2:(解決策)
たくさんのご意見ありがとうございました。これは非常に灰色の主題であるように思われるため、明確な答えがあるかどうかはわかりません。しかし、まとめて、開発者がベストプラクティスの定義を進めるのに役立つディスカッションポイントを提供しました。
Daevin
あなたの貢献に感謝します。あなたの答えは、開発者が実装できるいくつかのテストメカニズムの基礎を提供します。+1
おかげでCM_Dayton
、ベストプラクティスに貢献する提案は、監査トリガーを開発しているすべての人にとって有益です。+1
おかげでypercube
、さまざまな形式の定義変更が行われるテーブルに関する問題について多くのことを考えました。+1
結論として:
Is Select * ok in a tigger?
はい、それは灰色の領域です。「選択*は悪い」というイデオロギーを盲目的に実行しないでください。
Am I asking for Trouble?
はい、テーブルに新しい列を追加するだけではありません。
SELECT *
セーフティネットとして使用するのは好きですが、すべてのケースに対応できるわけではありません。たとえば、列を削除して再度追加した場合などです。これにより、列の順序が変更され、(すべての列が同じタイプでない限り)監査テーブルへの挿入が失敗するか、暗黙的なタイプ変換によりデータが失われます。