質問:SQL スクリプトまたはストアド プロシージャでマジック ナンバーやハードコードされた値を回避するための他の戦略にはどのようなものがありますか?
StatusID
レコードの値、またはその他の FK ルックアップ テーブル、または値の範囲に基づいてレコードの値をチェック/更新するストアド プロシージャについて考えてみましょう。
Status
ID が別のテーブルへの FK であるため、ID が最も重要であるテーブルを考えてみましょう。
避けるべきSQLスクリプトは何かのようなもの:
DECLARE @ACKNOWLEDGED tinyint
SELECT @ACKNOWLEDGED = 3 --hardcoded BAD
UPDATE SomeTable
SET CurrentStatusID = @ACKNOWLEDGED
WHERE ID = @SomeID
ここでの問題は、これが移植可能ではなく、ハードコードされた値に明示的に依存していることです。これを ID 挿入をオフにした別の環境に展開すると、微妙な欠陥が発生します。
SELECT
また、ステータスのテキストの説明/名前に基づいて回避しようとしています:
UPDATE SomeTable
SET CurrentStatusID = (SELECT ID FROM [Status] WHERE [Name] = 'Acknowledged')
WHERE ID = @SomeID
質問:SQL スクリプトまたはストアド プロシージャでマジック ナンバーやハードコードされた値を回避するための他の戦略にはどのようなものがありますか?
これを実現するための他の考え方:
- 新しい
bit
列 (「IsAcknowledged」などの名前) と、 の値を持つ行が 1 つだけ存在するルール セットを追加します1
。これにより、一意の行を見つけるのに役立ちます。SELECT ID FROM [Status] WHERE [IsAcknowledged] = 1)
ベストアンサー1
ステータステーブルのような状況では、私は「静的」データセットと呼ぶものを作成します。これらのテーブルには、
- 作成時に設定され定義され、
- 決して変わることなく、
- データベースインスタンスごとに常に同じであり、いいえ例外
つまり、テーブルを作成すると同時に、スクリプトを使用して値が常に同じになるようにデータを入力します。その後は、データベースがどこにあっても、いつあっても、知る値が何であるかを把握し、それに応じて適切にハードコードすることができます。(このような状況では、代理キーや ID 列プロパティを使用することはありません。)
数字を使用する必要はなく、文字列、バイナリ、日付など、最も単純で簡単、かつ適切なものを使用できます。(可能な場合は、varchar ではなく char 文字列を使用します。たとえば、「RCVD」、「DLVR」、「ACKN」などは、0、2、3 などの値よりもハードコードしやすい値です。)
このシステムは、拡張不可能な値のセットに対して機能します。これらの値を変更できる場合 (0 が「確認済み」を意味しなくなるなど)、セキュリティ アクセスの問題が発生します。ユーザーが新しいコードを追加できるシステムの場合は、解決すべき別の難しい設計上の問題があります。