我已经创建了以下存储过程,它复制了表中的记录以及其他表中的所有相关记录,但是,由于我是SQL新手,如果有人能够检查我的代码并向我展示如何改进它,以及是否存在任何危险,我将不胜感激。
USE [Neptune2Dev]
GO
/****** Object: StoredProcedure [dbo].[DuplicateItemInBatch] Script Date: 03/04/2013 17:55:47 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[DuplicateItemInBatch] @batchID AS INT , @numInBatch AS INT
AS
declare @itemIdToBeDuplicated as int
declare @duplicatedItemID as int
declare @URI as varchar(max)
declare @itemOrganisationID as int
declare @duplicateItemOrganisationID as int
BEGIN TRY
BEGIN TRANSACTION;
--increment all proceeding numbInbatch fileds to accomodiate the new item being duplicated
UPDATE items SET numinbatch = numinbatch + 1
WHERE numinbatch > @numInBatch AND BatchID = @batchID
select @itemIdToBeDuplicated = ID from items i where i.BatchID = @batchID and i.NumInBatch = @numInBatch
select @URI = URI from ItemMedia where ID = @itemIdToBeDuplicated
--duplicate the item and insert it into the table
insert into items
select
i.SupplierID, i.Title, i.PubDate, i.Body, i.StatusID,
i.IsRelevant, i.ClipDuration, i.ResearchDuration,
i.Comments, i.ItemTypeID, i.PageNumber, i.BatchID,
i.NumInBatch + 1, i.OverrideDate, i.MediaChannelID,
i.Size, i.PreviouslyCompleted
from items i where i.ID = @itemIdToBeDuplicated
select @duplicatedItemID = SCOPE_IDENTITY();
select @itemOrganisationID = ID from ItemOrganisations where ItemID = @itemIdToBeDuplicated
insert into ItemOrganisations
select @duplicatedItemID, OrganisationID, comment, rating from ItemOrganisations where ID = @itemOrganisationID
select @duplicateItemOrganisationID = SCOPE_IDENTITY();
insert into ItemOrganisationMessages
select @duplicateItemOrganisationID, MessageID from ItemOrganisationMessages where ItemOrganisationID = @itemOrganisationID
insert into ItemOrganisationIssues
select @duplicateItemOrganisationID, IssueID from ItemOrganisationIssues where ItemOrganisationID = @itemOrganisationID
insert into ItemByLines
select @duplicatedItemID, ByLineID from ItemByLines where ItemID = @itemIdToBeDuplicated
insert into ItemDocumentLink
select ItemDocumentID, @duplicatedItemID from ItemDocumentLink where ItemID = @itemIdToBeDuplicated
insert into ProfileResults
select ProfileId, @duplicatedItemID from ProfileResults where ItemID = @itemIdToBeDuplicated
insert into ItemNotes
select @duplicatedItemID,Quote,Theme,Rating,Comment,IsBad from ItemNotes where ItemID = @itemIdToBeDuplicated
IF @URI <> null
BEGIN
insert into ItemMedia values (@duplicatedItemID, @URI)
END
ELSE
PRINT N'No Article to be duplicated '
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
BEGIN
PRINT
ERROR_NUMBER() +' ' + ERROR_MESSAGE()
ROLLBACK TRANSACTION;
END;
END CATCH;发布于 2013-04-04 17:56:55
以下是一些没有具体顺序的评论:
CATCH块--包括注释--是来自文档的复制和粘贴。虽然阅读文档总是很好的,但请记住,这些示例是为了说明特定的特性,您不应该假设它们在生产代码中是可用的。TRY块中发生错误,那么您的CATCH块会提交(如果可能的话),这是您想要的吗?XACT_STATE()告诉您可以提交事务,而不是应该提交。有关详细信息,请参阅这个问题。CATCH块不检查或记录错误消息(使用ERROR_NUMBER()和类似的函数),因此如果确实发生错误,您将不知道它是什么INSERT中的所有列名;如果表结构发生更改,这将为您提供一些安全性。NULL值,则需要编写IF @URI IS NULLBEGIN和END包装整个存储过程体并不是必需的,但通常是很好的实践,否则很容易忘记该过程的结束位置,并意外地添加一些您无意中添加的代码。SET NOCOUNT ON请始终提到您的Server版本(2005、2008、2008R2、2012)和版本(Standard、Enterprise、Express),因为这决定了哪些语言特性可用。
https://codereview.stackexchange.com/questions/24677
复制相似问题