2013-04-03 130 views
1

我有一個包含有關供應商信息的一部分的表SQL Server的條件插入

背景:本表是聯接

  • 的部分主記錄,其中包含
    • 的的部件號,部件名稱和默認供應商。
  • 其他表是包含
    • 針對供應商的部件號的記錄,他們對部分報價供應商信息表(有額外的信息,我已經離開了這個例子)

在這張表中,一些零件的默認供應商是NULL。 對於那些我希望插入一條新記錄作爲佔位符 即#3低於

某些零件有默認供應商,但沒有可能的供應商記錄(帶引用)。 對於那些記錄,我也想插入一個新的記錄作爲佔位符。 即低於

當前表

+-------+-----------+-------------------+-------------------+------------+------------+ 
|PART |PART NAME |Default Supplier |Possible Suppliers |Quote  |InfoComplete| 
+-------+-----------+-------------------+-------------------+------------+------------+ 
|#1  |Part 1  |Supplier 5   |Supplier 1   |25.0  |0   | 
|#1  |Part 1  |Supplier 5   |Supplier 2   |20.5  |0   | 
|#2  |Part 2  |Supplier 10  |Supplier 10  |10.4  |1   | 
|#3  |Part 3  |NULL    |Supplier 3   |9.5   |0   | 
|#3  |Part 3  |NULL    |Supplier 4   |11.5  |0   | 
+-------+-----------+-------------------+-------------------+------------+------------+ 

所需的輸出(空間清晰顯示)

+-------+-----------+-------------------+-------------------+------------+------------+ 
|PART |PART NAME |Default Supplier |Possible Suppliers |Quote  |InfoComplete| 
+-------+-----------+-------------------+-------------------+------------+------------+ 
|#1  |Part 1  |Supplier 5   |Supplier 1   |25.0  |0   | 
|#1  |Part 1  |Supplier 5   |Supplier 2   |20.5  |0   | 
|#2  |Part 2  |Supplier 10  |Supplier 10  |10.4  |1   | 
|#3  |Part 3  |NULL    |Supplier 3   |9.5   |0   | 
|#3  |Part 3  |NULL    |Supplier 4   |11.5  |0   | 
|  |   |     |     |   |   |  
|#1  |Part 1  |Supplier 5   |**MISSING**  |NA   |0   | 
|#3  |Part 3  |**MISSING**  |**MISSING**  |NA   |0   | 
+-------+-----------+-------------------+-------------------+------------+------------+ 

#1從我讀了MERGE語句可能是一個解決方案,但我不能」不要讓它工作。

編輯:

對不起,我應該一直在我最初的職位更清晰一點,該信息被輸出到用戶查看丟失的數據。 沒有計劃替換數據庫中的NULL值。

我只是想操縱數據,以使用戶更清楚地瞭解數據。

根據反饋,我正在尋找更好的方式向用戶顯示信息。

+0

爲什麼要在這些記錄中浪費額外的空間來存儲'** MISSING **時,NULL會是一種更高效和典型的數據安排?此外,採用這種方法將會搜索缺省供應商空效率較低的零件。 –

+0

我無法從示例中看到第1部分(和第3部分)如何從可能的供應商處獲得** MISSING **? –

回答

1

考慮使用觸發器

CREATE TRIGGER NULL_DEFAULTSUPP 
AFTER INSERT ON TABLE-NAME 
FOR EACH ROW BEGIN 
WHERE NEW.Default Supplier IS NULL 
BEGIN 
INSERT INTO TABLE-NAME VALUES(NEW.PART, NEW.PART-NAME, "**MISSING**", ....); 
END; 
+0

謝謝你的幫助。 – Spacko

1

我決定不等着聽你的理由爲希望與magic strings更換空值。我只能假設你想這樣做,因爲你希望你的查詢很簡單,並且只要缺省供應商爲NULL,就輸出短語**MISSING**。有更好的方法以非重複的方式完成這項任務,而不是將外鍵轉換爲供應商(假設您有外鍵)到可從空包含的可爲空的varchar字段中。

我會建議你使用視圖如果是像這樣的情況下訪問此數據:

IF (OBJECT_ID('dbo.vw_PartsSuppliers') IS NOT NULL) 
    DROP VIEW dbo.vw_PartsSuppliers 
GO 

CREATE VIEW dbo.vw_PartsSuppliers 
AS 
    SELECT 
     p.PartId, 
     p.PartName, 
     ISNULL(s.SupplierName, '**MISSING**'), 
     ISNULL(s.Quote, 'NA'), 
     s.InfoComplete 
    FROM 
     dbo.Part p 
     LEFT JOIN dbo.Supplier s ON p.DefaultSupplierId = s.SupplierId    
GO 

這種方法是靈活的,可重複使用,並會給你你所追求的格式。此外,一旦查詢出現,您需要識別沒有默認供應商的零件(您可能會這樣做),因此您不會遇到性能問題,因爲您沒有搜索神奇字符串,而是查找NULL。

+0

謝謝你的幫助。我編輯了我的第一篇文章來解釋我的瘋狂! – Spacko

0

在這種情況下供應商ID用作表dbo.Supplier和Id PRIMARY KEY對錶dbo.SupplierInfo該外鍵與表dbo.Supplier關聯DefSupplierId

DECLARE @SupplierId TABLE(SupplierId int) 

INSERT dbo.Supplier(Part, PartName, DefaultSupplier) 
OUTPUT inserted.SupplierId INTO @SupplierId(SupplierId) 
SELECT DISTINCT s.Part, s.PartName, ISNULL(s.DefaultSupplier, '**MISSING**')  
FROM dbo.Supplier s LEFT JOIN dbo.SupplierInfo i ON s.SupplierId = i.DefSupplierId 
WHERE s.DefaultSupplier IS NULL OR i.PossibleSuppliers IS NULL 

INSERT dbo.SupplierInfo 
SELECT SupplierId, '**MISSING**', 0, 0 
FROm @SupplierId 

演示上SQLFisddle

0
PRIMARY KEY

這是一個簡單的例子,你可以使用MERGE來實現你想要的輸出。只有一個表PartsSuppliersInfo具有上述示例中有關零件和供應商的數據。

SQLFiddle DEMO

;WITH trgtCTE AS 
(
    SELECT Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete FROM PartsSuppliersInfo 
    WHERE DefaultSupplier = '**MISSING**' OR [PossibleSuppliers] = '**MISSING**' 
) 
MERGE trgtCTE AS trgt 
USING 
(
    SELECT DISTINCT Part, PartName, '**MISSING**' AS DefaultSupplier,'**MISSING**' AS PossibleSuppliers, NULL AS Quote, 0 AS InfoComplete FROM PartsSuppliersInfo 
    WHERE DefaultSupplier IS NULL 
    UNION 
    SELECT DISTINCT p.Part, PartName, DefaultSupplier,'**MISSING**' AS PossibleSuppliers, NULL AS Quote, 0 AS InfoComplete FROM PartsSuppliersInfo p 
    WHERE DefaultSupplier IS NOT NULL AND InfoComplete = 0 
) src 
ON src.part = trgt.part AND src.DefaultSupplier = trgt.DefaultSupplier AND src.PossibleSuppliers = trgt.PossibleSuppliers 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete) 
    VALUES (Part, PartName, DefaultSupplier, PossibleSuppliers, Quote, InfoComplete) 
WHEN NOT MATCHED BY SOURCE THEN 
    DELETE; 
MERGE

目標部分是CTE與具有**MISSING**關鍵字唯一的行。第一次它是空的,但是每次下一次語句運行時,它都會有前一次運行的結果。

源部分是具有邏輯的子查詢如何計算哪些**MISSING**行應該存在。

最後兩部分刪除不再需要的行(如果零件不再缺失)並插入新行。