我正在编写批处理插入语句,并希望使用临时表来跟踪插入的 ID,而不是自己循环遍历项目并为每个插入的行调用 SCOPE_IDENTITY()。
需要插入的数据具有(临时)ID 将其链接到也应该插入到另一个表中的其他数据,因此我需要实际 Id 和临时 Id 的交叉引用。
这是我到目前为止所拥有的一个例子:
-- The existing table
DECLARE @MyTable TABLE (ID INT IDENTITY(1,1), [Name] NVARCHAR(MAX));
-- My data I want to insert
DECLARE @MyInsertData TABLE (ID INT, [Name] NVARCHAR(MAX));
INSERT INTO @MyInsertData ( ID,Name)
VALUES ( -1 , 'bla'),(-2,'test'),(-3,'last');
DECLARE @MyCrossRef TABLE ([NewId] INT, OldId INT);
INSERT INTO @MyTable ( [Name] )
OUTPUT Inserted.ID, INS.ID INTO @MyCrossRef
SELECT [NAME] FROM @MyInsertData INS
-- Check the result
SELECT * FROM @MyCrossRef
Run Code Online (Sandbox Code Playgroud)
问题是我无法让 OUTPUT INTO …
我正在修改数据库的结构。表FinancialInstitution的几个列的内容必须转移到表Person 中。金融机构通过外键链接到人。每个金融机构都需要其相应人员的 ID。因此,对于在 Person 中插入的每个新行,必须将该新行的 id (IDENTITY) 复制回 FinancialInstitution 的相应行中。
这样做的明显方法是迭代 T-SQL 代码。但我很想知道是否可以仅使用基于集合的操作来实现。
我想象这样一个请求的内部层次会是这样的:
INSERT INTO Person (Street1, Number1, City1, State1, PostCode1, CountryId1, WorkDirectPhone1, Fax1, Email1)
OUTPUT inserted.Id, FinancialInstitution.Id
SELECT Id, Street, Number, City, [State], PostCode, CountryId, PhoneNumber, Fax, Email
FROM FinancialInstitution;
Run Code Online (Sandbox Code Playgroud)
不幸的是,似乎 OUTPUT 不能以这种方式关联......
我想这样做:
DECLARE @Id INT;
UPDATE Logins
SET SomeField = 'some value'
OUTPUT @Id = Id
WHERE EmailAddress = @EmailAddress -- this is a parameter of the sproc
Run Code Online (Sandbox Code Playgroud)
这甚至可能吗?我知道我可以声明一个本地表变量并将输出定向到那里,但如果可能的话我宁愿跳过它
sql-server-2008 sql-server sql-server-2012 update output-clause
考虑以下最小、完整且可验证的示例代码(请参阅此处的 dbfiddle):
CREATE TABLE [dbo].[test]
(
[i] bigint NOT NULL
identity(1,1)
PRIMARY KEY CLUSTERED
, [d] varchar(10) NOT NULL
);
GO
Run Code Online (Sandbox Code Playgroud)
使用INSTEAD OF INSERT, UPDATE触发器:
CREATE TRIGGER [dbo_test_trigger]
ON [dbo].[test]
INSTEAD OF INSERT, UPDATE
AS
BEGIN
IF ROWCOUNT_BIG() = 0 RETURN;
SET NOCOUNT ON;
MERGE INTO [dbo].[test] [target]
USING [inserted] [source] ON [target].[i] = [source].[i]
WHEN NOT MATCHED THEN
INSERT
(
[d]
)
VALUES
(
[source].[d]
)
WHEN MATCHED THEN
UPDATE
SET [target].[d] = [source].[d];
END; …Run Code Online (Sandbox Code Playgroud) 我有一系列可更新的视图,我们向最终用户公开作为后端流程的界面。
其中一个视图引用了两个表,并且需要一个INSTEAD OFforUPDATE和INSERTs的触发器。
表的结构是(大大简化):
Claim
(DataRowID bigint IDENTITY PRIMARY KEY
,<bunch of claim data>)
ClaimExtended
(ClaimDataRowID bigint FOREIGN KEY references dbo.Claim(DataRowID) NOT NULL
,<bunch of other claim data>)
Run Code Online (Sandbox Code Playgroud)
我最初的计划是在触发器中这样做:
CREATE TRIGGER [dbo].[MyTrigger] ON [dbo].[MyView]
INSTEAD OF INSERT
AS
DECLARE @IDLink TABLE
(RowID int
,ClaimDataRowID bigint)
DECLARE @Inserted TABLE
(RowID int identity (1,1) NOT NULL
,<all the columns from the view>)
INSERT INTO
@Inserted
(<View columns>)
SELECT
(<View columns>)
FROM
Inserted
INSERT INTO
Claim
(<Columns>) …Run Code Online (Sandbox Code Playgroud) trigger sql-server sql-server-2008-r2 identity output-clause
我正在做这样的更新:
UPDATE dbo.Table1
SET BirthDate = b.BirthDate
FROM Table1 a
JOIN Table2 b
ON a.ID = b.ID
Run Code Online (Sandbox Code Playgroud)
我想使用 OUTPUT 子句来备份我的更改。
UPDATE dbo.Table1
SET BirthDate = b.BirthDate
OUTPUT
inserted.Id, inserted.BirthDate AS New_BirthDate,
deleted.BirthDate AS Old_BirthDate
INTO OutputTable
FROM Table1 a
JOIN Table2 b
ON a.ID = b.ID
Run Code Online (Sandbox Code Playgroud)
我想知道的是 OUTPUT 子句是否有办法创建表 OutputTable 或者我是否必须在运行语句之前确保它已经存在?
该条款中是否存在未记录的限制OUTPUT,或者这是一个错误?
给出下表:
CREATE TABLE t1 (SomeId int, flag bit, value int);
Run Code Online (Sandbox Code Playgroud)
我想在UPDATE语句中使用计算值,然后使用OUTPUT输出该值。请注意,计算值未在该部件中使用SET,这可能允许通过输出左侧列来解决问题。
以下工作正常,它是一个完美标准的可更新子查询(派生表)。
UPDATE subT1
SET flag = 1
OUTPUT inserted.SomeValue
FROM (
SELECT *,
SomeValue = t1.value + 123
FROM t1
) subT1;
Run Code Online (Sandbox Code Playgroud)
然而使用窗口函数会出现一个奇怪的错误:
UPDATE subT1
SET flag = 1
OUTPUT inserted.Sum
FROM (
SELECT *,
Sum = SUM(t1.value) OVER (PARTITION BY t1.SomeId)
FROM t1
) subT1;
Run Code Online (Sandbox Code Playgroud)
Msg 404 Level 16 State 1 Line 3
The column reference "inserted.Sum" is not …Run Code Online (Sandbox Code Playgroud) 我想在我的应用程序的“SystemSettings”表中添加一条记录,并使用 UPDATE 中的值设置 PK 值。PK 值来自“TS_LASTIDS”表,其中包含此应用程序 (MicroFocus SBM) 中每个表的最大 PK 值。我需要增加该表中的“TS_LASTID”列,并在将新记录插入“SystemSettings”表时使用新值作为 PK。
Insert Into
ts_SystemSettings ( ts_Id, ts_Name, ts_LongValue)
Values (
( -- ******************** This subquery updates the PK in TS_LASTIDS and outputs the new value
Update
ts_LastIds
Set
ts_LastId=ts_LastId+1
Output
INSERTED.ts_LastId
Where
ts_Name = 'SystemSettings'
) , -- ********************
'NSLastChangeId' ,
1 ,
) ;
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚语法。这是 MS SQL Server 2012。