使用自动生成的列填充另一列

时间:2013-02-11 02:37:58

标签: sql sql-server tsql

如何在INSERT语句中使用自动生成的列填充其他列?

长话短说:我们正在重复使用数据库表和相关的ASP页面来显示与最初预期完全不同的数据。

我有一个类似于以下结构的表。它的结构不受我的控制。

ID       int          NON-NULL, IDENTITY(1,1)
OrderNo  varchar(50)  NON-NULL, UNIQUE
More     ...

该表已重新定位,我们未使用OrderNo列。但是,它是NON-NULLUNIQUE。作为虚拟数据,我想用行的ID列填充它。

到目前为止,我有以下SQL,但无法解决如何使用行生成的ID

INSERT INTO MyTable (OrderNo, More)
OUTPUT INSERTED.ID
VALUES (CAST(ID AS varchar(50)))

这只是给出了:

  

Msg 207,Level 16,State 1,Line 3
  列名称“ID”无效。

3 个答案:

答案 0 :(得分:1)

鉴于此表:

CREATE TABLE dbo.Example
(
    ID          integer     NOT NULL IDENTITY(1,1),
    OrderNo     varchar(50) NOT NULL,
    More        varchar(50) NULL
);

单行INSERT

如果忽略INSERTs列的所有 OrderNo单行,则可以使用DEFAULT约束:

ALTER TABLE dbo.Example
ADD DEFAULT CONVERT(varchar(50), IDENT_CURRENT('dbo.Example')) 
FOR OrderNo;

示例(仅限单行插入):

INSERT dbo.Example (More) VALUES ('More');
INSERT dbo.Example (More) VALUES ('More');

之后的表格内容:

Output

多行INSERT

在这种情况下,可以使用AFTER触发器,但另一个选项是INSTEAD OF触发器执行单个INSERT(无辅助UPDATE):

CREATE TRIGGER trg ON dbo.Example
INSTEAD OF INSERT
AS
BEGIN
    INSERT dbo.Example (OrderNo, More)
    SELECT
        CONVERT(varchar(50),
            CONVERT(bigint, IDENT_CURRENT('dbo.Example')) + 
            ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) +
            CASE 
                WHEN IDENT_CURRENT('dbo.Example') = IDENT_SEED('dbo.Example')
                THEN CONVERT(bigint, -1)
                ELSE CONVERT(bigint, 0)
            END),
        More
    FROM INSERTED;
END;

现在可以成功处理多行INSERT

INSERT dbo.Example (More) 
VALUES ('More 1'), ('More 2'), ('More 3');

表格内容:

Output 2

此方法的缺点是,如果表架构发生更改,则需要维护。

答案 1 :(得分:0)

一种选择是:

create trigger YourTable_Trigger
on YourTable
INSTEAD OF INSERT
as begin

   INSERT INTO YourTable (OrderNo, AnotherField)
   SELECT 0, AnotherField FROM Inserted

   UPDATE YourTable SET OrderNo = SCOPE_IDENTITY() WHERE ID = SCOPE_IDENTITY()
end;

这是Fiddle

祝你好运。

答案 2 :(得分:0)

这是使用OUTPUT子句的解决方案。不幸的是,你无法在一个声明中完成它。

CREATE TABLE Orders (
   ID      int         not null identity(1,1),
   OrderNo varchar(50) not null unique
)

CREATE TABLE #NewIDs ( ID int )

INSERT Orders (OrderNo)
   OUTPUT INSERTED.ID INTO #NewIDs
SELECT 12345

UPDATE o
   SET o.OrderNo = i.ID
FROM Orders o
JOIN #NewIDs i
   ON i.ID = o.ID

SELECT * FROM Orders