假設以下是部分的原始資料(欄位其實有數十個)
--#table1 原始資料
CREATE TABLE #table1
(
[Area] char(1), --
[Name] nvarchar(10), --
[Date] char(8), --西元年月日
[Qty] int, --整數
[Plan] char(2), --A1~A4 B1~B4
[Delivery] char(1), --0或1
[Delay] char(1) --0或1
)
INSERT INTO #table1
VALUES
('A', 'Carl', '20220405', 5, 'A3', '1', '0'),
('D', 'Ben', '20220499', 4, 'B4', '1', '0'),--有錯
('C', 'Allen', '20220501', 4, 'A1', '1', '0'),
('B', 'John', '2022060', 2, 'A1', '0', '1'),--有錯
('B', 'Mason', '20220223', 6, 'B1', '1', '0'),
('D', 'Nick', '20220326', 4, '3', '1', '2'),--有錯
('A', 'Peter', '20220302', 5, 'B3', '1', '0'),
('C', 'David', '20220112', 5, 'B3', '1', '2'),--有錯
('C', 'William','20220421', 3, 'A1', '0', '0'),
('D', 'Ted', '20220610', 2, 'A2', '1', '0'),
('A', 'Mike', '20220726', 6, 'A2', '1', '0'),
('B', 'Joe', '20220301', 4, 'B2', '0', '0'),
('C', 'Louis', '20220611', 4, 'B2', '1', '1'),
('A', 'Rick', '20220528', 3, 'B3', '0', '1'),
('D', 'Tom', '20220516', 3, 'B1', '', '0') --有錯
SELECT * FROM #table1
今天想檢查資料庫內的data是否符合標準,如日期格式,字串長度等等(寫入#table2),
最後再通知負責該Area的人員去做更正(#table3)。
--#table2 找出有錯的資料
SELECT [Area],[Name],'訊息'='[Date]格式錯誤' INTO #table2 FROM #table1 WHERE ISDATE([Date]) = 0
UNION
SELECT [Area],[Name],'訊息'='[Plan]錯誤' FROM #table1 WHERE NOT(LEFT([Plan],1) IN ('A','B') AND Right([Plan],1) BETWEEN '1' AND '4')
UNION
SELECT [Area],[Name],'訊息'='[Delivery]應為0或1' FROM #table1 WHERE NOT([Delivery] IN ('0','1'))
UNION
SELECT [Area],[Name],'訊息'='[Delay]應為0或1' FROM #table1 WHERE NOT([Delay] IN ('0','1'))
SELECT * FROM #table2
SELECT DISTINCT [Area],[Name],
STUFF((
SELECT '*' + [訊息]
FROM #table2
WHERE [Area] = t.[Area] AND [Name] = t.[Name]
FOR XML PATH('')
), 1, 1, '') AS d
INTO #table3
FROM #table2 t
--找出D區錯誤的資料
SELECT * FROM #table3 WHERE [Area] = 'D'
我這樣寫,是想說如果欄位有異動、規則有改,我只要增減UNION片段就好,
不知道這樣有沒有考量不周的情況?或有更好的寫法?
你的問題應該是在設計資料庫時候就應該考慮進去,不是在填寫資料時候檢查。
例如設計日期欄位時候使用日期格式,文字時候限制長度是多。