This WinForms project has the following code:
DataSet ds = new DataSet();
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["EbosPr.Properties.Settings.Database1ConnectionString1"].ConnectionString);
SqlCommand scmd = new SqlCommand("Select * From CustCalls ", conn);
SqlDataAdapter sda = new SqlDataAdapter(scmd);
sda.Fill(ds);
DataTable dt = ds.Tables[0];
this.dataGridView1.BindingContext[dt].EndCurrentEdit();
SqlCommandBuilder myBuilder = new SqlCommandBuilder(sda);
myBuilder.GetUpdateCommand();
sda.UpdateCommand = myBuilder.GetUpdateCommand();
sda.Update(dt);
It doesn't update the database and there is no error. How can this be improved?
I have the following code in production in a small internal utility and it works like a charme:
public int UpdateSQLDataTable(string connectionString, string TableName, DataTable dtSource)
{
using (SqlConnection sConn = new SqlConnection(connectionString))
{
sConn.Open();
var transaction = sConn.BeginTransaction();
try
{
SqlCommand command = sConn.CreateCommand();
command.Transaction = transaction;
command.CommandText = string.Format("SELECT TOP 1 * FROM dbo.[{0}] WITH (NOLOCK)", TableName);
command.CommandType = CommandType.Text;
// timeout in seconds...
command.CommandTimeout = 30;
SqlDataAdapter sAdp = new SqlDataAdapter(command);
SqlCommandBuilder sCMDB = new SqlCommandBuilder(sAdp);
int affectedRecords = sAdp.Update(dtSource);
transaction.Commit();
return affectedRecords;
}
catch (Exception /* exp */)
{
transaction.Rollback();
throw;
}
}
}
use a dataTable instead of a DataSet .. that worked for me
Related
I`ve written some code to establish a connection to SQL Server, then execute select procedure to take all data from my data table in SQL server, but it throw a InvalidOperationException at the command of declare a new SqlDataAdapter, please help me to fix this error.
public class dBConnect
{
//create SQLconnection variable
private SqlConnection con;
//create default constructor that passing a string to con
public dBConnect()
{
try
{
con = new SqlConnection(#"Server=Trump\SQLEXPRESS;
Database=Demo;User Id=sa;Password = stevejobs;");
}
catch(Exception exCon)
{
Console.WriteLine("Unable to connect to database: {0}", exCon);
}
}
//create Select method to Pour the data into the DataTable
public DataTable SelectAll(string procName, SqlParameter[] para = null)
{
//create a DataTable to store Data from DB
DataTable dt = new DataTable();
//create SQLCommand
SqlCommand cmd = new SqlCommand(procName, con);
//declare that cmdType is sp
cmd.CommandType = CommandType.StoredProcedure;
//input parameter of cmd
if (para != null)
cmd.Parameters.AddRange(para);
//create dataAdapter object
//InvalidOperationException was thrown at here
SqlDataAdapter da = new SqlDataAdapter(cmd);
//declare that cmd is select command of da
da.SelectCommand = cmd;
//use try/catch/finally to establish a connection
try
{
con.Open();
da.Fill(dt);
}
catch(Exception sqlEx)
{
Console.WriteLine(#":Unable to establish a connection: {0}", sqlEx);
}
finally
{
con.Close();
con.Dispose();
}
return dt;
}
}
}
You should:
cmd.CommandText = "your Stored Procedure here.";
cmd.CommandType = CommandType.StoredProcedure;
//input parameter of cmd
if (para != null)
cmd.Parameters.AddRange(para);
//create dataAdapter object
Put your con.Open(); above
or
Just take a look at this steps
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
using (SqlCommand cmd = con.CreateCommand())
{
//sample stored procedure with parameter:
// "exec yourstoredProcedureName '" + param1+ "','" + param2+ "'";
cmd.CommandText = "Your Stored Procedure Here";
cmd.CommandType =CommandType.StoredProcedure;
using (SqlDataAdapter adp = new SqlDataAdapter(cmd))
{
adp.Fill(dt);
return dt;
}
}
}
Cleaning up your code a bit here:
public DataTable SelectAll(string procName, SqlParameter[] para = null)
{
DataTable dt = new DataTable();
try
{
using (SqlConnection con = new SqlConnection(connString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand(procName, con))
{
cmd.CommandType = CommandType.StoredProcedure;
if (para != null)
cmd.Parameters.AddRange(para);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
}
}
catch (Exception sqlEx)
{
Console.WriteLine(#":Unable to establish a connection: {0}", sqlEx);
}
return dt;
}
How can I adapt my code to any changes that are made remain persistent?
As I understand I need to update the datatable which in turn will update the database. So I have tried to use the update command like below on a button click event.
adb.Update(dt);
However this doesn't seem to work, so I am obviously missing something, but I'm not sure what?.
Code
String ConnStr = "Data Source=database.com\\sqlexpress; Initial Catalog=Data; User ID=mobile; Password=password";
String SQL = "SELECT stationID, LocationName, plandate, username, status FROM dbo.joblist WHERE username = #username and status = #status";
SqlConnection con = new SqlConnection(ConnStr);
try
{
con.Open();
}
catch (Exception)
{
MessageBox.Show(e.ToString());
}
SqlCommand command = new SqlCommand(SQL, con);
command.Parameters.Add("#username", SqlDbType.VarChar).Value = auditorCmb.Text;
command.Parameters.Add("#status", SqlDbType.VarChar).Value = statusCmb.Text;
SqlDataAdapter adb = new SqlDataAdapter(command);
using (DataTable dt = new DataTable())
{
try
{
adb.Fill(dt);
dataGridView1.AutoResizeColumns();
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
con.Close();
}
catch
{
MessageBox.Show(e.ToString());
}
dataGridView1.DataSource = dt;
}
As far as I know SqlDataAdapter does not generate insert, update or delete commands on its own.
You have to either set them manually - https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.selectcommand(v=vs.110).aspx.
Or generate them with SqlCommandBuilder:
public static DataSet SelectSqlRows(string connectionString,
string queryString, string tableName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(queryString, connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
connection.Open();
DataSet dataSet = new DataSet();
adapter.Fill(dataSet, tableName);
//code to modify data in DataSet here
builder.GetUpdateCommand();
//Without the SqlCommandBuilder this line would fail
adapter.Update(dataSet, tableName);
return dataSet;
}
}
Is this good approach to get data from stored procedure? For example procedure is making select * from base. Here is my code but I need help with dataset and adapter:
public static DataSet Osvezi(string naziv_tablice)
{
SqlCommand cmd = null;
DataSet dataset = null;
SqlConnection konekcija = new SqlConnection(ConfigurationManager.AppSettings["skripta"]);
if (konekcija != null)
{
try
{
if (konekcija.State == ConnectionState.Closed)
konekcija.Open();
cmd = new SqlCommand();
cmd.Connection = konekcija;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Osvezi";
cmd.Parameters.Add(new SqlParameter("#tablica", SqlDbType.Int)).Value = naziv_tablice;
cmd.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter(cmd);
// Fill the DataSet using default values for DataTable names, etc
da.Fill(dataset);
return dataset;
}
catch (Exception ee)
{
//Obravnava napak
}
finally
{
konekcija.Close();
konekcija.Dispose();
cmd.Dispose();
}
return dataset;
}
return dataset;
}
Try this one instead:
public static DataSet Osvezi(string naziv_tablice)
{
try
{
using (SqlConnection konekcija = new SqlConnection(ConfigurationManager.AppSettings["skripta"]))
{
konekcija.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = konekcija;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Osvezi";
cmd.Parameters.AddWithValue("#tablica", naziv_tablice??DBNull.Value);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
// Fill the DataSet using default values for DataTable names, etc
DataSet dataset = new DataSet();
da.Fill(dataset);
return dataset;
}
}
}
}
catch (Exception ee)
{
//Obravnava napak
}
return null;
}
Please correct the following.
You don't need to open the connection.
There shouldn't be any command.ExecuteNonQuery.
The parameter in the method is string but the datatype of SqlParameter is SqlDbType.Int.
I try to write a winform application:
I dislike below codes:
DataTable dt = new DataTable();
dt.Load(dr);
ds = new DataSet();
ds.Tables.Add(dt);
Above part of codes looks unsufficient.How can I best loading dataset?
public class LoadDataset
{
public DataSet GetAllData(string sp)
{
return LoadSQL(sp);
}
private DataSet LoadSQL(string sp)
{
SqlConnection con = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"].ToString());
SqlCommand cmd = new SqlCommand(sp, con);
DataSet ds;
try
{
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
ds = new DataSet();
ds.Tables.Add(dt);
return ds;
}
finally
{
con.Dispose();
cmd.Dispose();
}
}
}
Here is a simple function I converted from VB to C# (http://www.developerfusion.com/tools/convert/vb-to-csharp/). I use this extensively.
Simple wrapper function to help return a dataset from and SQL statement via an existing connection.
This should have performance improvements over re-connected via a connection string each time. Wraps any SQL errors in to a custom format.
public System.Data.DataSet GetDataSet(string sqlStatement, System.Data.SqlClient.SqlConnection connection)
{
System.Data.DataSet functionReturnValue = default(System.Data.DataSet);
if (connection == null) {
throw new ArgumentNullException("connection");
}
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
System.Data.SqlClient.SqlDataAdapter adp = new System.Data.SqlClient.SqlDataAdapter();
System.Data.DataSet dset = new System.Data.DataSet();
try {
// Connect to the database
if (connection.State != ConnectionState.Open) {
connection.Open();
}
if (connection.State != ConnectionState.Open) {
throw new MyCustomException("Connection currently {0} when it should be open.", connection.State));
}
// Create a command connection
cmd = new System.Data.SqlClient.SqlCommand();
{
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlStatement;
}
//.ExecuteReader() 'Forward only Dataset
// Create a data adapter to store the inforamtion
adp = new System.Data.SqlClient.SqlDataAdapter();
dset = new DataSet();
{
adp.SelectCommand = cmd;
adp.Fill(dset, "Results");
}
// Return the resulting dataset to the calling application
functionReturnValue = dset;
}
catch (System.Data.SqlClient.SqlException objSE) {
functionReturnValue = null;
// Let the calling function known they stuffed up and give them the SQL to help out.
throw new JDDataException(System.String.Format("SQL :- {0}.", sqlStatement), objSE);
}
finally {
if ((cmd != null)) cmd = null;
if ((adp != null)) adp = null;
if ((dset != null)) dset = null;
}
return functionReturnValue;
}
public string GetSqlConnection()
{
return System.Configuration.ConfigurationManager.AppSettings["SqlConnectionString"];
}
public DataSet getDataSet(string sql)
{
DataSet ds = new DataSet();
SqlConnection conn = new SqlConnection(GetSqlConnection());
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill(ds);
conn.Close();
conn.Dispose();
da.Dispose();
return ds;
}
I created a stored procedure so as to return me a table.
Something like this:
create procedure sp_returnTable
body of procedure
select * from table
end
When I call this stored procedure on the frontend what code do I need to write to retrieve it in a datatable object?
I wrote code something like the following. I basically want to know retrieving and storing table into an object of datatable. All my queries are running, but I don't know how to retrieve table into a datatable through a stored procedure
DataTable dtable = new DataTable();
cmd.Connection = _CONN;
cmd.CommandText = SPNameOrQuery;
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter adp = new SqlDataAdapter(cmd);
OpenConnection();
adp.Fill(dtTable);
CloseConnection();
Here in this code a command has been bound with the stored procedure name and its parameters. Will it be returning me a datatable from the stored procedure?
string connString = "<your connection string>";
string sql = "name of your sp";
using(SqlConnection conn = new SqlConnection(connString))
{
try
{
using(SqlDataAdapter da = new SqlDataAdapter())
{
da.SelectCommand = new SqlCommand(sql, conn);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet ds = new DataSet();
da.Fill(ds, "result_name");
DataTable dt = ds.Tables["result_name"];
foreach (DataRow row in dt.Rows) {
//manipulate your data
}
}
}
catch(SQLException ex)
{
Console.WriteLine("SQL Error: " + ex.Message);
}
catch(Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
}
Modified from Java Schools Example
Set the CommandText as well, and call Fill on the SqlAdapter to retrieve the results in a DataSet:
var con = new SqlConnection();
con.ConnectionString = "connection string";
var com = new SqlCommand();
com.Connection = con;
com.CommandType = CommandType.StoredProcedure;
com.CommandText = "sp_returnTable";
var adapt = new SqlDataAdapter();
adapt.SelectCommand = com;
var dataset = new DataSet();
adapt.Fill(dataset);
(Example is using parameterless constructors for clarity; can be shortened by using other constructors.)
Explaining if any one want to send some parameters while calling stored procedure as below,
using (SqlConnection con = new SqlConnection(connetionString))
{
using (var command = new SqlCommand(storedProcName, con))
{
foreach (var item in sqlParams)
{
item.Direction = ParameterDirection.Input;
item.DbType = DbType.String;
command.Parameters.Add(item);
}
command.CommandType = CommandType.StoredProcedure;
using (var adapter = new SqlDataAdapter(command))
{
adapter.Fill(dt);
}
}
}