Update dataset using stored procedure

J

John

Hi, ADO.NET guru,

I have a question about ADO.NET, here is the scenerio:

1. DataSet contains multiple tables with relation defined, let's say (Order
and OrderDetails)
2. I will fill the dataSet using one stored procedure to call another two
stored procedure to return multiple table, using table mapping
3. I have to use stored procedure to do all update, insert and delete
4. so I will not use Command Builder
5. Is it possible to use SqlDataAdapter.update(dataset) to save all the
changes back into database after I manipulate the dataset (some updates,
some insert and some delete)? If yes, how to specify the update,delete and
insert command using stored procedures for multiple tables?

Thanks very much!

John
 
W

William Ryan eMVP

You can use the DataAdapterConfiguration wizard and select Stored Procedures
for the command type. It's pretty much that easy but you'll need to handle
premissions on your own. Check out Bill Vaughn's article on Weaning
Developers from the CommandBuilder under the MSDN articles section of
www.betav.com

HTH,

Bill
 
K

Kevin Yu [MSFT]

Thanks for Bill's quick response.

Hi John,

Thank you for posting in the community!

First of all, I would like to confirm my understanding of your issue. From
your description, I understand that you need to update multiple source
tables with a single SqlDataAdapter. If there is any misunderstanding,
please feel free to let me know.

I think it is possible to use SqlDataAdapter.update(dataset) to save all
the changes back into database. We can set the
SqlDataAdapter.UpdateCommand's CommandText property to that stored
procedure name and CommandType property to CommandType.StoredProcedure.
Then we have to add parameters to that UpdateCommand. Make sure that the
value of the parameter has been mapped to the correct source column.

However, It is not recommended to use one SqlDataAdapter to update multiple
database tables if there are columns with the same name in different
tables. As the values from source column might be confused by the same
column name, the database table might not be correctly updated.

Does this answer your question? If anything is unclear, please feel free to
reply to the post.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
P

Prodip Saha

John,
Yes, it can be done. I have done it successfully. Look at the code snippet
below. You may have to make some modification since you have multiple tables
in the dataset. My recommendation would be--loop through the dataset for
each table, create a new DataTable with the GetChanges() method on the table
and pass it to the function. The new table will be created with the default
name "Table" which is an important requirement.

I am sure it will work. Good luck.
Prodip Saha
A Freelance Developer

public bool UpdateEntries(DataTable dtTable)
{
try
{
OleDbCommand updateCmd=CreateUpdateCommand();
OleDbCommand insertCmd=CreateInsertCommand();
OleDbCommand deleteCmd=CreateDeleteCommand();
int
retVal=ExecuteNonQuery(DatabaseConnectionString,updateCmd,insertCmd,deleteCm
d,dtTable,true);

if (retVal >0)
{
return true;
}
else
{
return false;
}
}
catch(Exception ex)
{
throw new Exception("User Defined Error:Unable to update entries.",ex);
}

}

private OleDbCommand CreateUpdateCommand(int EntryListType)
{
OleDbCommand cmd = new OleDbCommand();
cmd.Connection=new OleDbConnection(Database Connection String);
cmd.Connection.Open();
cmd.CommandTimeout=your custom time out in sec;
cmd.CommandType = CommandType.StoredProcedure;

cmd.CommandText="stored proc name";

OleDbCommandBuilder.DeriveParameters(cmd);

foreach(OleDbParameter paramCurrent in cmd.Parameters)
{
if (paramCurrent.Direction==ParameterDirection.Input)
{
paramCurrent.SourceColumn=paramCurrent.ParameterName;
}

}

if(cmd.Connection.State==ConnectionState.Open)
{
cmd.Connection.Close();
}
return cmd;

}

private OleDbCommand CreateInsertCommand(int EntryListType)
{
OleDbCommand cmd = new OleDbCommand();
cmd.Connection=new OleDbConnection(Database Connection String);
cmd.Connection.Open();
cmd.CommandTimeout=your custom time out in sec;
cmd.CommandType = CommandType.StoredProcedure;

cmd.CommandText="stored proc name";

OleDbCommandBuilder.DeriveParameters(cmd);

foreach(OleDbParameter paramCurrent in cmd.Parameters)
{
if (paramCurrent.Direction==ParameterDirection.Input)
{
paramCurrent.SourceColumn=paramCurrent.ParameterName;
}

}

if(cmd.Connection.State==ConnectionState.Open)
{
cmd.Connection.Close();
}
return cmd;

}

private OleDbCommand CreateDeleteCommand()
{
OleDbCommand cmd = new OleDbCommand();
cmd.Connection=new OleDbConnection(Database Connection String);
cmd.Connection.Open();
cmd.CommandTimeout=your custom time out in sec;
cmd.CommandType = CommandType.StoredProcedure;

cmd.CommandText="stored proc name";

OleDbCommandBuilder.DeriveParameters(cmd);

foreach(OleDbParameter paramCurrent in cmd.Parameters)
{
if (paramCurrent.Direction==ParameterDirection.Input)
{
paramCurrent.SourceColumn=paramCurrent.ParameterName;
paramCurrent.SourceVersion=DataRowVersion.Original;
}

}

if(cmd.Connection.State==ConnectionState.Open)
{
cmd.Connection.Close();
}
return cmd;

}

public int ExecuteNonQuery(string
connectionString,OleDbCommand updateCommand,OleDbCommand
insertCommand,OleDbCommand deleteCommand,DataTable dataTable,bool
useTransaction)
{
int retval=0;
OleDbTransaction txn=null;
OleDbConnection cn=null;

//Check if the DataTable has updated records. If so, an update command is
required.
DataTable updatedTable=dataTable.GetChanges(DataRowState.Modified);
if ((updatedTable !=null) && (updateCommand==null))
{
throw new Exception("Update Failed. Data has been modified but no update
command is specified.");
}

//Check if the DataTable has inserted records. If so, an insert command
is required.
DataTable insertedTable=dataTable.GetChanges(DataRowState.Added);
if ((insertedTable !=null) && (insertCommand==null))
{
throw new Exception("Update Failed. Data has been inserted but no insert
command is specified.");
}

//Check if the DataTable has deleted records. If so, a delete command is
required.
DataTable deletedTable=dataTable.GetChanges(DataRowState.Deleted);
if ((deletedTable !=null) && (deleteCommand==null))
{
throw new Exception("Update Failed. Data has been deleted but no delete
command is specified.");
}


try
{

//create & open a OleDbConnection, and dispose of it after we are done.
cn = new OleDbConnection(connectionString);
cn.Open();

//Create a data adapter
OleDbDataAdapter da = new OleDbDataAdapter();

//Assign commands to the adapter
if (updatedTable !=null)
{
updateCommand.Connection=cn;
da.UpdateCommand=updateCommand;
}

if (insertedTable !=null)
{
insertCommand.Connection=cn;
da.InsertCommand=insertCommand;
}

if (deletedTable !=null)
{
deleteCommand.Connection=cn;
da.DeleteCommand=deleteCommand;
}


//Create a new transaction if useTransaction is true
if (useTransaction==true)
{
txn = cn.BeginTransaction();

//Set the Transaction property of the DataAdapter's Commands.
if (updatedTable !=null)
{
da.UpdateCommand.Transaction = txn;
}
if (insertedTable !=null)
{
da.InsertCommand.Transaction = txn;
}
if (deletedTable !=null)
{
da.DeleteCommand.Transaction = txn;
}
}


//Submit the changes.
retval=da.Update(dataTable);

//Commit the changes and close the connection.
if (txn !=null)
{
txn.Commit();
}

return retval;

}
catch(Exception ex)
{

try
{
if (txn !=null)
{
txn.Rollback();
}

}
catch (OleDbException OleDbex)
{
throw OleDbex;
}

throw ex;
}
finally
{
if (cn !=null)
{
if (cn.State ==ConnectionState.Open)
{
cn.Close();
}
}
}


}
 
J

John

Thanks Kevin,

I decided to go on each table - and figured out the order of update by
analyzing the datarelation of the dataset, for delete, i delete children
before parent, for insert, insert parent before child - it worked quit well.

Thanks!

John
 
K

Kevin Yu [MSFT]

You're welcome, John. Thanks for sharing your experience with all the
people here. If you have any questions, please feel free to post them in
the community.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top