经过几天的互联网搜索并试图改善这一点后,我终于决定寻求帮助。
我每天从一个包含大约110万行数据的客户端收到一个平面文件。我将此数据导入带有SSIS的临时数据库(SQL Server 2012)。这只需几秒钟。数据基本上是预约信息。
平面文件中有几个字段,但我必须使用它来同步报告表:
UpdateType - 包含INSERT,UPDATE或DELETE ChangeDate - 行更改时的日期时间戳 UniqueKey - UniqueKey + ChangeDate为行
创建唯一键来自客户端的要求是我按照ChangeKate by UniqueKey的顺序INSERT,UPDATE或DELETE报告数据库中的行。我无法弄清楚如何在一个集合中做到这一点,所以我创建了一个while循环,运行时间超过20小时太长了。
以下是我收到的平面文件数据示例:
UpdateType UniqueKey ChangeDate MoreDate INSERT 27244595 2013-09-24 08:51:48.367 synchronize data follows DELETE 27244595 2013-09-25 10:15:08.433 synchronize data follows INSERT 27244595 2013-09-25 10:15:09.990 synchronize data follows DELETE 27244595 2013-09-25 15:02:36.287 synchronize data follows INSERT 27244595 2013-09-25 15:02:36.610 synchronize data follows
正如您所看到的那样,插入了相同的记录然后删除了多次,但情况并非总是如此。在此示例数据中,只有最后一条记录应出现在报告数据库表中,预定了1个约会。
以下是来自同一平面文件的另一个示例:
UpdateType UniqueKey ChangeDate MoreDate INSERT 28243572 2013-09-25 10:15:08.610 synchronize data follows INSERT 28243572 2013-09-25 10:15:09.880 synchronize data follows DELETE 28243572 2013-09-25 14:01:36.210 synchronize data follows INSERT 28243572 2013-09-25 14:02:37.287 synchronize data follows
在此示例中,第一个和最后一个记录应出现在报告数据库表中。预约有2个约会。还有其他时候混合更新。
我不会创建报告,也不知道它们是什么样的。
这是我编写的用于从登台数据库同步报告数据库的代码。如果您对如何改进此流程有任何建议,我欢迎他们并感谢您的帮助。
DECLARE --DECLARE SOME VARIABLES TO USE IN THE LOOP
@UPDATETYPE VARCHAR(6) --THIS WILL BE INSERT, DELETE OR UPDATE
,@KEY INTEGER --THIS IS THE UNIQUEKEY
,@CHANGEDATE DATETIME --THIS IS THE CHANGE DATE FROM THE FLATFILE
--START A WHILE LOOP TO GO ROW BY ROW
WHILE (SELECT COUNT(*) FROM STAGEDB.DBO.APPIONTMENTCHANGE) > 0
BEGIN
SELECT @UPDATETYPE = (SELECT TOP 1 [UPDATETYPE] FROM STAGEDB.DBO.APPIONTMENTCHANGE
ORDER BY [UNIQUEKEY], [CHANGEDATE]) --GET THE UPDATE TYPE FOR THE IF STATEMENTS
SELECT @KEY = (SELECT TOP 1 [UNIQUEKEY] FROM STAGEDB.DBO.APPIONTMENTCHANGE
ORDER BY [UNIQUEKEY], [CHANGEDATE]) --GET THE KEY
SELECT @CHANGEDATE = (SELECT TOP 1 [CHANGEDATE] FROM STAGEDB.DBO.APPIONTMENTCHANGE
ORDER BY [UNIQUEKEY], [CHANGEDATE]) --GET THE CHANGEDATE
--IF THIS ROW IS AN INSERT THEN COMPLETE THIS ON THE REPORT DATABASE
IF @UPDATETYPE = 'INSERT'
BEGIN
INSERT INTO [REPORTDB].[DBO].[APPOINTMENT]
([REPORTDB].[DBO].[APPOINTMENT].[UNIQUEKEY]
,[REPORTDB].[DBO].[APPOINTMENT].[APPOINTMENT]
,[REPORTDB].[DBO].[APPOINTMENT].[CLIENTLEADBK]
,[REPORTDB].[DBO].[APPOINTMENT].[FIRSTNAME]
,[REPORTDB].[DBO].[APPOINTMENT].[LASTNAME]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER2]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER3]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER4]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSSTREET]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSCITY]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSSTATE]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSZIP]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSCOUNTRY])
SELECT TOP 1 [UNIQUEKEY]
,[APPOINTMENT]
,[CLIENTLEADBK]
,[FIRSTNAME]
,[LASTNAME]
,[PHONENUMBER]
,[PHONENUMBER2]
,[PHONENUMBER3]
,[PHONENUMBER4]
,[ADDRESSSTREET]
,[ADDRESSCITY]
,[ADDRESSSTATE]
,[ADDRESSZIP]
,[ADDRESSCOUNTRY]
FROM [STAGEDB].[DBO].[APPIONTMENTCHANGE]
ORDER BY [UNIQUEKEY], [CHANGEDATE];
--ONCE THE INSERT IS COMPLETED THEN DELETE THE ALREADY WORKED RECORD FROM THE STAGING DATABASE
DELETE FROM [STAGEDB].[DBO].[APPIONTMENTCHANGE]
WHERE [UNIQUEKEY] = @KEY AND [CHANGEDATE] = @CHANGEDATE;
END
--IF THE ROW IS A DELETE REQUEST THEN COMPLETE THIS ON THE REPORT DATABASE
IF @UPDATETYPE = 'DELETE'
BEGIN
DELETE FROM [REPORTDB].[DBO].[APPOINTMENT]
WHERE [UNIQUEKEY] = @KEY AND [CHANGEDATE] = @CHANGEDATE;
--ONCE THE DELETE IS COMPLETED THEN DELETE THE ALREADY WORKED RECORD FROM THE STAGING DATABASE
DELETE FROM [STAGEDB].[DBO].[APPIONTMENTCHANGE]
WHERE [UNIQUEKEY] = @KEY AND [CHANGEDATE] = @CHANGEDATE;
END
--IF THE ROW IS A UPDATE REQUEST DO THAT
IF @UPDATETYPE = 'UPDATE'
BEGIN
UPDATE [REPORTDB].[DBO].[APPOINTMENT]
SET [REPORTDB].[DBO].[APPOINTMENT].[APPOINTMENT] = B.[APPOINTMENT]
,[REPORTDB].[DBO].[APPOINTMENT].[CLIENTLEADBK] = B.[CLIENTLEADBK]
,[REPORTDB].[DBO].[APPOINTMENT].[FIRSTNAME] = B.[FIRSTNAME]
,[REPORTDB].[DBO].[APPOINTMENT].[LASTNAME] = B.[LASTNAME]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER] = B.[PHONENUMBER]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER2] = B.[PHONENUMBER2]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER3] = B.[PHONENUMBER3]
,[REPORTDB].[DBO].[APPOINTMENT].[PHONENUMBER4] = B.[PHONENUMBER4]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSSTREET] = B.[ADDRESSSTREET]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSCITY] = B.[ADDRESSCITY]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSSTATE] = B.[ADDRESSSTATE]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSZIP] = B.[ADDRESSZIP]
,[REPORTDB].[DBO].[APPOINTMENT].[ADDRESSCOUNTRY] = B.[ADDRESSCOUNTRY]
FROM [REPORTDB].[DBO].[APPOINTMENT]
INNER JOIN [STAGEDB].[DBO].[APPIONTMENTCHANGE] B
ON [REPORTDB].[DBO].[APPOINTMENT].[UNIQUEKEY] = B.[UNIQUEKEY]
WHERE [REPORTDB].[DBO].[APPOINTMENT].[UNIQUEKEY] = @KEY;
--ONCE THE UPDATE IS COMPLETED THEN DELETE THE ALREADY WORKED RECORD FROM THE STAGING DATABASE
DELETE FROM [STAGEDB].[DBO].[APPIONTMENTCHANGE]
WHERE [UNIQUEKEY] = @KEY AND [CHANGEDATE] = @CHANGEDATE;
END
END
我宁愿拥有所有需要插入的文件,所有这些都需要删除,所有这些都应该更新,而不是每次发生的记录更改,但这是我现在必须处理的。
赞赏所有改进的重要想法。请提供尽可能多的解释。
答案 0 :(得分:0)
使用普通的sql命令。首先是插入
insert into realtable
(field1, field2, etc)
select field1, field2, etc
from stagingtable
where idfield in
(select idfield
from stagingtable
except
select idfield
from realtable)
更新
update r
set field1 = s.field1
, etc
from realtable r join stagingtable s on something
where whatever
缺失
delete from reatable
where idfield in
(select idfield
from staging table
where you want the record deleted from the real table)