如何在INSERT
语句中使用自动生成的列填充其他列?
长话短说:我们正在重复使用数据库表和相关的ASP页面来显示与最初预期完全不同的数据。
我有一个类似于以下结构的表。它的结构不受我的控制。
ID int NON-NULL, IDENTITY(1,1)
OrderNo varchar(50) NON-NULL, UNIQUE
More ...
该表已重新定位,我们未使用OrderNo
列。但是,它是NON-NULL
和UNIQUE
。作为虚拟数据,我想用行的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”无效。
答案 0 :(得分:1)
鉴于此表:
CREATE TABLE dbo.Example
(
ID integer NOT NULL IDENTITY(1,1),
OrderNo varchar(50) NOT NULL,
More varchar(50) NULL
);
如果忽略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');
之后的表格内容:
在这种情况下,可以使用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');
表格内容:
此方法的缺点是,如果表架构发生更改,则需要维护。
答案 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