What is the wrong with Scope_Identity? - c#

I tried milions of methods to make scope identity work. It is just returns __Page !!
Query = "INSERT INTO seekers(name,sname,lname,status,gender,dob,major,experince,email,password,phone,valid,city) values(#name,#sname,#lname,#status,#gender,#dob,#major,#exp,#email,#password,#phone,0,#city);SELECT SCOPE_IDENTITY();";
// setting up command definition
Command = new SqlCommand(Query, Connection);
// setting up command parameters
Command.Parameters.AddWithValue("email", txt_email.Text);
Command.Parameters.AddWithValue("gender", lst_gender.SelectedValue);
Command.Parameters.AddWithValue("status", lst_status.SelectedValue);
Command.Parameters.AddWithValue("phone", long.Parse("968" + txt_phone.Text));
Command.Parameters.AddWithValue("password", txt_password.Text);
Command.Parameters.AddWithValue("exp", lst_exp.SelectedValue);
Command.Parameters.AddWithValue("city", lst_exp.SelectedValue);
Command.Parameters.AddWithValue("major", lst_major.SelectedValue);
Command.Parameters.AddWithValue("name", txt_name.Text);
Command.Parameters.AddWithValue("sname", txt_sname.Text);
Command.Parameters.AddWithValue("lname", txt_lname.Text);
Command.Parameters.AddWithValue("dob", cld_birth.SelectedDate);
int ID = (int)Command.ExecuteScalar();

Try Out Parameter as follow...
Query = "INSERT INTO seekers(name,sname,lname,status,gender,dob,major,experince,email,password,phone,valid,city) values(#name,#sname,#lname,#status,#gender,#dob,#major,#exp,#email,#password,#phone,0,#city);SET #ID=SCOPE_IDENTITY();"
//Your Parameters..
SqlParameter ID=new SqlParameter();
ID.Name="#ID";
ID.Direction=ParameterDirection.Output;
Command.Parameters.Add(ID);
Command.ExecuteNonQuery();
int id=(int)ID.Value;
or
Tryb to Cast Output as follow...
Query = "INSERT INTO seekers(name,sname,lname,status,gender,dob,major,experince,email,password,phone,valid,city) values(#name,#sname,#lname,#status,#gender,#dob,#major,#exp,#email,#password,#phone,0,#city);SELECT CAST(scope_identity() AS int);"
int id= (Int32)Command.ExecuteScalar();

use set nocount off and try
As First execute statement is insert the returned value is number of records effected

SCOPE_IDENTITY will return a decimal, try:
int ID = (int) (decimal) Command.ExecuteScalar();
It's not very clear what you mean by:
It is just returns __Page !!
Presumably the posted code is throwing an exception, and that's resulting in some higher level code doing whatever it is you mean by "... returns __Page".
If you look at the exception details, you'll find more about what happened: which I suspect is an InvalidCastException because you're trying to cast the object returned by Command.ExecuteScalar (a boxed decimal) to an int.

Related

Getting string value from SQL function inside a CLR

Attempted (non-working) solution included below.
I have an sql function called get_parameter which looks in a table for a given string and returns the associated string:
declare #str varchar(20);
set #str = dbo.get_parameter('filecount')
print #str
It works! I run this and it prints out exactly what it should print. In this case, the parameter is the string '44'.
Now I want to run a C# CLR. But I want the CLR to be able to look up the parameter that it needs.
[SqlFunction(DataAccess = DataAccessKind.Read)]
public static string Import_TestFunc()
{
using (SqlConnection conn = new SqlConnection("context connection=true"))
{
SqlCommand command = new SqlCommand();
command.Connection = conn;
conn.Open();
// Find out how many files DSAMS processing requires.
command.CommandText = #"EXEC get_parameter 'filecount' ";
string cnt = (string)command.ExecuteScalar();
if (String.IsNullOrEmpty(cnt))
{
return "'cnt' not found."; // error return code. can't find this parameter.
}
return cnt;
}
}
However, this does not work. It constantly thinks the value for cnt is null (or empty) when it returns from get_parameter.
As requested, the code for get_parameter
ALTER FUNCTION [dbo].[get_parameter]
(
#SelectedParameterName nvarchar(max)
)
RETURNS nvarchar(max)
AS
BEGIN
DECLARE #result nvarchar(max);
SET #result = (SELECT ParameterValue from Parameters WHERE ParameterName = #SelectedParameterName);
RETURN isnull(#result,'');
END
I have tried the solution as per Mike Dinescu below, but it problem is that the call to ExecuteScalar() still returns a null. I did try to change to CommandType.Text and in that case I get the following interesting message:
A .NET Framework error occurred during execution of user-defined routine or aggregate "Import_TestFunc":
System.Data.SqlClient.SqlException: Procedure or function 'get_parameter' expects parameter '#SelectedParameterName', which was not supplied.
This is interesting, because I'm looking right at where it adds the parameter #SelectedParameterName.
command.Parameters.Add(new SqlParameter("#SelectedParameterName", SqlDbType.NVarChar )).Value = "filecount";
If you want to execute a user-defined function, or stored procedure from .NET, you should set the CommandType to CommandType.StoredProcedure, and add the needed parameters to the command object before executing the command.
command.CommandType = CommandType.StoredProcedure;
command.CommandText = #"dbo.get_parameter";
// here you add the paramters needed for your procedure/function
// in your case it will be just one (make sure you add the correct name for you function)
command.Parameters.Add(new SqlParamter("SelectedParameterName", SqlDbType.NVarChar));
command.Prepare();
command.Parameters[0].Value = "filecount";
string cnt = (string)command.ExecuteScalar();

Multi-statement SQL transaction failing at null parameter

I have a multi-statement SQL query that takes place within a SqlTransaction as follows:
string sName = "";
string sNumber = "";
string sFirstName = "";
string sqlQuery1 = #"INSERT INTO myTable(Name, Number) VALUES (#_Name, #_Number)";
string sqlQuery2 = #"INSERT INTO myOtherTable( ID, FirstName) VALUES ( #_ID, #_First )";
SqlConnection conn = new SqlConn(***);
conn.Open();
SqlTransaction transaction;
SqlCommand command1 = new SqlCommand(sqlQuery1, conn, transaction);
SqlCommand command2 = new SqlCommand(sqlQuery2, conn, transaction);
command1.Parameters.Add("#_Name", SqlDbType.NVarChar, 255).Value = sName;
command1.Parameters.Add("#_Number", SqlDbType.NVarChar, 255).Value = sNumber;
int? returnedID = (int?)command1.ExecuteScalar();
command2.Parameters.Add("#_ID", SqlDbType.Int).Value = (int)returnedID; <--- Error
command2.Parameters.Add("#_First", SqlDbType.NVarChar, 255).Value = sFirstName;
command2.ExecuteNonQuery();
transaction.Commit();
At the line I marked as an error, I get an error during execution about "The parameterized query expects the parameter #_ID which was not supplied.
Now, assuming I have no typos while simplifying my code to this example, why am I receiving a null value in returnedID for a properly executed statement? When I just run the statement on its own in a query, I get no errors and it returns successful. Why null when running it in this transaction? Thanks!
Edit: I purposely left off a try{} catch from this as it wasn't relevant to the question I had. Otherwise, I just forgot about the IDENTITY_SCOPE() that I needed in the Insert query since there would otherwise be no return value.
ExecuteScalar returns the first column of the first row in the result set returned by the query (MSDN). Your statement is an insert, it does not return any result set.
The easiest way to fix your example is to run all queries in one command and use SCOPE_IDENTITY to get the inserted id.
string sqlQuery =
#"INSERT INTO myTable(Name, Number) VALUES (#_Name, #_Number);
INSERT INTO myOtherTable( ID, FirstName) VALUES ( SCOPE_IDENTITY(), #_First )";
Since insert statements don't return a value, ExecuteScalar() can't return the identity as you want. You can combine the insert with a select scope_identity() as in the example on the ExecuteScalar() documentation to get the functionality I think you're expecting.
You seem to assume that INSERT INTO myTable(Name, Number) VALUES (#_Name, #_Number) is going to return the ID of the inserted row; why would you think that? The assumption is incorrect, which is why you're getting a null value back from ExecuteScalar.
ExecuteScalar returns null if the command's result set is empty, and the result set of an INSERT statement is in fact empty, unless you include an OUTPUT clause.

How to get string value from an OracleParameter object when using ExecuteNonQuery

As the code Shows below, I want to insert a row into a database table (oracle 11) and return a String-Value of the inserted row.
using (OracleCommand cmd = con.CreateCommand()) {
cmd.CommandText = "insert into foo values('foo','bar') returning idString into :lastIdParam";
cmd.Parameters.Add(new OracleParameter("lastIdParam", OracleDbType.Varchar2), ParameterDirection.ReturnValue);
cmd.ExecuteNonQuery(); // returning 1 (insert row successfully)
var result = cmd.Parameters["lastIdParam"].Value.ToString(); // == String.Empty
}
Debugging shows that lastIdParam.Value's value = Empty.String:
My Problem is, that I'm not getting the return string into my return-parameter but it will work when returning an integer value (like sequence no of inserted id). Cast Problem? ...?
The idString is filled if running the Statement directly (or if I just do something like returning 'ABC' into :myOutputParameter
Any ideas how to retrieve a string after inserting row?
Have you tried setting a size for the parameter? The default size is 0.
new OracleParameter("lastIdParam", OracleDbType.Varchar2, 128)
The idString is an expression which has no value in your context, unless it is a column name in your table. Therefore, it is epected to be empty. You may change your query like the example below and see what happens.
cmd.CommandText = "insert into foo values('foo','bar') returning hereYouHaveToUseAColumnFromTheFooTable into :lastIdParam";

Issue with SqlCommand Parameters

When I execute the following query in SSMS I get the expected result i.e. '1'
SELECT TSID
FROM tblTimesheets
WHERE TSUser = 'PJW' AND TSDate = '2012-01-18';
However, when the SqlCommand is produced by the code in my application the ExecuteScalar fails (it simply causes the method to exit with no error message).
public int GetID(string paramUser, DateTime paramDate)
{
string strSql = "SELECT TSID " +
"FROM tblTimesheets " +
"WHERE TSUser = #TSUser AND TSDate = #TSDate;";
string strConnection = BuildConnectionString();
SqlConnection linkToDB = new SqlConnection(strConnection);
linkToDB.Open();
SqlCommand sqlCom = new SqlCommand(strSql, linkToDB);
sqlCom.Parameters.Add("#TSUser", SqlDbType.Text);
sqlCom.Parameters.Add("#TSDate", SqlDbType.Date);
sqlCom.Parameters["#TSUser"].Value = paramUser;
sqlCom.Parameters["#TSDate"].Value = paramDate;
int intResult = (Int32)sqlCom.ExecuteScalar();
linkToDB.Close();
return intResult;
}
I've stepped through the code and can confirm the parameters are PJW and 2012-01-18 as required, but the ExecuteScalar returns any data, which I know should be there based on my comparable query in SSMS.
Please assist.
Instead of SqlDbType.Text try any of the following, depending on the type of the column:
SqlDbType.VarChar
SqlDbType.NVarChar
SqlDbType.NText
SqlDbType.NChar
SqlDbType.Char
When the parameter is of DB type date, it is a good practice to defensively strip the time part on setting the parameter, like this:
sqlCom.Parameters.Add("#TSDate", SqlDbType.Date);
sqlCom.Parameters["#TSDate"].Value = paramDate.Date;
Please let me know if this does not help, and I'll remove my answer.
You say the ExecuteScalar fails with no error message. Wrap your code in a try-catch block to make sure any exceptions that ExecuteScalar() might be throwing are caught.
Other than that try and do as others have suggested and view the SQL produced using SQL Profiler, then run that SQL in SSMS to compare results.
SELECT TSID
FROM tblTimesheets
WHERE TSUser = 'PJW' AND TSDate = '2012-01-18';
Here U r passing the exact date as parameter
Where as while passing the parameter in to the stored procedure you are passing
"DateTime paramDate"
A date time variable
May be you need to parse to exact date format as supported by the stored procedure
i.e you need to format the paramDate variable to 'YYYY-mm-DD'
I am not sure.. Try it.. and reply if it helps or not !

Get the value of a stored procedure with SQL Server Express

I have a stored procedure which checks the username and the password from a SQL Server database table. The stored procedure returns 1 if the username and the password is correct or returns 0. Here is the code. Could you please tell me how can I get the 1 or 0 pls? The rdr.toString does not work.
SqlCommand cmd = new SqlCommand("sp_IsValidLogon", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#Username", textBox1.Text));
cmd.Parameters.Add(new SqlParameter("#Password", textBox2.Text));
rdr = cmd.ExecuteReader();
label1.Text = rdr.ToString();
Try this
label1.Text=cmd.ExecuteScalar().ToString();
instead of this:
rdr = cmd.ExecuteReader();
label1.Text=rdr.ToString();
This should work fine:
if (rdr.Read())
label1.Text = rdr[0].ToString();
You first must call .Read() method once to "initialize" the data reader then take the value of the first field - assuming that's all your stored procedure returns, it will work.
You can do all of this without Reader though:
label1.Text = cmd.ExecuteScalar().ToString();
The ExecuteScalar() exists exactly for this purpose - read one single value from database.
If you are returning it from the sproc using the RETURN statement, then you need to add another INTEGER parameter to the SqlCommand in your .NET code with a ParameterDirection = ParameterDirection.ReturnValue.
Then after executing the sproc, just retrieve the value of that param from the SqlCommand.
Use ExecuteScalar insted. Example here:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx
I assume that your stored procedure has an actual "return" statement that returns 0 or 1. in that case, add a sqlparameter to your command with ParameterDirection set to "ReturnValue".
ExecuteNonQuery should work fine in this case.
ExecuteScalar returns the value of the first column of the first row. If you are not "returning" the 0 or 1 from the stored procedure as a query result, then that is not what you want.
However, without seeing your stored procedure code I can't tell which of the two approaches is the one you need.

Categories

Resources