INSERT使用由单独脚本生成的ID与外键约束冲突

时间:2018-06-06 14:57:15

标签: sql sql-server

所以我一直得到这个错误(表名改变了):

  

INSERT语句与FOREIGN KEY约束“FK__SubTable__Table__xxxxxxxx”冲突。冲突发生在数据库“Development”,表“dbo.Table”,列'TableID'。

基本上从这个脚本(被称为过程)

begin

    begin transaction

    begin try

        declare @TableID int

        exec @TableID = createParent    @params... = [params...]


        insert into [dbo].[SubTable]
            (
            [TableID]
            ,[other fields...]
            )
        select
            @TableID
            ,[other params..]

        select
            SCOPE_IDENTITY()    [SubTableID]
            ,@TableID           [TableID];

    end try
    begin catch
        select
            ERROR_NUMBER()
            ,ERROR_NUMBER()
            ,ERROR_SEVERITY()
            ,ERROR_STATE()
            ,ERROR_PROCEDURE()
            ,ERROR_LINE()
            ,ERROR_MESSAGE()

        select @Commit = 0;

    end catch

    if @Commit = 1
    begin
        commit transaction
    end

    if @Commit = 0
    begin
        rollback transaction
    end

end

createParent脚本的工作方式非常相似,除非它不调用任何其他脚本,只选择它自己的SCOPE_IDENTITY()

任何人都知道或了解这里的问题是什么? (或者可以建议另一种方法在另一个表中创建记录,最好使用其他存储过程并使用其ID作为外键)

编辑:

如果其他人恰好处于相同的情况,则管理以使其正常运行;将过程的结果插入表变量而不是标量变量,然后选择从中为我解决问题。

1 个答案:

答案 0 :(得分:0)

评论太长了。

虽然技术上可行,但从存储过程返回值(执行状态除外)是一个坏习惯。相反,您应该使用输出参数。

我认为代码看起来应该更像这样:

declare @TableID int;
declare @status int;

exec @status = createParent    @params... = [params...], @TableId output;

然后你会检查@status以查看它是否正确。

在您的情况下,您可能会返回错误的ID。我可能会怀疑具有下列条件之一的if会起作用:

if @TableId is not null
begin
. . .
end;

或者:

if @TableId > 0
. . .

至少,这应该有效:

if exists (select 1 from <tabletable> t where t.TableId = @tableId)
. . .