(NodeId、NodeName)と構造テーブル(ParentNodeId、ChildNodeId)を持つノードテーブルがあります。 insert updateまたはdelete文が無限の関係を引き起こす可能性があるかどうかをチェックするトリガを書くにはどうすればよいですか?SQLツリーの無限ループを防ぐためのトリガー
3
A
答えて
1
親が直接的または間接的に子の子にならない循環依存条件を再帰的にチェックする必要があります。
SQL Server 2005では、同じものに対して再帰的なCTEを書くことができます。例 -
WITH [RecursiveCTE]([Id], [ParentAccountId]) AS
(
SELECT
[Id],
[ParentAccountId]
FROM [Structure]
WHERE [Id] = @Id
UNION ALL
SELECT
S.[Id],
S.[ParentAccountId]
FROM [Structure] S INNER JOIN [RecursiveCTE] RCTE ON S.[ParentAccountId] = RCTE.[Id]
)
SELECT * FROM [RecursiveCTE]
3
これは私のソリューションであり、これまでのところ期待通りに動作します。
CREATE TRIGGER [dbo].[CheckNodeDependence] ON [dbo].[ObjectTrees]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON
DECLARE @CTable TABLE(ChildId INT NOT NULL,
ParentId INT NOT NULL,
[Level] INT NOT NULL,
RowId INT NOT NULL)
DECLARE @Level INT
SET @Level = 1
DECLARE @rows_affected INT
SET @rows_affected = 1
INSERT INTO @CTable
SELECT ObjectId, ParentId, 1, ObjectId FROM INSERTED
WHILE @rows_affected > 0
BEGIN
SET @Level = @Level + 1
INSERT INTO @CTable
SELECT T.ObjectId, T.ParentId, @Level, C.RowId
FROM ObjectTrees T
INNER JOIN @CTable C ON T.ParentId = C.ChildId
AND C.Level = @Level - 1
SET @rows_affected = @@rowcount
IF EXISTS(
SELECT * FROM @CTable B
INNER JOIN @CTable V ON B.level = 1
AND V.Level > 1
AND V.RowId = B.RowId
AND V.ChildId = B.RowId)
BEGIN
DECLARE @error_message VARCHAR(200)
SET @error_message = 'Operation would cause illegal circular reference in tree structure, level = ' + CAST(@Level AS VARCHAR(30))
RAISERROR(@error_message,16,1)
ROLLBACK TRANSACTION
RETURN
END
END
END
GO
関連する問題
- 1. ASP.netの無限ループを防ぐ方法
- 2. デプスファーストサーチアルゴリズムが無限ループに陥るのを防ぐために8 Puzzle
- 3. Vue2 + JQueryライブラリ - 必要なコンポーネントの無限ループ、プライベートプロパティを防ぐ
- 4. 2つのEditTextで無限ループを防ぐ方法は?
- 5. Groovyスクリプト:可能なメモリリークや無限ループを防ぐ方法
- 6. RxJs:無限ループを防止
- 7. postgresqlの更新を防ぐためのトリガー
- 8. ループのための無限ループとデッドコード
- 9. Prologの無限ループ。これをどうやって防ぐのですか?
- 10. Pythonのサブプロセスで無限ループを防ぐ方法を教えてください。
- 11. Googleの視覚化による無限ループを防ぐ方法setSelection()?
- 12. データベースの破損を防ぐSQL Serverのトリガー
- 13. タートルのための無限ループlisten
- 14. クリアアクションepicのための無限ループ
- 15. mousemownがトリガーするのを防ぐ
- 16. A PHPのSQLインジェクションを防ぐための機能とXSS
- 17. SQLインジェクションを防ぐための変数のクリーンアップ方法 - union select?
- 18. codeigniterのSQLインジェクションを防ぐための基本的な知識
- 19. データベースレベルプライマリキーのないテーブルの作成を防ぐためのテーブル作成のトリガー
- 20. SQLインジェクションを防ぐ
- 21. PL/SQL挿入を防止するためのトリガー
- 22. ゲームの無限ジャンプを防ぐ方法は?コロナLUA
- 23. Tampermonkey Script - 無限の送信を防ぐ方法
- 24. PHPのスクリプトタイムアウトを防ぐためのusleep
- 25. プロセスマイニングを防ぐためにログを無効にできます。
- 26. Asyncio、無限ループ、無限ループ
- 27. MemoryCache - アイテムの期限切れを防ぐ
- 28. SQLインジェクションを防ぐためにパラメータ化されたSQLクエリを書くには?
- 29. エラー:レッド・ブラック・ツリー内の無限ループ文があれば
- 30. PHP円の依存性に無限ループを引き起こすような陥凹のDICを防ぐ方法
しかし、いったん検出されると、挿入/更新がトリガを使用して失敗する最も良い方法は何ですか? – MatBailie
プラットフォームによって異なります。 Oracleでは、できるだけ多くの有益な情報をテキストに含めて、うまくいけば例外をスローします。しかし、実際は、それはアプリケーションに依存しますね。 –
はい。使用しているアプリケーションによって異なります。 SQL Serverでは、例外をスローして挿入を停止します。または、代わりにトリガーを使用して何もしないでください。 – Kirtan