具有多表插入的SQL Server存储过程

具有多表插入的SQL Server存储过程,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我正在使用SQL Server Management Studio 2014,我正在编写一个存储过程,以插入到许多带有外键的表中 我有两个错误: Msg 547,16级,状态0,程序插入命令,第163行 INSERT语句与外键约束“FK__Customers__Addre__145C0A3F”冲突。冲突发生在数据库“FlowerCompany”、表“dbo.Addresses”、列“AddressID”中 Msg 547,16级,状态0,程序插入命令,第178行 INSERT语句与外键约束“FK

我正在使用SQL Server Management Studio 2014,我正在编写一个存储过程,以插入到许多带有外键的表中

我有两个错误:

Msg 547,16级,状态0,程序插入命令,第163行
INSERT语句与外键约束“FK__Customers__Addre__145C0A3F”冲突。冲突发生在数据库“FlowerCompany”、表“dbo.Addresses”、列“AddressID”中

Msg 547,16级,状态0,程序插入命令,第178行
INSERT语句与外键约束“FK__订单_客户_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'

虽然我已经阅读了错误,但我不知道如何修复它们,也不知道它们为什么存在。

您正在使用
IDENTITY\u INSERT
并为PhoneId和AddressId插入您自己的值
SCOPE_IDENTITY()
始终是插入到标识列中的最后一个值,因此插入到phone后,它将返回PhoneId,而不会添加

选项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()

您正在使用
IDENTITY\u INSERT
并为PhoneId和AddressId插入您自己的值
SCOPE_IDENTITY()
始终是插入到标识列中的最后一个值,因此插入到phone后,它将返回PhoneId,而不会添加

选项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()

我将事情更改为选项2,并且得到了相同的错误删除所有
select max+1
part totaly在每个变量中填充SCOPE\u IDENTITY值,正好在相应的insert语句之后。就像@Jason用
地址
的例子演示的那样。我将事情更改为选项2,并且我得到了相同的错误删除所有
选择max+1
部分总计在每个变量中填充SCOPE\u IDENTITY值,正好在适当的insert语句之后。就像@Jason在
地址的例子中演示的那样。所以您的表已经在标识列上有了PK,但您可能不相信愚蠢的服务器会完成这项工作,而自己完成所有工作?像硬方法一样?你能显示外键的脚本吗?所以你的表已经在标识列上有了PK,但你可能不相信这项工作是愚蠢的服务器完成的,所有的工作都是你自己完成的?喜欢硬方法吗?你能展示外键的脚本吗?