2013-02-21 17 views
43

ストアドプロシージャには3つの挿入文があります。重複したキー値の挿入最初の2つのクエリでSQL Serverでトランザクションをロールバックまたはコミットする方法

エラー

PRIMARY KEY制約の違反

及び第三のクエリは通常どおり実行され発生します。

これで、すべてのクエリで例外が生成された場合は、すべてがロールバックされる必要があります。

どのクエリでも例外が生成されない場合は、コミットされます。

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) 
+0

ようこそStackOverflow:コード、XML、またはデータサンプルを投稿する場合は、**これらの行をテキストエディタで強調表示し、エディタツールバーの[コードサンプル]ボタン( '{}')をクリックしてくださいフォーマットと構文はそれを強調する! –

+0

@marc_sありがとうmarc。 StoreProcedureを追加しました。チェックアウトしてください。 –

+0

**ストアドプロシージャ** - **プロシージャ** ** SQL Server内に**保存されています - ストアとは関係ありません.... –

答えて

132

良いニュースは、SQL Serverのトランザクションが

あなたがBEGIN TRANSACTIONCOMMITであなたのEXECステートメントをラップすることができます(各execは別のバッチとして処理されます。)複数のバッチにまたがることができますが、あなたはよですエラーが発生した場合はさらに進んでロールバックする必要があります。

理想的には、このような何かしたいと思います:私はあなたがすでに精通していると信じて

BEGIN TRY 
    BEGIN TRANSACTION 
     exec(@sqlHeader) 
     exec(@sqlTotals) 
     exec(@sqlLine) 
    COMMIT 
END TRY 
BEGIN CATCH 

    IF @@TRANCOUNT > 0 
     ROLLBACK 
END CATCH 

BEGIN TRANSACTIONCOMMITを。 BEGIN TRYBEGIN CATCHブロックには、基本的に発生したエラーを捕まえて処理するブロックがあります。 EXECステートメントのいずれかでエラーが発生すると、コード実行はCATCHブロックにジャンプします。

トランザクションを可能な限り短くしたい場合は、既存のSQLビルディングコードをトランザクション外にする必要があります(上記)。

+1

の主なスカートです。それはうまく動作します。最初に動作するときはstoreProcedureにあります。 storePの2回目の実行時に例外が生成されます: - "EXECUTEの後のトランザクションカウントは、BEGINおよびCOMMITステートメントの不一致の数を示します。前のカウント= 0、現在のカウント= 1" –

+2

申し訳ありませんが、それは 'IF @@ TRANCOUNT> 0'だったはずです。答えを更新します。 –

+0

ありがとうございます。今それは正常に動作しています。 –

関連する問題