我的存储过程如下:
--Stored procedure to update data in Data_Archive.dbo.company
CREATE PROC dbo.TransferCompanyInfo
as
BEGIN TRAN
INSERT INTO Data_Archive.dbo.Company
Select
CompanyID,
CompanyName,
Address1,
Address2,
Address3,
Address4,
ZipCode,
FROM OLD.dbo.company
where not exists (select Data_Archive.dbo.Company.CompanyID from Data_Archive.dbo.Company
WHERE CompanyID = OLD.dbo.Company.CompanyID)
Update Data_Archive.dbo.Company
Set
Data_Archive.dbo.Company.CompanyID = b.CompanyID,
Data_Archive.dbo.Company.CompanyName = b.CompanyName,
Data_Archive.dbo.Company.Address1 = b.Address1,
Data_Archive.dbo.Company.Address2 = b.Address2,
Data_Archive.dbo.Company.Address3 = b.Address3,
Data_Archive.dbo.Company.Address4 = b.Address4,
Data_Archive.dbo.Company.ZipCode = b.ZipCode,
From Data_Archive.dbo.Company a, OLD.dbo.Company b
Where a.CompanyID = b.CompanyID
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR ('Error occured while copying data to TachographData_Archive.dbo.company', 16, 1)
RETURN -1
END
IF @@TRANCOUNT > 0
BEGIN
COMMIT TRAN
RETURN 0
END
但是我想知道如何让它更快,因为目前它必须扫描表以查看是否不存在,然后插入,然后再次扫描并更新。我想如果相反我做了如果存在更新其他插入它会使它更快但我不知道如何重新格式化它。目前我尝试了下面的代码但是没有工作:
- 更新Data_Archive.dbo.company中的数据的存储过程
CREATE PROC dbo.TransferCompanyInfo
as
BEGIN TRAN
Update Data_Archive.dbo.Company
Set
Data_Archive.dbo.Company.CompanyID = b.CompanyID,
Data_Archive.dbo.Company.CompanyName = b.CompanyName,
Data_Archive.dbo.Company.Address1 = b.Address1,
Data_Archive.dbo.Company.Address2 = b.Address2,
Data_Archive.dbo.Company.Address3 = b.Address3,
Data_Archive.dbo.Company.Address4 = b.Address4,
Data_Archive.dbo.Company.ZipCode = b.ZipCode,
From Data_Archive.dbo.Company a, OLD.dbo.Company b
Where a.CompanyID = b.CompanyID
ELSE
INSERT INTO Data_Archive.dbo.Company
Select
CompanyID,
CompanyName,
Address1,
Address2,
Address3,
Address4,
ZipCode,
FROM OLD.dbo.company
where not exists (select Data_Archive.dbo.Company.CompanyID from Data_Archive.dbo.Company
WHERE CompanyID = OLD.dbo.Company.CompanyID)
IF @@ERROR <> 0
BEGIN
ROLLBACK TRAN
RAISERROR ('Error occured while copying data to TachographData_Archive.dbo.company', 16, 1)
RETURN -1
END
IF @@TRANCOUNT > 0
BEGIN
COMMIT TRAN
RETURN 0
END
答案 0 :(得分:3)
您可以使用MERGE:
MERGE Data_Archive.dbo.Company WITH (HOLDLOCK) AS a
USING OLD.dbo.Company AS o
ON a.CompanyID = b.CompanyID
WHEN MATCHED THEN UPDATE
SET CompanyName = o.CompanyName,
Address1 = o.Address1,
Address2 = o.Address2,
Address3 = o.Address3,
Address4 = o.Address4,
ZipCode = o.ZipCode
WHEN NOT MATCHED BY TARGET THEN
INSERT (CompanyName, Address1, Address2, Address3, Address4, ZipCode)
VALUES (o.CompanyName, o.Address1, o.Address2, o.Address3, o.Address4, o.ZipCode)
WHEN NOT MATCHED BY SOURCE THEN DELETE;
这将更新存在的所有记录,插入任何新记录,并从归档中删除已从OLD
数据库中删除的任何记录。如果不需要最后一位,则只需删除WHEN NOT MATCHED BY SOURCE THEN DELETE
。
使用HOLDLOCK
将确保您不会遇到race condition,虽然MERGE仍有some quirks,但我认为这不会成为问题。
这样做的主要好处是SQL在单个事务中管理它,因此您无需检查一个部件是否出现故障,然后再回滚事务。
答案 1 :(得分:1)
使用MERGE
声明:
MERGE INTO Stg.Data_Archive.dbo.Company AS tbl
USING (
SELECT old.CompanyID, old.CompanyName, old.Address1, old.Address2, old.Address3, old.Address4, old.ZipCode
FROM OLD.dbo.Company AS old
LEFT OUTER JOIN Data_Archive.dbo.Company AS new
ON old.CompanyID = new.CompanyID
WHERE new.CompanyID IS NOT NULL) AS source
ON tbl.CompanyID=source.CompanyID
WHEN MATCHED THEN --if i find a row, update
UPDATE SET
tbl.CompanyID = source.CompanyID,
tbl.CompanyName = source.CompanyName,
tbl.Address1 = source.Address1,
tbl.Address2 = source.Address2,
tbl.Address3 = source.Address3,
tbl.Address4 = source.Address4,
tbl.ZipCode = source.ZipCode
WHEN NOT MATCHED THEN --if not, insert a new one
INSERT (CompanyID, CompanyName, Address1, Address2, Address3, Address4, ZipCode)
VALUES (source.CompanyID, source.CompanyName, source.Address1, source.Address2, source.Address3, source.Address4, source.ZipCode);
答案 2 :(得分:0)
BEGIN TRY
SET NOCOUNT ON
DECLARE @l_numberOfRecordsInserted INT
BEGIN
RAISERROR ( N'Invalid Application User ID %d passed.'
,17
,1
,-1 )
END
IF NOT EXISTS ( SELECT
1
FROM
Data_Archive.dbo.Company
WHERE
( CompanyID = @i_CompanyID )
AND CompanyName = @vc_CompanyName )
BEGIN
INSERT INTO
Data_Archive.dbo.Company
(
CompanyID,
CompanyName,
Address1,
Address2,
Address3,
Address4,
ZipCode
)
Select CompanyID,
CompanyName,
Address1,
Address2,
Address3,
Address4,
ZipCode
FROM OLD.dbo.company
where not exists (select Data_Archive.dbo.Company.CompanyID from Data_Archive.dbo.Company
WHERE CompanyID = @i_CompanyID)
END
ELSE
BEGIN
Update Data_Archive.dbo.Company
Set
Data_Archive.dbo.Company.CompanyID = b.CompanyID,
Data_Archive.dbo.Company.CompanyName = b.CompanyName,
Data_Archive.dbo.Company.Address1 = b.Address1,
Data_Archive.dbo.Company.Address2 = b.Address2,
Data_Archive.dbo.Company.Address3 = b.Address3,
Data_Archive.dbo.Company.Address4 = b.Address4,
Data_Archive.dbo.Company.ZipCode = b.ZipCode,
From Data_Archive.dbo.Company a, OLD.dbo.Company b
Where a.CompanyID = @i_CompanyID
END
RETURN 0
END TRY
--------------------------------------------------------
BEGIN CATCH
-- Handle exception
DECLARE @i_ReturnedErrorID INT
EXECUTE @i_ReturnedErrorID = dbo.usp_HandleException @i_UserId = @i_AppUserId
RETURN @i_ReturnedErrorID
END CATCH
答案 3 :(得分:0)
您可以尝试使用Merge
语句。我相信这对你有用:
Merge Into Data_Archive.dbo.Company As Target
Using
(
Select CompanyID,
CompanyName,
Address1,
Address2,
Address3,
Address4,
ZipCode
From OLD.dbo.company
) As Source On Source.CompanyID = Target.CompanyID
When Not Matched Then
Insert (CompanyID, CompanyName, Address1, Address2, Address3, Address4, ZipCode)
Values (Source.CompanyID, Source.CompanyName, Source.Address1, Source.Address2, Source.Address3, Source.Address4, Source.ZipCode)
When Matched Then
Update
Set CompanyName = Source.CompanyName,
Address1 = Source.Address1,
Address2 = Source.Address2,
Address3 = Source.Address3,
Address4 = Source.Address4,
ZipCode = Source.ZipCode
;