0

私は自己関連のテーブルを作成しています:

テーブルItem列:
ItemId int-PK;
金額-nullではありません。価格マネー-アイテムの祖先の金額に従って値を取得するUDFを使用して計算された列。
ParentItemId int-null許容、このテーブル内の別のItemIdへの参照。

ループを回避する必要があります。つまり、兄弟は祖先の祖先になることはできません。つまり、ItemId = 2 ParentItemId = 1の場合、ItemId 1 ParentItemId=2は許可されません。

この状況でのベストプラクティスはどうあるべきかわかりません。UDFなどからスカラー値を取得するCKを追加する必要があると思います。

編集: 別のオプションは、INSTEAD OFトリガーを作成し、1つのトランザクションにParentItemIdフィールドの更新を入れ、トランザクションのキャンセルに失敗した場合は@@ RowIdentityからPriceフィールドを選択することですが、UDF検証を希望します。

どんなアイデアでも大歓迎です。

4

5 に答える 5

1

これは間違いなくデータベースレベルで実施する必要がありますか?

私はこのようなデータベース(これに似たテーブルはフォルダーのようなものです)を持っているので質問しているだけで、アプリケーションで正しい親子関係が設定されていることを確認するだけです。

于 2009-12-22T08:33:12.090 に答える
1

このようなチェックは実装するのが簡単ではなく、考えられる解決策は多くのバグを引き起こす可能性があり、最初の問題よりも難しい問題になる可能性があります。通常は、ユーザー入力の制御を追加し、読み取りデータの無限ループを防止するだけで十分です。アプリケーションがストアド プロシージャを使用し、ORM を使用しない場合、このロジックを SP に実装することを選択します。それ以外の場合 - DB ではなく、他のレイヤーで処理します

于 2009-12-22T08:39:40.237 に答える
0

実生活では、これはどれほど大きな問題ですか?これらの状況を検出するには(おそらくトリガーを使用して)コストがかかる可能性があります。実際、すべてのトランザクションのごく一部だけがこの問題を引き起こす場合、トランザクションごとに多くの労力がかかる可能性があります。

最初に考えてください。

于 2009-12-22T08:31:26.023 に答える
0

簡単なトリックは、ParentItemIdをItemIdよりも小さくすることです。これにより、この単純なコンテキストでループが閉じられるのを防ぎます。

ただし、欠点があります。何らかの理由で親を削除/挿入する必要がある場合は、その子もすべて削除/挿入する必要がある場合があります。

同様に、階層を順番に挿入する必要があり、親を再割り当てできない場合があります。

于 2009-12-22T08:32:20.993 に答える
0

テスト済みで、うまく機能します:

CREATE TRIGGER Item_UPDATE
   ON Item
   FOR INSERT, UPDATE
AS 
BEGIN

BEGIN TRY
    SELECT Price FROM INSERTED
END TRY
BEGIN CATCH
    RAISERROR('This item cannot be specified with this parent.', 16, 1)
    ROLLBACK TRANSACTION;
END CATCH

END
GO
于 2009-12-22T09:42:12.757 に答える