一つの方法は、テンプレートテーブルの上にAFTER INSERT
トリガーを作成することである下にサブカテゴリーが、このような、ある意味でインポートテーブルから挿入すると、Parent_Id
,Lev_No
,Primary_Cat_Id
およびLast_Lev
の値が自動的に更新されます。
私はあなたのテーブルの構造はこのような何かを見てと仮定しています:
IF OBJECT_ID('tr_Template_Insert', 'TR') IS NOT NULL DROP TRIGGER tr_Template_Insert;
GO
CREATE TRIGGER tr_Template_Insert
ON Template
AFTER INSERT
AS BEGIN
WITH CTE AS (
SELECT RN, cats, lvl
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM Import) T
CROSS APPLY (
VALUES ([Main Category], 1)
, ([Sub Category 1], 2)
, ([Sub Category 2], 3)) S(cats,lvl)
WHERE S.cats IS NOT NULL
)
UPDATE T
SET Last_Lev = Z.lastLev
, Primary_Cat_Id = COALESCE(Z.PrimaryCat, T.CSD_ID)
, Parent_Id = COALESCE(Z.ParentCat, T.CSD_ID)
, Lev_No = Z.levNo
FROM Template T
JOIN (
SELECT C.cats
, MAX(CASE WHEN C.lvl = LL.lastlev THEN 1 ELSE 0 END) lastLev
, MAX(Pri.primarycat) PrimaryCat
, MAX(Par.parentcat) ParentCat
, MAX(lvl) levNo
FROM CTE C
JOIN inserted I ON I.Category = C.cats
OUTER APPLY (
SELECT T.CSD_ID
FROM CTE CZ
JOIN Template T ON T.Category = CZ.cats
WHERE CZ.RN = C.RN
AND CZ.lvl = 1) Pri(primarycat)
OUTER APPLY (
SELECT T.CSD_ID
FROM CTE CZ
JOIN Template T ON T.Category = CZ.cats
WHERE CZ.RN = C.RN
AND CZ.lvl = C.lvl-1) Par(parentcat)
OUTER APPLY (
SELECT MAX(lvl)
FROM CTE CZ
WHERE CZ.RN = C.RN) LL(lastlev)
GROUP BY C.cats) Z ON Z.cats = T.Category;
END
これを行うための簡単な方法があるかもしれません、しかし:あなたのトリガーは、次のようになるはずです
IF OBJECT_ID('Import', 'U') IS NOT NULL DROP TABLE Import;
CREATE TABLE Import (
[Main Category] VARCHAR(255) -- NOT NULL?
, [Sub Category 1] VARCHAR(255)
, [Sub Category 2] VARCHAR(255));
INSERT Import
VALUES ('Domestic', NULL, NULL)
, ('Domestic', 'House', NULL)
, ('Domestic', NULL, NULL)
, ('Domestic', NULL, NULL)
, ('Domestic', 'Bath', 'Toilet')
, ('Domestic', NULL, NULL)
, ('Commercial', NULL, NULL)
, ('Commercial', NULL, NULL)
, ('Commercial', NULL, NULL)
, ('Commercial', NULL, NULL)
, ('Commercial', NULL, NULL)
, ('Commercial', NULL, NULL);
IF OBJECT_ID('Template', 'U') IS NOT NULL DROP TABLE Template;
CREATE TABLE Template (
CSD_ID INT IDENTITY (1, 1) PRIMARY KEY
, Category VARCHAR(255) NOT NULL
, Parent_Id INT
, Lev_No INT
, Primary_Cat_Id INT
, Last_Lev BIT);
これは技術的には機能します(サンプルデータと少なくとも)。
その後、あなただけの主要なカテゴリから開始し、ひとつずつ挿入を行うには、カーソルまたは何かが必要だろう:
DECLARE @cats VARCHAR(255);
DECLARE curs CURSOR FOR
SELECT cats
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM Import) Z
CROSS APPLY (
VALUES ([Main Category], 1)
, ([Sub Category 1], 2)
, ([Sub Category 2], 3)) S(cats,lvl)
LEFT JOIN Template T ON T.Category = S.cats
WHERE S.cats IS NOT NULL
AND T.Category IS NULL
GROUP BY cats
ORDER BY MIN(lvl); -- main cats first, then subcat1, then subcat2
OPEN curs;
FETCH NEXT FROM curs INTO @cats;
WHILE @@FETCH_STATUS = 0 BEGIN
INSERT Template(Category)
VALUES (@cats);
FETCH NEXT FROM curs INTO @cats;
END
CLOSE curs;
DEALLOCATE curs;
カーソルをメインカテゴリ、その後、サブカテゴリー1を挿入し、その後、サブカテゴリ2とトリガーが残りの値を入力します。
申し訳ありませんが、BathのParent_IDは1 – Jay
である必要があります。そのため、テンプレートテーブルが空になり、特定の値で入力しますか?そうであれば、インサートのCSD_ID/Categoryを取得してインポートテーブルに対してチェックし、それに応じてparent_id、primary_cat_id、last_levを更新するために、挿入後トリガを実行する必要があります。 – ZLK