ストアドプロシージャには、3つのinsertステートメントがあります。
重複キー値の挿入時に、最初の2つのクエリでエラーが生成されます
PRIMARY KEY制約の違反
3番目のクエリは通常どおり実行されます。
クエリで例外が発生した場合、すべてをロールバックする必要があります。
クエリによって生成された例外がない場合、コミットされます。
declare @QuantitySelected as char
set @QuantitySelected = 2
declare @sqlHeader as varchar(1000)
declare @sqlTotals as varchar(1000)
declare @sqlLine as varchar(1000)
select @sqlHeader = 'Insert into tblKP_EstimateHeader '
select @sqlHeader = @sqlHeader + '(CompanyID,CompanyName,ProjectName,EstimateID,EstimateHeader,QuoteDate,ValidUntil,RFQNum,Revision,Contact,Status,NumConfigurations) '
select @sqlHeader = @sqlHeader + ' select CompanyID,CompanyName,ProjectName,EstimateID,EstimateHeader,QuoteDate,ValidUntil,RFQNum,Revision,Contact,Status,NumConfigurations '
select @sqlHeader = @sqlHeader + 'from V_EW_Estimate_Header where EstimateID = 2203'
select @sqlTotals = 'Insert into tblKP_Estimate_Configuration_Totals '
select @sqlTotals = @sqlTotals + '(ConfigRecId,RecId,SellQty,ConfigNum,ConfigDesc,SortOrder,OptionsInMainPrice,MarkupPctQty,'
select @sqlTotals = @sqlTotals + ' SellPriceQty,RubberStamp,OptPriceQty,StatusRecid,LastUpdate_Date,LastUpdate_User,TotalCost,QuantityBracketSelected)'
select @sqlTotals = @sqlTotals + ' select ConfigRecId,RecId,SellQty' + @QuantitySelected + ',ConfigNum,ConfigDesc,SortOrder,OptionsInMainPrice'
select @sqlTotals = @sqlTotals + ' ,MarkupPctQty' + @QuantitySelected + ',SellPriceQty' + @QuantitySelected + ',RubberStamp,OptPriceQty' + @QuantitySelected + ',StatusRecid,LastUpdate_Date,LastUpdate_User,TotalCost' + @QuantitySelected + ',' + @QuantitySelected
select @sqlTotals = @sqlTotals + ' from v_EW_Estimate_Configuration_Totals where ConfigRecId = -3'
select @sqlLine = 'Insert into tblKP_Estimate_Configuration_Lines'
select @sqlLine = @sqlLine + '(MstrRfqRecId,RfqRecId,RfqLineRecId,CompanyId,VendorQuoteNum,LineGrp,LineNum,StatusRecId,'
select @sqlLine = @sqlLine + ' LineDesc,LineSize,LineMatl,LineDeco,LineFinish,CopyFromRecId,PerPieceCost,IsOptional,'
select @sqlLine = @sqlLine + ' CopyToNewRev,RecId,UnitPrice,LineQty,LinePrice,CustOrVend,SellQty1,RfqNum,ConfigLineIsOptional,ConfigLinePerPieceCost,ConfigLineRecid,SellPrice,SaleQty)'
select @sqlLine = @sqlLine + ' select distinct MstrRfqRecId,RfqRecId,RfqLineRecId,CompanyId,VendorQuoteNum,LineGrp,LineNum,'
select @sqlLine = @sqlLine + ' StatusRecId,LineDesc,LineSize,LineMatl,LineDeco,LineFinish,CopyFromRecId,PerPieceCost,IsOptional,'
select @sqlLine = @sqlLine + ' CopyToNewRev,RecId,UnitPrice' + @QuantitySelected + ',LineQty' + @QuantitySelected + ', isnull(LinePrice' + @QuantitySelected + ', 0.0000),CustOrVend,SellQty' + @QuantitySelected + ',RfqNum,ConfigLineIsOptional,ConfigLinePerPieceCost,ConfigLineRecid,SellPrice' + @QuantitySelected + ',SaleQty' + @QuantitySelected
select @sqlLine = @sqlLine + ' from v_EW_EstimateLine where rfqlinerecid in (select RfqLineRecID from kp_tblVendorRfqConfigLine where ConfigRecID = -3) '
exec( @sqlHeader)
exec(@sqlTotals)
exec(@sqlLine)
幸いなことに、SQL Serverのトランザクションは複数のバッチにまたがることができます(各exec
は個別のバッチとして扱われます)。
EXEC
ステートメントをBEGIN TRANSACTION
およびCOMMIT
でラップできますが、エラーが発生した場合はさらに一歩進んでロールバックする必要があります。
理想的には、次のようなものが必要です。
BEGIN TRY
BEGIN TRANSACTION
exec( @sqlHeader)
exec(@sqlTotals)
exec(@sqlLine)
COMMIT
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK
END CATCH
BEGIN TRANSACTION
とCOMMIT
はすでにご存じだと思います。 BEGIN TRY
およびBEGIN CATCH
ブロックは、発生したエラーをキャッチして処理するために基本的にあります。 EXEC
ステートメントのいずれかでエラーが発生した場合、コード実行はCATCH
ブロックにジャンプします。
トランザクションはできるだけ短くしたいので、既存のSQL構築コードはトランザクションの外側(上記)にある必要があります。