2016-03-06 55 views
0

我正在使用SQL Server Management Studio 2014,並且正在編寫一個存儲過程以插入到具有外鍵的許多表中。帶有多個表插入的SQL Server存儲過程

我得到兩個錯誤:

消息547,級別16,狀態0,過程insertintoorders,163線
INSERT語句衝突與外鍵約束 「FK__Customers__Addre__145C0A3F」。衝突發生在數據庫「FlowerCompany」,表「dbo.Addresses」,列'AddressID'中。

消息547,級別16,狀態0,過程insertintoorders,178線
INSERT語句衝突與外鍵約束 「FK__Orders__Customer__1FCDBCEB」。衝突發生在數據庫「FlowerCompany」,表「dbo.Customers」,列'CustomerID'。

這裏是我的存儲過程和我對它的測試執行:

CREATE PROCEDURE insertintoorders 
    @Street varchar(50), 
    @City varchar(30), 
    @State varchar(2), 
    @Zip varchar(9), 
    @Phone varchar(10), 
    @FlowerName varchar(50), 
    @FirstName varchar(40), 
    @LastName varchar(40), 
    @OrderStatus varchar(12), 
    @DeliverDate date, 
    @OrderMessage varchar(100), 
    @OrderDate date, 
    @Vase bit, 
    @OrderCost decimal(6,2) 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    DECLARE @flower int; 

    SELECT @flower = Arr.FlowerID 
    FROM Arrangements Arr 
    WHERE FlowerName = @FlowerName 

    DECLARE @AddID int; 
    SELECT @AddID = coalesce((SELECT MAX(AddressID) + 1 FROM Addresses), 1) 

    DECLARE @PhoneID int; 
    SELECT @PhoneID = coalesce((SELECT MAX(PhoneID) + 1 FROM Phone), 1) 

    DECLARE @CustID int; 
    SELECT @CustID = coalesce((SELECT MAX(CustomerID) + 1 FROM Customers), 1) 

    DECLARE @Del int; 
    SELECT @Del = coalesce((SELECT MAX(DeliveryID) + 1 FROM Delivery), 1) 

    DECLARE @Ords int; 
    SELECT @Ords = coalesce((select max(StatusID) + 1 from OrderStatus), 1) 

    DECLARE @Ord int; 
    SELECT @Ord = coalesce((select max(OrderID) + 1 from Orders), 1) 

    INSERT INTO Addresses (Street, City, States, Zip) 
    VALUES (@Street, @City, @State, @Zip) 

    SET @AddId = SCOPE_IDENTITY() 

    INSERT INTO Phone (Phone) 
    VALUES (@Phone) 

    SET @PhoneID = SCOPE_IDENTITY() 

    INSERT INTO Customers (AddressID, PhoneID, FirstName, LastName) 
    VALUES (SCOPE_IDENTITY(), SCOPE_IDENTITY(), @FirstName, @LastName) 

    SET @CustID = SCOPE_IDENTITY() 

    INSERT INTO Delivery (DeliverDate) 
    VALUES (@DeliverDate) 

    SET @Del = SCOPE_IDENTITY() 

    INSERT INTO OrderStatus (OrderStatus) 
    VALUES (@OrderStatus) 

    SET @Ords = SCOPE_IDENTITY() 

    INSERT INTO Orders ([CustomerID], [FlowerID], [StatusID],[DeliveryID], OrderMessage, OrderDate, OrderCost, Vase) 
    VALUES (SCOPE_IDENTITY(), @flower, SCOPE_IDENTITY(), SCOPE_IDENTITY(), @OrderMessage, @OrderDate, @OrderCost, @Vase) 

    SET @Ord = SCOPE_IDENTITY() 
END 
GO 

EXEC insertintoorders @Street = '555 LANE', @City='Somewhere', @State = 'XX', @Zip = '99999', @Phone = '1234567896', @FlowerName = 'The Flower of Love', @FirstName = 'George', 
@LastName = 'Fish', @DeliverDate = '10/10/2016', @OrderStatus = 'Completed', @OrderMessage = 'Fishy flowers', @OrderDate = '03/03/2016', @OrderCost = '200', @Vase = '1' 

雖然我讀過的錯誤,我不理解如何解決這些問題,或者爲什麼他們在那裏。

+0

因此,你的表已經在IDENTITY列上有PK,但是你可能不相信這個工作是愚蠢的服務器並且自己完成所有工作?像困難的方式? –

+0

你可以顯示外鍵的腳本嗎? –

回答

2

您正在使用IDENTITY_INSERT併爲PhoneId和AddressId插入自己的值。 SCOPE_IDENTITY()始終是插入到標識列中的最後一個值,因此在插入電話後,它將返回PhoneId並永遠不會添加Id。

選項1:使用您擁有的值。這是一個糟糕的主意,因爲如果你做兩增加的同時,你可能會得到衝突

SET IDENTITY_INSERT dbo.Customers ON 
INSERT INTO Customers (CustomerID,AddressID,PhoneID,FirstName,LastName) 
VALUES (@CustID, @AddId, @PhoneId ,@FirstName, @LastName) 
SET IDENTITY_INSERT dbo.Customers OFF 

選項2:只是讓系統設置的標識值和每個插入之後讓他們,即:

INSERT INTO Addresses (Street, City, States, Zip) 
VALUES (@Street,@City,@State,@Zip) 
SET @AddId = SCOPE_IDENTITY() 
+0

我將選項2更改爲選項2,並且出現相同的錯誤 – wiredlime2015

+0

完全刪除所有「select max + 1」部分 –

+0

在適當的插入語句後立即用SCOPE_IDENTITY值填充每個變量。就像@Jason用「地址」示例演示的一樣。 –

相關問題