Specific cast is not valid, while retrieving scope_identity - c#

I am getting exception: "Specific cast is not valid", here is the code
con.Open();
string insertQuery = #"Insert into Tender (Name, Name1, Name2) values ('Val1','Val2','Val3');Select Scope_Identity();";
SqlCommand cmd = new SqlCommand(insertQuery, con);
cmd.ExecuteNonQuery();
tenderId = (int)cmd.ExecuteScalar();

In the interests of completeness, there are three issues with your code sample.
1) You are executing your query twice by calling ExecuteNonQuery and ExecuteScalar. As a result, you will be inserting two records into your table each time this function runs. Your SQL, while being two distinct statements, will run together and therefore you only need the call to ExecuteScalar.
2) Scope_Identity() returns a decimal. You can either use Convert.ToInt32 on the result of your query, or you can cast the return value to decimal and then to int.
3) Be sure to wrap your connection and command objects in using statements so they are properly disposed.
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(sql, connection))
{
connection.Open();
int tenderId = (int)(decimal)command.ExecuteScalar();
}
}

Try this:-
con.Open();
string insertQuery = #"Insert into Tender (Name, Name1, Name2) values ('Val1','Val2','Val3');Select Scope_Identity();";
SqlCommand cmd = new SqlCommand(insertQuery, con);
tenderId = Convert.ToInt32(cmd.ExecuteScalar());
EDIT
It should be this as it is correctly pointed out that scope_identity() returns a numeric(38,0) :-
tenderId = Convert.ToInt32(cmd.ExecuteScalar());
Note: You still need to remove the:-
cmd.ExecuteNonQuery();

Test the following first:
object id = cmd.ExcuteScalar()
Set a break point and have a look at the type of id. It is probably a Decimal and cannot directly be casted to int.

it needs Convert.ToInt32(cmd.ExecuteScalar());

Related

Creating table at runtime and storing data in it

I want to create a table at the runtime and store information into it.
Below the code which i tried.
SqlConnection con = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True;");
con.Open();
String crt = "CREATE TABLE trail (Name Varchar(50) NOT NULL, Sex Varchar(50) NOT NULL)";
SqlCommand cov = new SqlCommand(crt, con);
cov.ExecuteReader();
String add = "Insert into trail value (#nam,#sex)";
SqlCommand cmd = new SqlCommand(add,con);
cmd.Parameters.AddWithValue("#nam",TextBox1.Text);
cmd.Parameters.AddWithValue("#sex", RbtGender.SelectedValue);
cmd.ExecuteReader();
con.Close();
Response.Redirect("Success.aspx");
There is no point to use ExecuteReader with CREATE statement. It does not return any data anyway (and it retursn SqlDataReader, it is not a void method). Use ExecuteNonQuery instead to execute your queries. Same with INSERT statement also.
And it is values not value. Take a look at INSERT (Transact-SQL) syntax.
Also use using statement to dispose your SqlConnection and SqlCommand like;
using(SqlConnection con = new SqlConnection(connString))
using(SqlCommand cov = con.CreateCommand())
{
//
}
Don't use AddWithValue by the way. Use one of Add overloads. This method has some problems.
Read: http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
I wrote this code before
cmd.Connection = con;
Then I wrote this
cmd.ExecuteReader();

Clear a database table

I'm using the following code to clear a database table:
public void ClearAll()
{
SqlCommand info = new SqlCommand();
info.Connection = con;
info.CommandType = CommandType.Text;
info.CommandText = "edit_.Clear()";
}
Why does it not work?
With a sql command you usually pass a TSQL statement to execute. Try something more like,
SqlConnection con = new SqlConnection(ConfigurationSettings.AppSettings["con"]);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "DELETE FROM Edit_ ";
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
You need to execute the command, so info.Execute() or info.ExecuteNonQuery().
Try info.CommandText='DELETE FROM edit_';
The CommandText attribute is the TSQL statement(s) that are run.
You also need a info.ExecuteNonQuery();
1) Decide whether to use a TRUNCATE or a DELETE statement
Use TRUNCATE to reset the table with all its records and indexes:
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "TRUNCATE TABLE [dbo].[Edit_]";
command.ExecuteNonQuery();
}
Use DELETE to delete all records but do not reset identity/auto increment columns
using (SqlCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "DELETE FROM [dbo].[Edit_]";
command.ExecuteNonQuery();
}
Note that there is another line in the samples. In the sample you provided the SQL statement never gets executed until you call one of the ExecuteXXX() methods like ExecuteNonQuery().
2) Make sure you use the correct object (are you sure its called edit_?). I recommend to put the schema before the table name as in the examples before.
3) Make sure you use the correct connection string. Maybe everything worked fine on the production environment ;-)

Run stored procedure in C#, pass parameters and capture the output result

This is a simple task that I want to acheive but ASP.NET makes it quite difficult, next to impossible. I followed this question
Running a Stored Procedure in C# Button but found out ExecuteNonQuery does not return the output from query.
I tried this other approach but can't seem to pass the paremeters in this way
SqlConnection myConnection = new SqlConnection(myconnectionString);
SqlCommand myCommand = new SqlCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "usp_GetCustomer";
myCommand.SelectParameter <-- does not exist
Can someone write this simple code, how can I implement it? Basically I am passing a #username and #month (both character strings) to stored procedure and it returns a number that I want to capture and assign to a label control.
Thank you
The output from my query is this. It runs a complex query, create a temp table and then it runs
select ##rowcount
and I am capturing that.
Don't use SqlCommand.ExecuteNonQuery() if you actually want data from a result set.
Make sure your procedure uses set nocount on
Then use SqlCommand.ExecuteScalar()
return (int)myCommand.ExecuteScalar(); // value of select ##rowcount
Edit: As for your parameters:
myCommand.Parameters.AddWithValue("#username","jsmith");
myCommand.Parameters.AddWithValue("#month","January");
I prefer using linq-to-sql to handle stored procedures. Create a linq-to-sql model, where you add the SP you want to call. This will expose the SP as a function on the generated data context, where the parameters are ordinary C# functions. The returned values will be exposed as a collection of C# objects.
If you have multiple results from the SP things get a bit more complicated, but still quite straight forward.
Use the Parameters collection of the command to set the parameters, and the ExecuteScalar to run the query and get the value from the single-row single-column result.
Use using blocks to make sure that the connection and command are closed and disposed properly in any situation. Note that you have to provide the connection to the command object:
int result;
using (SqlConnection connection = new SqlConnection(myconnectionString)) {
using (SqlCommand command = new SqlCommand(connection)) {
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "usp_GetCustomer";
command.Parameters.Add("#username", SqlDbType.VarChar).Value = username;
command.Parameters.Add("#month", SqlDbType.VarChar).Value = month;
connection.Open();
result = (int)myCommand.ExecuteScalar();
}
}
using(SqlConnection myConnection = new SqlConnection(myconnectionString))
{
SqlCommand myCommand = new SqlCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "usp_GetCustomer";
myCommand.Parameters.Add("#USER_NAME", SqlDbType.VarChar).Value = sUserName; // user name that you pass to stored procedure
myCommand.Parameters.Add("#Month", SqlDbType.VarChar).Value = iMonth; // Month that you pass to stored procedure
// to get return value from stored procedure
myCommand.Parameters.Add("#ReturnValue", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
myConnection .Open();
myCommand.ExecuteScalar();
// Returnvalue from stored procedure
return Convert.ToInt32(command.Parameters["#ReturnValue"].Value);
}
Simple code to get return value from SQL Server
SqlConnection myConnection = new SqlConnection(myconnectionString);
SqlCommand myCommand = new SqlCommand();
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.CommandText = "usp_GetCustomer";
myCommand.Parameters.Add("#USER_NAME", SqlDbType.VarChar).Value = sUserName; // user name that you pass to the stored procedure
myCommand.Parameters.Add("#Month", SqlDbType.VarChar).Value = iMonth; //Month that you pass to the stored procedure
// to get return value from the stored procedure
myCommand.Parameters.Add("#ReturnValue", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
myConnection .Open();
myCommand.ExecuteScalar();
// Returnvalue from the stored procedure
int iReturnValue = Convert.ToInt32(command.Parameters["#ReturnValue"].Value);

ExecuteScalar always returns null when calling a scalar-valued function

Why does this return null?
//seedDate is set to DateTime.Now; con is initialized and open. Not a problem with that
using (SqlCommand command = new SqlCommand("fn_last_business_date", con))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#seed_date", seedDate);//#seed_date is the param name
object res = command.ExecuteScalar(); //res is always null
}
But when I call this directly in the DB as follows:
select dbo.fn_last_business_date('8/3/2011 3:01:21 PM')
returns '2011-08-03 15:01:21.000'
which is the result I expect to see when I call it from code
Why, why, why?
Why does everyone insist on the select syntax?..
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("calendar.CropTime", c))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#RETURN_VALUE", SqlDbType.DateTime).Direction = ParameterDirection.ReturnValue;
cmd.Parameters.AddWithValue("#d", DateTime.Now);
cmd.ExecuteNonQuery();
textBox1.Text = cmd.Parameters["#RETURN_VALUE"].Value.ToString();
}
try:
using (SqlCommand command = new SqlCommand("select dbo.fn_last_business_date(#seed_date)", con))
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("#seed_date", seedDate);//#seed_date is the param name
object res = command.ExecuteScalar(); //res is always null
}
You are actually getting an error that isn't being caught. You don't call scalar udfs like you call stored procedures.
Either wrap the udf in a stored proc, or change syntax. I'm not actually sure what that is because it isn't common...
Ah ha: see these questions:
How to use SQL user defined functions in .NET?
Calling user defined functions in Entity Framework 4

SQL Server and C#: get last inserted id

public static void CreateSocialGroup(string FBUID)
{
string query = "INSERT INTO SocialGroup (created_by_fbuid) VALUES (#FBUID); SELECT ##IDENTITY AS LastID";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#FBUID", FBUID);
connection.Open();
command.ExecuteNonQuery();
}
}
Is this the right way to do it? And how do i get LastID in to a variable? Thanks
OUTPUT clause?
string query = "INSERT INTO SocialGroup (created_by_fbuid)
OUTPUT INSERTED.IDCol --use real column here
VALUES (#FBUID)";
...
int lastId = (int)command.ExecuteScalar();
You can use ExecuteScalar to get the last value from a Sqlcommand.
The scope_identity() function is safer than ##identity.
If your server supports the OUTPUT clause you could try it with this one:
public static void CreateSocialGroup(string FBUID)
{
string query = "INSERT INTO SocialGroup (created_by_fbuid) OUTPUT INSERTED.IDENTITYCOL VALUES (#FBUID)";
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#FBUID", FBUID);
connection.Open();
var _id = command.ExecuteScalar();
}
}
Personally, I would re-write your code to use Parameters. You could either use an InputOutput parameter or an Output Parameter. However, using a Return Value in your SQL would also work.
Full examples on this can be found on MSDN.
I would also use Scope_Identity() rather than ##Identity this will ensure that you will reveice the ID that relates to the current transaction. Details on Scope_Identity can be found here.
U can try ExecuteScalar for getting the LastID value.
I'd recommend to use a stored procedure to do this. You can give it an OUTPUT parameter which you can use to return the id value back to your app.
cmd = new SqlCommand("Insert into table values (1,2,3); SELECT SCOPE_IDENTITY()", conn);
lastRecord = cmd.ExecuteScalar().ToString();
Use Stored Procedure only for the queries and use SCOPE_IDENTITY to get max value.
SqlCommand command = new SqlCommand("select max(id) from SocialGroup ", connection);
int lastId = (int)command.ExecuteScalar();

Categories

Resources