Click here to Skip to main content
15,879,326 members
Please Sign up or sign in to vote.
2.33/5 (3 votes)
See more:
I got two Tables 'Purchase Order' abd 'Purchase Order Products'.

I am using .NET c# program to call store procedure.

I would like to generate id and insert record for 'Purchase Order' first. Then insert records for 'Purchase Order Products' since it includes the ids generated.

If just calling a single store procedure, I can use TRY CATCH and ROLLBACK to make sure updates of two tables in sync. However, I do not know how to pass a list of information (i.e. all records for Purchase Order Product) into a single store procedure.

e.g. pass the following list as parameters
each Product include name, qty, amount
ProductA, 1, $20
ProductB, 3, $28
...

So I assume calling insert product procedure each time for one product, but then it cannot rollback the inserted row of 'Purchase Order' if any errors occur in inserting 'Products'.

Is there any practice that can solve my situation so I could make sure all records (Order and Products) will be added or no records will be added and error is known?
Posted
Updated 3-Mar-13 16:28pm
v2

Hi,
For your solution you need to study Using Transactions in ADO.NET[^] and read about SqlTransaction Class[^]. After study this you are able to integrate such given example's code into your system. Please review below links.

http://code.rumeryenterprises.com/post/2010/03/14/C-Sql-Transaction-Example.aspx[^]
http://www.aspnettutorials.com/tutorials/database/sql-transaction-csharp.aspx[^]
http://www.dotnetspider.com/resources/31532-Sql-Transaction.aspx[^]
 
Share this answer
 
Hello ,

Create one stored procedure as mentioned below

SQL
CREATE PROCEDURE spSavePurchase_Order_Products
(
 @OrderInfo AS XML
)
AS 
BEGIN
DECLARE @tblOrderInfo AS TABLE(Product NVARCHAR(MAX),Qty INT , Amount INT)
--DECLARE @tblOrderInfo AS TABLE(ProductId NVARCHAR(MAX),Qty INT , Amount INT)

INSERT INTO @tblOrderInfo 
SELECT 
   Orders.Orderinfo.value('@Product', 'NVARCHAR(MAX)') as Product,
   Orders.Orderinfo.value('@Qty', 'NVARCHAR(MAX)') as Qty,
   Orders.Orderinfo.value('@Amount', 'NVARCHAR(MAX)') as Amount
   --Y.ID.value('(Items/Item/@Name)[1]', 'varchar(max)') as "Name",
   --Y.ID.value('(Attributes/Attribute/@ID)[1]', 'int') as AttributeID
FROM @OrderInfo.nodes('/Orders/Order') as Orders(Orderinfo)

BEGIN TRAN
 BEGIN TRY
  
   
   INSERT INTO [Purchase Order](Name)
   SELECT Product FROM @tblOrderInfo WHERE Product NOT IN (SELECT Name FROM [Purchase Order]) 
   
   INSERT INTO [Purchase Order Products] (ProductId  ,Qty  , Amount )
   SELECT PO.Id,tblO.Qty,tblO.Amount FROM @tblOrderInfo tblO inner join [Purchase Order] PO on tblO.Product=PO.Name
   
   
   COMMIT TRAN
  END TRY
 BEGIN CATCH 
    ROLLBACK TRAN
  END CATCH
 
END


Create single XML string for all your orders and execute above procedure and pass that XML String

see below

SQL
DECLARE @X AS XML


SET @X='<Orders>
           <Order Product="ProductA1" Qty="10" Amount="10"></Order>
           <Order Product="ProductB1" Qty="20" Amount="100"></Order>  
	</Orders>'


EXEC spSavePurchase_Order_Products @X


Hope this helps if yes then accept and vote this solution
--RDBurmon
 
Share this answer
 
v2
Hi swissivan,

(I Assume you're using MS SQL Server for db)
You can have a SQLCommand object, A connection to db and list of all queries to be executed whether it is call a procedure or it's a text command. Add all the queries to the list, create a SQLTransaction object for you SQLConnection and assign it to SQLCommand. Start the Transactin, Iterate through & execute each command in queries-list and then Commit the transaction. Put the all above in a try catch block and in Carch put the Rollback in case if anything goes wrong.

Do write back for any clarification.

Hope this helps!

-SK
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900