Sql 如何创建只获取表中已更新数据的查询
我不知道从哪里开始,也不知道这将如何运作,我希望有人有一个想法或一个行之有效的方法 为了演示我正在尝试执行的操作,我创建了一个存储过程,通过从链接表获取记录来更新或插入本地表中的新记录。存储过程在SQL Server中作为作业运行,以更新和插入新记录 我的问题是:是否有一种方法可以查询本地表中的数据,以便最初可以获取所有记录,而不是仅获取已插入的新记录或已更新的旧记录 我不想连续获取所有记录,只想添加新记录或更新记录 这可能吗 以下是我创建的用于更新本地电话数据的存储过程:Sql 如何创建只获取表中已更新数据的查询,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我不知道从哪里开始,也不知道这将如何运作,我希望有人有一个想法或一个行之有效的方法 为了演示我正在尝试执行的操作,我创建了一个存储过程,通过从链接表获取记录来更新或插入本地表中的新记录。存储过程在SQL Server中作为作业运行,以更新和插入新记录 我的问题是:是否有一种方法可以查询本地表中的数据,以便最初可以获取所有记录,而不是仅获取已插入的新记录或已更新的旧记录 我不想连续获取所有记录,只想添加新记录或更新记录 这可能吗 以下是我创建的用于更新本地电话数据的存储过程: CREATE PRO
CREATE PROCEDURE sp_UPDATE_PHONE_RECORDS
AS
BEGIN
MERGE dbo.PHONE_REC AS Target
USING (SELECT MEMBER_ID
,HOME_PHONE = dbo.udf_StdPhoneFmt(HOME)
,CELL_PHONE = dbo.udf_StdPhoneFmt(CELL)
,WORK_PHONE = dbo.udf_StdPhoneFmt(WORK)
FROM PHONE WHERE MEMBER_ID IS NOT NULL) AS SOURCE
ON (Target.MEMBER_ID = SOURCE.MEMBER_ID)
WHEN MATCHED THEN
UPDATE SET Target.HOME_PHONE = Source.HOME_PHONE,Target.CELL_PHONE = Source.CELL_PHONE,
Target.WORK_PHONE = Source.WORK_PHONE
WHEN NOT MATCHED BY TARGET THEN
INSERT (MEMBER_ID, HOME_PHONE, CELL_PHONE ,WORK_PHONE)
VALUES (Source.MEMBER_ID, Source.HOME_PHONE, Source.CELL_PHONE, Source.WORK_PHONE);
END
GO
这可能吗
谢谢大家 我们通常会在源表中添加两个日期/时间字段,如source.LastModifiedOn和source.CreatedOn 然后,当作业运行以更新目标表时,您可以说get me all Source.LastModifiedOn和Source.CreatedOn行(自上次作业运行以来),并基于这些行执行更新/插入 当然,您需要确保Source.LastModifiedOn和Source.CreatedOn设置正确。我将与
$action
列一起使用:
DECLARE @Target TABLE
(
Id INT NOT NULL,
Value VARCHAR(10) NULL
);
INSERT @Target
VALUES (1, 'A'), (2, NULL), (3, NULL);
DECLARE @Source TABLE
(
Id INT NOT NULL,
Value VARCHAR(10) NULL
);
INSERT @Source
VALUES (2, 'B'), (4, 'D'), (5, 'E');
DECLARE @AffectedRows TABLE
(
MergeAction NVARCHAR(10) NOT NULL,
Old_Id INT NULL,
Old_Value VARCHAR(10) NULL,
New_Id INT NULL,
New_Value VARCHAR(10) NULL
);
MERGE @Target t
USING @Source s ON t.Id = s.Id
WHEN MATCHED THEN
UPDATE SET Value = s.Value
WHEN NOT MATCHED THEN
INSERT (Id, Value) VALUES (s.Id, s.Value)
OUTPUT $action, deleted.Id, deleted.Value, inserted.Id, inserted.Value
INTO @AffectedRows(MergeAction, Old_Id, Old_Value, New_Id, New_Value);
SELECT * FROM @Target;
SELECT * FROM @AffectedRows;
结果:
Id Value
-- -----
1 A
2 B <-- updated row
3 NULL
4 D <-- inserted row
5 E <-- inserted row
MergeAction Old_Id Old_Value New_Id New_Value
----------- ----------- ---------- ----------- ---------
INSERT NULL NULL 4 D
INSERT NULL NULL 5 E
UPDATE 2 NULL 2 B
Id值
-- -----
1A
2 B您可以在本地表上写入触发器,当对其进行更新或插入时,将触发该触发器。作为触发器逻辑的一部分,您必须将更新或新插入的记录插入到临时表中。这是记录对本地表所做更改的最简单方法 这基本上是的一种变体,但当我不关心创建记录的实际日期/时间时,我有时会使用另一种方法:
我只需添加一个名为modified
的bit
字段,默认值为1。
如果在表中插入新行,modified
将自动设置为1。
如果更新现有行,我必须确保modified
也设置为1
这样,作业只需搜索modified=1
的所有行
无需跟踪上次执行作业的日期/时间
当作业成功执行时,它所做的最后一件事是“重置”所有行中的modified
字段:
update TheTable set modified = 0
在我看来,如果只关心自上次作业运行以来对行进行了修改,而不关心对行进行了修改,那么这种方法的工作量就会减少
但它与RDotLee的“LastModifiedOn/CreatedOn”方法具有相同的缺点-您需要确保表上的每次更新都将modified
列设置为1,因此您只能在控制写入表的所有代码时使用它。时间戳
时间戳在和插入或更新时递增
在主机上使其成为时间戳,在从机上使其成为二进制(8)
我觉得这是一个合适的工具。我将使用你的例子并反馈反馈,不想将其标记为答案,以防我有其他问题。但感谢您花时间回答。:)@如果你有问题,请随时提问。如果我知道答案,我会帮助你。这是一个有趣的方法。:)再次感谢!好吧,我找到了一个有效的解决方案,不确定它是否是最好的,它是这里发布的想法的组合。我所做的是在本地表上创建一个时间戳列。这会在每次更新记录或插入新记录时向记录(行)添加SMALLDATETIME。现在,我可以根据在过去24小时内更新或插入的记录,或者使用时间戳查询本地表。我怎样才能把代码发回到这里?@unserageguy你是说时间戳吗?这不是一个很短的时间。我在3小时前发布了答案。不,我在本地表上创建了一列,并将该列命名为TIME_STAMP,数据类型为smalldatetime。我现在需要知道的是,如何使用TIME\u STAMP列中的datetime查询本地表,以获得在此时间和该时间之间插入或更新的所有记录。这与我发布的查询类似。但您应该真正了解时间戳,因为它在插入和更新时自动递增。SmallDateTime只适用于分钟,因此如果同步,那么在同一分钟内更新,则不会重新同步。我非常感谢您的帮助。在您看来,使用实际日期对我来说比使用时间戳更好,因为该表将从链接表每天更新一到两次。我现在需要做的就是创建一个查询,该查询显示:从本地表中获取所有日期,该表是在这个时间和那个时间之间创建的,或者是在昨天和今天之间创建的。
select [timeStampSlave].*
from [timeStampSlave]
join [timeStampMaster]
on [timeStampSlave].[ID] = [timeStampMaster].ID
and [timeStampSlave].[timeStamp] < [timeStampMaster].[timestamp]
[MasterSever].[test].[dbo].[timeStampMaster]