一種方式是通過在模板表上創建AFTER INSERT
觸發,使得當您從導入表中插入時,它將自動更新Parent_Id
,Lev_No
,Primary_Cat_Id
和Last_Lev
的值。
我假設你的表結構是這個樣子:
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);
你觸發看起來應該像下面這樣:
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
有可能做到這一點更簡單的方法,但這在技術上是有效的(至少在樣本數據方面)。
在此之後,你只需要一個鼠標或東西一一做刀片,先從主要類別:
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