How to change command text of SqlCommandBuilder.InsertCommand? - c#

I want to modify SqlCommandBuilder to retrieve SCOPE_IDENTITY() value after an insert, without creating a stored procedure for each of 2000+ tables.
I'm trying this code:
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM dbo.Categories", connection);
DataTable categories = new DataTable();
adapter.Fill(categories);
...
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.InsertCommand = builder.GetInsertCommand();
adapter.InsertCommand.CommandText = adapter.InsertCommand.CommandText+
+"; SELECT SCOPE_IDENTITY() AS SCOPEIDENTITY";
...
adapter.Update(categories);
But no matter what I type, the DataAdapter executes the SQL statement that existed in the beginning - not my changes.
Even this text does not produce a SQL error:
adapter.InsertCommand.CommandText = "Hello world";
adapter.Update(categories);
SQL Server profiler shows this SQL statement instead of error.
exec sp_executesql N'INSERT INTO [dbo].[Categories] ([CategoryName]) VALUES (#p1)',N'#p1 nvarchar(12)',#p1=N'New Category'

The SqlCommand manual page says the following:
You can reset the CommandText property and reuse the SqlCommand object.
However, you must close the SqlDataReader before you can execute a new or
previous command.
It doesn't look like you are using a SqlDataReader, but this might apply to the SqlDataAdapter you are using.

builder.GetInsertCommand().Clone();

Related

Updating SQL table with the contents of a datatable

I am creating an application in WPF using C# where users populate a datagrid and the information is then stored in a DataTable called smb1. The following code works for inserting the data into the SQL database but when I modify the code for updating it does not work. Does anyone know how I can modify my code to allow Updates as there are no errors thrown when I run my application in Visual Studio. I must add that the Equipment column cannot be edited in the datagrid so the returned data is the same as the data taken from the database so that the updated rows will be matched to the equipment rows in the SQL database using the WHERE clause. Below is the original insertion code plus my attempt for updating the database.
Insert Code
SqlConnection con = new SqlConnection(MyConnectionString);
string SqlCmdText = "Insert into SHIFTLOG Values(#EQUIPMENT,#BATCHNO,#PRODUCTNO,#STATUS,#DATE,#PERIOD,#MACHINE)";
SqlCommand sc = new SqlCommand(SqlCmdText, con);
con.Open();
foreach (DataRow row in smb1.Rows)
{
sc.Parameters.Clear();
sc.Parameters.AddWithValue("#EQUIPMENT", row["EQUIPMENT"]);
sc.Parameters.AddWithValue("#BATCHNO", row["BATCHNO"]);
sc.Parameters.AddWithValue("#PRODUCTNO", row["PRODUCTNO"]);
sc.Parameters.AddWithValue("#STATUS", row["STATUS"]);
sc.Parameters.AddWithValue("#DATE", DateTime.Now.ToString("yyyy-MM-dd"));
sc.Parameters.AddWithValue("#PERIOD", DateTime.Now.ToString("tt"));
sc.Parameters.AddWithValue("#MACHINE", "SMB1");
sc.ExecuteNonQuery();
}
con.Close();
Attempt for Update Code
SqlConnection con = new SqlConnection(MyConnectionString);
string SqlCmdText = "UPDATE SHIFTLOG SET EQUIPMENT='#EQUIPMENT',BATCHNO='#BATCHNO',PRODUCTNO='#PRODUCTNO',STATUS='#STATUS',DATE='2013-09-12',PERIOD='#PERIOD',MACHINE='#MACHINE' WHERE EQUIPMENT='#EQUIPMENT'";
SqlCommand sc = new SqlCommand(SqlCmdText, con);
con.Open();
foreach (DataRow row in smb1.Rows)
{
sc.Parameters.Clear();
sc.Parameters.AddWithValue("#EQUIPMENT", row["EQUIPMENT"]);
sc.Parameters.AddWithValue("#BATCHNO", row["BATCHNO"]);
sc.Parameters.AddWithValue("#PRODUCTNO", row["PRODUCTNO"]);
sc.Parameters.AddWithValue("#STATUS", row["STATUS"]);
sc.Parameters.AddWithValue("#PERIOD", DateTime.Now.ToString("tt"));
sc.Parameters.AddWithValue("#MACHINE", row["MACHINE"]);
sc.ExecuteNonQuery();
}
con.Close();
Thanks for any help.
Remove the single quotes around the parameters.
string SqlCmdText = "UPDATE SHIFTLOG SET EQUIPMENT=#EQUIPMENT,BATCHNO=#BATCHNO,PRODUCTNO=#PRODUCTNO,STATUS=#STATUS,DATE='2013-09-12',PERIOD=#PERIOD,MACHINE=#MACHINE WHERE EQUIPMENT=#EQUIPMENT";
Also, I think the update section for EQUIPMENT=#EQUIPMENT is redundant, as the where clause will not be correct if it has changed. So you could use
string SqlCmdText = "UPDATE SHIFTLOG SET BATCHNO=#BATCHNO,PRODUCTNO=#PRODUCTNO,STATUS=#STATUS,DATE='2013-09-12',PERIOD=#PERIOD,MACHINE=#MACHINE WHERE EQUIPMENT=#EQUIPMENT";
remove the '' in all the parameters in your sql statement
"UPDATE SHIFTLOG SET BATCHNO=#BATCHNO,....... WHERE EQUIPMENT=#EQUIPMENT
if you use quotes all your parameters take as string values, not as SQL parameters
And also you need to use columns with [] like [DATE] if those are reserved keywords
How to deal with SQL column names that look like SQL keywords?

Giving table friendly name in SQL query using MS SQL server

I am using ADO.NET to execute store procedure. The store procedure is having multiple select statement. When I access DataSet, the tables are named as Table1, Table2 and so on. I want to give user friend name to each of these table. I do not want to use Table variable or temp tables in my SQL query. DO I have any other alternatives?
I am using following code to get the dataset
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
try
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["connString"].ConnectionString;
con.Open();
cmd = new SqlCommand("sp_GetData", con);
cmd.Parameters.Add(new SqlParameter("#ParamOne", param));
cmd.CommandType = CommandType.StoredProcedure;
da.SelectCommand = cmd;
da.Fill(ds);
}
I dont want to do this either
da.TableMappings.Add("Table", "MyTable1");
da.TableMappings.Add("Table1", "MyTable2");
da.TableMappings.Add("Table2", "MyTable3");
or this
ds.Tables[0].TableName = "NametbA";
ds.Tables[1].TableName = "NametbB";
Preferably I want to specify the name in the SQL query. The reason I want to use this approach is because, I will pass this dataset as it to a function which will write the table name into a file.
Please provide your suggestions.
Thank you
It is unfortunately not possible to set it automatically. You will have to provide it to the code somehow.
One option would be to change the structure of your results to have twice as many result sets where the odd one is the name and the even is the data:
-- Table name
SELECT 'nameoftable' AS TableName
-- Data
SELECT * FROM ...
c# code (consider it to be psudo code):
myDataSet.Tables[1].TableName = myDataSet.Tables[0]["TableName"].ToString();
Table names in the ADO.Net dataset object are entirely .Net, C# (or vb.net) specific. They have nothing to do with the table names in the SQL query or in the database. Change them in your C# code, by simply writing
myDataSet.Tables[0].TableName 'WhateverYouWant";

Return a table or data set from mysql stored procedure and access in asp.net c#

I want to create a my sql stored procedure with start and end dates as parameters.Based on the start and end dates,procedure should query for each day in between start and end dates.And return the result table or dataset.How to get dataset or table as result set in asp.net c#?
Please help me in sorting out this issue.
Use MySqlDataAdapter
Represents a set of data commands and a database connection that are
used to fill a dataset and update a MySQL database
Example from the Article:
public DataSet SelectRows(DataSet dataset,string connection,string query)
{
MySqlConnection conn = new MySqlConnection(connection);
MySqlDataAdapter adapter = new MySqlDataAdapter();
adapter.SelectCommand = new MySqlCommand(query, conn);
adapter.Fill(dataset);
return dataset;
}
Where SelectCommand could be a select query or Stored Procedure
Parameters: MySqlCommand that is a SQL SELECT statement or stored
procedure and is set as the SelectCommand property of the
MySqlDataAdapter.

Multiple Select result and Linq to Entities

I have an SP which returns an unknown amount of data, here is an example for my query:
MySP:
WHILE (#counter <= #SomeParameter)
BEGIN
Select *
From tblFoo
Where tblFoo.Counter=#counter
#counter=#counter+1
END
In order to store the data efficiently I would like to use DataSet , that will store in each of it's DataTable the result for each of the Selects.
Since my application is based on EF 5 , I tried to call my SP with my dbContext object, here is what I tried to do.
var ds=db.Database.SqlQuery<DataSet>("MySP #counter #SomeParameter", value1,value2);
That doesn't seem to work properly.
I thought of using the classic ADO.NET to solve this matter, and use SqlDataAdapter , But I am not sure how to pass the original Connection reference from the dbContext to the SqlDataAdapter.Connection Property since its not the same type.
Note: The reason I am using DataSet and not Entities Collection at this matter is because the results I am getting from the SP could have different columns and therefore I'm not sure if Entities Collection will do.
I would like to know how to call my SP using Entities (or SqlAdapter) to fill each of the tables at my DataSet with the results of each Select from my SP.
I'm fresh at EF so if I am thinking or doing anything wrong any tip would be appriciated.
You can try with this code - based on SqlDataAdapter class
var connectionString = "...";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
var cmd = new SqlCommand("YourSP", connection);//Adjust your stored procedure name
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#SomeParameter", YourValue));//Adjust your value
adapter.SelectCommand = cmd;
adapter.Fill(dataset);
return dataset;
}

Stored procedure with table type parameter returns data but SqlDataAdapter will not fill

I'm passing a data table to stored procedure (using a table type) to update multiple records at once. SQL profiler shows the stored procedure executing and the records are updated; however, I'm also returning a data set to a SqlDataAdapter. When I execute this in SSMS, I get the results. When I run this in code, rows are not being received.
Any ideas? I'm clueless on why the SqlDataAdapter isn't being filled. Oddly enough, I can get a tables count, but no rows for any tables.
CREATE PROCEDURE [dbo].[SGT_UpdateSGT]
#SGT_GuidelinesTbl As [dbo].[SGT_GuidelinesTbl] Readonly
AS
BEGIN
SET NOCOUNT ON;
update g set Disposition=sgt.Disposition, DispositionDate=GETDATE() from SGTGuidelineRequests g inner join #SGT_GuidelinesTbl sgt on g.pkid=sgt.pkid
select u.ForeName, u.Email, g.*
from #SGT_GuidelinesTbl sgt
inner join SGTGuidelineRequests g on g.pkid=sgt.pkid
inner join Users u on u.NBID=g.SubmittedBy
END
GO
c# code. The session is being filled
DataSet dataSet = new DataSet();
DataTable queue = (DataTable)Session["SGTKeepDeleteQueue"];
using (SqlConnection sqlConnection = new SqlConnection(SQLConn.CWFMO()))
{
sqlConnection.Open();
SqlCommand sqlCommand = new SqlCommand("SGT_UpdateSGT", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter guidelinesTblParam = new SqlParameter();
guidelinesTblParam.ParameterName = "#SGT_GuidelinesTbl";
guidelinesTblParam.SqlDbType = SqlDbType.Structured;
guidelinesTblParam.Value = queue;
sqlCommand.Parameters.Add(guidelinesTblParam);
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand);
sqlDataAdapter.Fill(dataSet);
}
And this is what SQL Profiler receives. When I execute this, I get at least 1 row of data.
declare #p1 dbo.SGT_GuidelinesTbl
insert into #p1 values(1,N'Approved',N'8/23/2012 12:00:00 AM')
exec SGT_UpdateSGT #SGT_GuidelinesTbl=#p1
I changed the name of the SqlDataAdapter and it works. I'm not sure why, I didn't name it that anywhere else in the file. Cleaning the solution didn't solve this either. At least it works.

Categories

Resources