我正在尝试使用一次性脚本针对SQL Server数据库运行。
我想将一列(columnA)的值设置为基于另一个表(columnB)中的列的值,我要更新的每个项目都具有一个外键-我已经做到了。我最后要做的是,对于成功更新的每个项目,我想根据已更新项目的值在另一个表(本质上是审计表)中创建一行。
所以我的更新sql看起来像这样
UPDATE [mainTable]
SET [mainTable].[columnA]=[otherTable].[columnB]
FROM [mainTable]
INNER JOIN [otherTable]
ON [mainTable].[foreignKey]=ad.[primaryKey]
Where [mainTable].[columnA]<>[otherTable].[columnB]
那很好。
我还有一个单独的INSERT into语句,看起来像这样
INSERT INTO [auditTable] (
{various columnnames])
SELECT (
{some similar column names and also some different ones})
FROM [mainTable]
WHERE [mainTable].[columnA]=1
现在,如果我在第一个insert语句之后运行它,它将在审计表中为主表中columnA值为1的每一行创建一行。这不是我想要的。
如果在已运行的update命令中更新了一行,我只想在auditTable中插入新行。是否可以基于INNER JOIN在一条命令中同时执行UPDATE和INSERT INTO?
谢谢
PS。如您所知,我对SQL并不十分熟悉,我已经花了一个小时在google上搜索有关此方面的信息,却找不到任何东西
答案 0 :(得分:2)
我将在更新之前填充审核表,以便可以使用与更新时相同的条件来填充审核。您可以将这两个操作包装在事务中以确保它们同时发生。例如
BEGIN TRAN UpdateAndRecord
INSERT INTO AuditTable
column1
,column2
)
(Select Column1
,Column2
FROM [mainTable]
INNER JOIN [otherTable]
ON [mainTable].[foreignKey]=ad.[primaryKey]
Where [mainTable].[columnA]<>[otherTable].[columnB]
)
UPDATE [mainTable]
SET [mainTable].[columnA]=[otherTable].[columnB]
FROM [mainTable]
INNER JOIN [otherTable]
ON [mainTable].[foreignKey]=ad.[primaryKey]
Where [mainTable].[columnA]<>[otherTable].[columnB]
COMMIT TRAN UpdateAndRecord
答案 1 :(得分:2)
您可以在此处使用OUTPUT
子句
UPDATE [mainTable]
SET [mainTable].[columnA]=[otherTable].[columnB]
OUTPUT inserted.columnA, deleted.columnA
INTO AuditTable(InsertedId,DeletedId)
FROM [mainTable]
INNER JOIN [otherTable]
ON [mainTable].[foreignKey]=ad.[primaryKey]
WHERE [mainTable].[columnA]<>[otherTable].[columnB]
进一步Read
如果要插入其他数据,例如[otherTable]。[somevalue],则可以将MERGE
与OUTPUT
子句一起使用
MERGE INTO Target AS T
USING Source s ON t.Id=s.Id
WHEN MATCHED THEN
UPDATE
SET t.co1=s.col1
OUTPUT s.Id,DELETED.Id,INSERTED.ID INTO AuditTable(EntityId,OldId,NewId);
答案 2 :(得分:0)
我觉得您应该使用TRIGGER AFTER UPDATE,您可以检查它的工作方式: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017
基本上,您必须在要插入表的地方创建一个触发器,该触发器将在每次插入后执行。
希望它会带领您前进:)