我有一种情况,我必须在ERP的表格中插入/更新大量信息。我首先要检查表是否存在信息,如果不存在,则插入,如果存在,则更新。
我有以下示例代码。
IF NOT EXISTS(SELECT * FROM EXT00101 WHERE PT_Window_ID='ITEM_SHIP_MAINT' and PT_UD_Key='18 RND PA' and PT_UD_Number=5)
BEGIN
INSERT INTO EXT00101 VALUES('ITEM_SHIP_MAINT', '18 RND PA', 5, '70')
End
IF EXISTS(SELECT * FROM EXT00101 WHERE PT_Window_ID='ITEM_SHIP_MAINT' and PT_UD_Key='18 RND PA' and PT_UD_Number=5)
BEGIN
UPDATE EXT00101
SET STRGA255='70'
WHERE PT_Window_ID='ITEM_SHIP_MAINT' and PT_UD_Key='18 RND PA' and PT_UD_Number=5;
END
我对一个有23,000多行的excel文件使用邮件合并。这导致我的SQL语句为260,000多行。必须有一种更有效的方法来完成它。
如果没有,我将不得不大打破这段代码。
Microsoft SQL Server 2005
答案 0 :(得分:0)
为了使用SSIS让您使用正确的轨道,第一步是使用执行SQL任务来创建临时表:
IF (OBJECT_ID(N'dbo.tmpEXT00101Staging') IS NOT NULL
DROP TABLE dbo.tmpEXT00101Staging;
CREATE TABLE dbo.tmpEXT00101Staging
( PT_Window_ID VARCHAR(50) NOT NULL,
PT_UD_Key VARCHAR(50) NOT NULL,
PT_UD_Number INT NOT NULL,
STRGA255 VARCHAR(50) NOT NULL
);
然后使用数据流任务将数据导入此表(平面文件或Excel源,目标将是OLE DB目标。您可能需要将数据流任务上的“延迟验证”设置为false和/或者在目标上“验证外部元数据”为false,因为目标是在运行时创建的)。您也可以将临时表永久保存在那里,而只需在每次执行开始时使用TRUNCATE TABLE dbo.tmpEXT00101Staging
清除它。
最后使用此临时表更新主表(如果您不想永久保留,则删除临时表以进行清理)
BEGIN TRAN;
-- UPDATE ROWS THAT EXIST
UPDATE t
SET STRGA255 = st.STRGA255
FROM dbo.EXT00101 t
INNER JOIN dbo.tmpEXT00101Staging st
ON st.PT_Window_ID = T.PT_Window_ID
AND st.PT_UD_Key = t.PT_UD_Key
AND st.PT_UD_Number = t.PT_UD_Number;
-- INSERT ROWS THAT DO NOT EXIST
INSERT EXT00101 (PT_Window_ID, PT_UD_Key, PT_UD_Number, STRGA255)
SELECT PT_Window_ID, PT_UD_Key, PT_UD_Number, STRGA255
FROM dbo.tmpEXT00101Staging st
WHERE NOT EXISTS
( SELECT 1
FROM dbo.EXT00101 t
WHERE st.PT_Window_ID = T.PT_Window_ID
AND st.PT_UD_Key = t.PT_UD_Key
AND st.PT_UD_Number = t.PT_UD_Number
);
COMMIT TRAN;
-- CLEAN UP AND DROP STAGING TABLE (OPTIONAL)
IF (OBJECT_ID(N'dbo.tmpEXT00101Staging') IS NOT NULL
DROP TABLE dbo.tmpEXT00101Staging;
这里有可能遇到竞争条件,所以你应该确保你有一些约束来阻止试图插入同一记录的并发线程的任何完整性违规。
为了完整起见,执行UPSERT的首选方案是MERGE(如果您从2005年的任何时候升级):
MERGE dbo.EXT00101 WITH (HOLDLOCK) AS t
USING dbo.tmpEXT00101Staging AS st
ON st.PT_Window_ID = T.PT_Window_ID
AND st.PT_UD_Key = t.PT_UD_Key
AND st.PT_UD_Number = t.PT_UD_Number
WHEN MATCHED THEN
UPDATE
SET STRGA255 = st.STRGA255
WHEN NOT MATCHED THEN
INSERT (PT_Window_ID, PT_UD_Key, PT_UD_Number, STRGA255)
VALUES (st.PT_Window_ID, st.PT_UD_Key, st.PT_UD_Number, st.STRGA255);