Sql 对于每个更新,在别处插入存储过程

Sql 对于每个更新,在别处插入存储过程,sql,sql-server,tsql,stored-procedures,foreach,Sql,Sql Server,Tsql,Stored Procedures,Foreach,这种情况可能只有通过循环才能实现,但谁知道呢 我在一个使用MS SQL Server的Java编码环境中,我一直在四处搜索,似乎找不到在事务历史表中插入记录的好方法,在发出更新多条记录的单个更新命令后,我们必须对其他表中的每个操作进行更新。对于更新的每个更新记录,我也要执行一个insert语句,本质上这是我们目前在不使用存储过程的代码中逐个执行的操作: UPDATE table SET column1=null, column2=null, column3=0, column4=getDate(

这种情况可能只有通过循环才能实现,但谁知道呢

我在一个使用MS SQL Server的Java编码环境中,我一直在四处搜索,似乎找不到在事务历史表中插入记录的好方法,在发出更新多条记录的单个更新命令后,我们必须对其他表中的每个操作进行更新。对于更新的每个更新记录,我也要执行一个insert语句,本质上这是我们目前在不使用存储过程的代码中逐个执行的操作:

UPDATE table SET column1=null, column2=null, column3=0, column4=getDate() where column5=? and column6=1
...
//Insert transtable
createTransaction(tran, localConn);
...
INSERT INTO transtable ( a, b, c, d, e, f, g, h, i, " +
                 "j, k, l, m, n, o, p, q, r, s, " +
                 "t, u, v, w) " +
                 " VALUES ( ? ,? ,? ,? ,? ,? ,getDate() ,getDate() ,getDate() ,? ,? ,? ,? ,? ,? ,? ,getDate() ,getDate(),? ,? ,? ,?,? )
我想做的是,在更新时做如下操作:

USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[setFlags]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

UPDATE table1
SET column1 = '2', column2 = NULL
WHERE column1 = '1' or column1 = '2'
--FOR EACH UPDATED ROW IN THIS TABLE, CREATE A TRANSACTION IN TRANSTABLE

UPDATE table2
SET column1 = '0', column2 = NULL
WHERE column1 = '1'
--FOR EACH UPDATED ROW IN THIS TABLE, CREATE A TRANSACTION IN TRANSTABLE

UPDATE table3
SET column1 = '0', column2 = NULL
WHERE column1 = '1'
--FOR EACH UPDATED ROW IN THIS TABLE, CREATE A TRANSACTION IN TRANSTABLE

END
但是,对于每个更新的记录(通常使用此实用程序更新大约100条记录),也需要在transtable表中执行大约100次插入,该表还将包含来自被更新行的一些数据

有人有什么想法吗?资源在那里?等我是个初学者,所以有时候我不知道该找什么。最近我一直在搜索“为每个更新插入SQL”或“为每个更新循环插入”

我可能需要使用TSQL,但如果有更好的方法(听起来效率也非常低),最好知道:

您不知道您使用的是哪个版本的SQL Server,也不知道您使用的是哪个版本。如果您使用的是2008企业版,请查看。有一篇很好的介绍文章。

对于您的情况,最好的解决方案可能是使用触发器,正如定义的那样:“触发器是一种特殊的存储过程,当数据库服务器中发生事件时自动执行。”

下面的脚本在tempdb上创建了两个表:
mydatanow
mydatalog
。每次在
mydatanow
中插入或更新一行时,触发器
makelog
都会运行,其实现会将插入
mydatanow
的所有行复制到
mydatalog
——如果一条update语句影响到多行,则复制所有行

USE tempdb;
GO
CREATE TABLE mydatanow (id SMALLINT, c1 VARCHAR(10), c2 VARCHAR(10));
CREATE TABLE mydatalog (id SMALLINT, c1 VARCHAR(10), c2 VARCHAR(10), moment DATETIME);
GO
CREATE TRIGGER makelog ON mydatanow
AFTER INSERT, UPDATE
AS BEGIN
    INSERT mydatalog(id, c1, c2, moment)
    SELECT id, c1, c2, GETDATE()
    FROM inserted
END
GO
INSERT mydatanow VALUES (1, 'abe', 'apple');
INSERT mydatanow VALUES (2, 'beth', 'banana');
UPDATE mydatanow SET c1 = 'carl', c2 = 'no fruit';
GO
SELECT * FROM mydatanow;
-- id     c1         c2
-- ------ ---------- ----------
-- 1      carl       no fruit
-- 2      carl       no fruit

SELECT * FROM mydatalog;
-- id     c1         c2         moment
-- ------ ---------- ---------- -----------------------
-- 1      abe        apple      2012-05-10 19:36:45.843
-- 2      beth       banana     2012-05-10 19:36:45.843
-- 1      carl       no fruit   2012-05-10 19:36:45.847
-- 2      carl       no fruit   2012-05-10 19:36:45.847

你看过触发器了吗?触发器基本上是SQL代码,在表上发生填充时执行。您可以捕获正在插入/更新的行,例如,更新另一个表。我能看到的唯一问题是它是全局的,这意味着每次更新和每次插入都会触发触发器,而不仅仅是存储的触发。您可能需要查找有关SQL事务日志的信息。您的服务器可能已经存储了您要查找的所有内容。我从来没听说过“偷窥触发器”,我来看看。每次更新和每次插入触发器都可能是一个问题,但我仍会研究它。亲爱的,我会尝试一下。还有,是的,我不知道这个版本与本案有关,或者我会提供它。我也在考虑把表作为一个变量放在一边,这样做,做我的更新,保留变量,用我检索到的数据创建一个事务。另外,我会给你打电话,但我还不到15次!终于有时间来批评你了;)