将ID插入INSERT INTO ... OUTPUT ... INTO临时表上的临时表变量中

时间:2018-12-13 07:56:44

标签: sql-server insert-into

这是我正在使用的示例过程。

create procedure PRO_ProcName
    @description varchar(max), 
    @txn_no varchar
as
begin
    declare @txn table (
        id bigint,
        description varchar(max),
        txn_no varchar
    );

    declare @txn_id bigint;

    insert into transactions    
    (
        description,
        txn_no
    )
    output
        inserted.description,
        inserted.txn_no
    into @txn
    values
    (
        @description,
        @txn_no
    )

    select @txn_id = id from @txn;
end

我遇到类似以下错误:

Column name or number of supplied values does not match table definition.

我知道这是因为我的临时表中有id字段,并且没有将其插入insert into语句中。我不能给id赋值,因为它是自动递增主键。

我该如何解决这种情况并将id插入的记录获取到变量中?

2 个答案:

答案 0 :(得分:2)

inserted表表示插入后目标表中存在的数据-因此它还包括自动生成的值,无论这些值是由默认值定义生成还是由列上的标识定义生成-因此您需要在inserted.id子句中添加output

但是,您的过程中还有另外两个错误。
首先也是最重要的一点是,您没有为@txn_no varchar参数指定长度。在这种情况下,SQL Server将隐式指定1个字符的长度。
第二个事实是您没有在@txn子句中指定output的列列表。

这是您代码的改进版本,已修复所有这些问题:

create procedure PRO_ProcName
    @description varchar(max), 
    @txn_no varchar(255) -- Note: I don't know the actual length you need
as
begin
    declare @txn table (
        id bigint,
        description varchar(max),
        txn_no varchar
    );

    declare @txn_id bigint;

    insert into transactions    
    (
        description,
        txn_no
    )
    output
        inserted.id,
        inserted.description,
        inserted.txn_no
    into @txn(id, description, txn_no)
    values
    (
        @description,
        @txn_no
    )

    select @txn_id = id from @txn;
end

答案 1 :(得分:1)

  

我不能给id赋值,因为它是自动增量主键。

不,不是。您尚未声明它是任何东西。因此,我们需要首先解决该问题:

cross apply

然后我们通过在values()子句中指定列列表来解决此问题:

declare @txn table (
    id bigint IDENTITY PRIMARY KEY,
    description varchar(max),
    txn_no varchar
);

无论如何,指定列列表始终是一个好习惯。

或者,如果我对您的问题有误解,且ID应该来自INTO,则只需将output inserted.description, inserted.txn_no into @txn (description, txn_no) 添加为transactions子句中的另一列。 inserted.id表示插入后表的状态。因此,即使您没有在OUTPUT中指定列,也可以将其列包含在inserted子句中。