SQL Out parameter received as null while passing from C# - c#

I am trying to populate a value in an out parameter but it is returned as null from the stored procedure.
But it works fine when I try to run the query through SSMS.
Stored procedure:
CREATE PROCEDURE [dbo].[USP_ABCD]
(#signal_xml AS NVARCHAR(MAX) OUT) -- this parameter includes the result in case
AS
BEGIN
DECLARE #signal_data XML
SET #signal_data = cast(#signal_xml as XML)
INSERT INTO DBLog
VALUES ('USP_ABCD', 'test', #signal_xml, ERROR_MESSAGE(), GETUTCDATE())
SET #signal_xml = 'ABCD';
END
C# code calling this stored procedure:
private static void runSP()
{
try
{
var temp = File.ReadAllText(#"abcd\TEST1.txt");
var conStr = System.Configuration.ConfigurationManager.ConnectionStrings["test"].ConnectionString;
using (SqlConnection connection = new SqlConnection(conStr))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
// Setup the command to execute the stored procedure.
command.CommandText = "dbo.USP_ABCD";
command.CommandType = CommandType.StoredProcedure;
// Set up the output parameter to retrieve the summary.
SqlParameter paramSignalXml = new SqlParameter("#signal_xml", SqlDbType.NVarChar, -1);
paramSignalXml.Direction = ParameterDirection.Output;
paramSignalXml.Value = temp;
command.Parameters.Add(paramSignalXml);
// Execute the stored procedure.
command.ExecuteNonQuery();
Console.WriteLine((String)(paramSignalXml.Value));
var retValue = (String)(paramSignalXml.Value);
connection.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Is it not possible to pass value to output parameter or am I missing something? Can someone help me with this? Thanks in advance.

Related

Integer out parameter null issue in ADO.NET while calling through procedure

I'm facing one issue when I try to get output value from SQL Server stored procedure which is of INT type, then I'm getting NULL value ☹ .
Here is the stored procedure:
CREATE PROCEDURE dbo.NULLISSUE
#input VARCHAR(10),
#output INT = 0 OUTPUT
AS
BEGIN
IF #input >= '1'
BEGIN
SET #output = #output + 1
RETURN(0)
END
END
Here is the .NET code:
using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand())
{
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.NULLISSUE";
command.Parameters.Clear();
command.Parameters.AddWithValue("#input", "1");
command.Parameters.AddWithValue("#output", SqlDbType.Int);
command.Parameters["#output"].Value = 0;
command.Parameters["#output"].Direction = ParameterDirection.Output;
command.CommandTimeout = 3000;
connection.Open();
command.ExecuteNonQuery();
connection.Close();
Console.WriteLine(command.Parameters["#output"].Value);
//null value ?
Console.ReadLine();
}
}
I have a fix by doing ISNULL(#output, 0) in the procedure but not sure why it can be done on the .NET side and why ADO.NET not passing/setting/initializing OUTPUT parameter = 0.
Thanks in advance.
#output must be ParameterDirection.InputOutput if you want it to use the initial value set within the client.
Currently as it's ParameterDirection.Output the value is ignored, it defaults to NULL within the procedure and NULL + anything results in a NULL.

A SqlParameter with parameter name '#name' is not contained by this SqlParameterCollection function

I am trying to return a value from the code below but I am getting an error that says:
A SqlParameter with parameter name '#vRESULT' is not contained by this SqlParameterCollection
c# Code:
public int userLogin()
{
string connStr = ConfigurationManager.ConnectionStrings["conn"].ToString();
string cmdStr = #"fucn_LOg";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
try
{
conn.Open();
cmd.CommandText = cmdStr;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters[":vResult"].Direction = ParameterDirection.Output;
cmd.Parameters.Add(new SqlParameter("param1", SqlDbType.VarChar)).Value = TB_1.Text;
cmd.Parameters.Add(new SqlParameter("param2", SqlDbType.VarChar)).Value = TB_2.Text;
cmd.ExecuteScalar();
return Int32.Parse(cmd.Parameters[":vResult"].Value.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return -1;
}
}
}
the sql server function code below with returning parameter DECLARE #vResult int
CREATE FUNCTION USER_LOGIN(#USER_NAME VARCHAR(60),
#PWD VARCHAR(60))
RETURNS INT
AS BEGIN
DECLARE #vResult int
SELECT #vRESULT=COUNT(*)
FROM OPER
WHERE UPPER(UNAM)=UPPER(#USER_NAME)
AND PSW=#PWD
IF #vResult=1
SET #vResult=1
ELSE
SET #vResult= -1
RETURN #vResult
END
Just Get result from Stroed Procedure like this:
var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());
This gets first and Only result from Stored Procedure.
Also recommend simplify your code Like this:
public int userLogin() {
string connStr = ConfigurationManager.ConnectionStrings["conn"].ToString();
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand("fucn_LOg", conn)) {
try {
cmd.Connection.Open();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#param1", TB_1.Text);
cmd.Parameters.AddWithValue("#param2", TB_2.Text);
var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());
}
catch (Exception ex) {
MessageBox.Show(ex.ToString());
return -1;
}
finally {
if (cmd.Connection.State != ConnectionState.Closed) cmd.Connection.Close();
}
}
}
And your Stored procedure should looks Like this:
CREATE PROCEDURE fucn_LOg
(
#param1 nvarchar(max),
#param2 nvarchar(max)
)
AS
BEGIN
SET NOCOUNT ON;
if (exists(select * from tbUsers where flLogin = #param1 and flPassword = #param2))
begin
return 1;
end
else
begin
return 0;
end
END
GO
OR
CREATE PROCEDURE fucn_LOg
(
#param1 nvarchar(max),
#param2 nvarchar(max)
)
AS
BEGIN
SET NOCOUNT ON;
select COUNT(*) from tbUsers where flLogin = #param1 and flPassword = #param2
END
GO
Several problems.
First, you don't need the cmd.Parameters.Clear();, as you just establish a new cmd.
Second, use # for SQL Server parameters.
Third, a parameter named vResult is not set, so cmd.Parameters[":vResult"].Direction is invalid. You need to assign its type and value. Make sure your stored procedure has this parameter set with correct SQL data type.
Lastly, I guess you return the vResult in your stored procedure like select #vResult; so make it a new vResult = function(vResult). But no, it is not how SQL Server work. It won't change your input parameter even though you return your #vResult. While, ExecuteScaler does. So, simply get your result back by var result = cmd.ExecuteScalar();.
You are getting data from a stored procedure, not getting back the parameter you sent. That's the supposed correct way.
conn.Open();
cmd.CommandText = cmdStr;
cmd.CommandType = CommandType.StoredProcedure;
//Base on sql you provided, it is no need for this part.
/*
SqlParameter vResult = new SqlParameter();
vResult.ParameterName = "#vResult";
vResult.Direction = ParameterDirection.Output;
vResult.SqlDbType = System.Data.SqlDbType.???;
vResult.Value = ???;
cmd.Parameters.Add(vResult);
*/
cmd.Parameters.Add("#param1", SqlDbType.VarChar).Value = TB_1.Text;
cmd.Parameters.Add("#param2", SqlDbType.VarChar).Value = TB_2.Text;
var result = cmd.ExecuteScalar();
return Int32.Parse(result.ToString());
This is hard to debug without the SP, but a couple of things jump out.
First, you need to use the '#' character as a prefix for your parameter names, not a colon.
Second, you should define your output parameter like this:
SqlParameter outputParam = new SqlParameter("#vResult", SqlDbType.Int);
outputParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(outputParam);

ExecuteNonQuery with return value in a stored procedure [duplicate]

I am trying to call a stored procedure from my C# windows application. The stored procedure is running on a local instance of SQL Server 2008. I am able to call the stored procedure but I am not able to retrieve the value back from the stored procedure. This stored procedure is supposed to return the next number in the sequence. I have done research online and all the sites I've seen have pointed to this solution working.
Stored procedure code:
ALTER procedure [dbo].[usp_GetNewSeqVal]
#SeqName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update AllSequences
set #NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = #SeqName
if ##rowcount = 0 begin
print 'Sequence does not exist'
return
end
return #NewSeqVal
end
Code calling the stored procedure:
SqlConnection conn = new SqlConnection(getConnectionString());
conn.Open();
SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter();
param = cmd.Parameters.Add("#SeqName", SqlDbType.NVarChar);
param.Direction = ParameterDirection.Input;
param.Value = "SeqName";
SqlDataReader reader = cmd.ExecuteReader();
I have also tried using a DataSet to retrieve the return value with the same result. What am I missing to get
the return value from my stored procedure? If more information is needed, please let me know.
You need to add a ReturnValue-direction parameter to the command:
using (SqlConnection conn = new SqlConnection(getConnectionString()))
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = parameterStatement.getQuery();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");
// #ReturnVal could be any name
var returnParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
Setting the parameter's direction to ParameterDirection.ReturnValue instructs the SqlCommand to declare it as a variable and assign the stored procedure's return value to it (exec #ReturnValue = spMyProcedure...), exactly like you would write it in SQL.
I know this is old, but i stumbled on it with Google.
If you have a return value in your stored procedure say "Return 1" - not using output parameters.
You can do the following - "#RETURN_VALUE" is silently added to every command object. NO NEED TO EXPLICITLY ADD
cmd.ExecuteNonQuery();
rtn = (int)cmd.Parameters["#RETURN_VALUE"].Value;
The version of EnterpriseLibrary on my machine had other parameters.
This was working:
SqlParameter retval = new SqlParameter("#ReturnValue", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
db.ExecuteNonQuery(cmd);
object o = cmd.Parameters["#ReturnValue"].Value;
I had a similar problem with the SP call returning an error that an expected parameter was not included. My code was as follows.
Stored Procedure:
#Result int OUTPUT
And C#:
SqlParameter result = cmd.Parameters.Add(new SqlParameter("#Result", DbType.Int32));
result.Direction = ParameterDirection.ReturnValue;
In troubleshooting, I realized that the stored procedure was ACTUALLY looking for a direction of "InputOutput" so the following change fixed the problem.
r
Result.Direction = ParameterDirection.InputOutput;
This is a very short sample of returning a single value from a procedure:
SQL:
CREATE PROCEDURE [dbo].[MakeDouble] #InpVal int AS BEGIN
SELECT #InpVal * 2; RETURN 0;
END
C#-code:
int inpVal = 11;
string retVal = "?";
using (var sqlCon = new SqlConnection(
"Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
{
sqlCon.Open();
retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";",
sqlCon).ExecuteScalar().ToString();
sqlCon.Close();
}
Debug.Print(inpVal + " * 2 = " + retVal);
//> 11 * 2 = 22
ExecuteScalar(); will work, but an output parameter would be a superior solution.
You can try using an output parameter. http://msdn.microsoft.com/en-us/library/ms378108.aspx
Or if you're using EnterpriseLibrary rather than standard ADO.NET...
Database db = DatabaseFactory.CreateDatabase();
using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal"))
{
db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue");
db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);
db.ExecuteNonQuery(cmd);
var result = (int)cmd.Parameters["RetVal"].Value;
}
I see the other one is closed. So basically here's the rough of my code. I think you are missing the string cmd comment. For example if my store procedure is call:DBO.Test. I would need to write cmd="DBO.test". Then do command type equal to store procedure, and blah blah blah
Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;

Sql Server Stored Procedure not executing from MVC

I am trying to execute a stored procedure in my Sql Server Database from an Asp.Net MVC project. I have set it up in a way that I can use it for testing purposes, which is why the variable "procedureTest" is a constant value (I know that "2044" is an existing record in my database). I will change this once I accomplish a successful run. Also, I know that my stored procedure works because I have executed it in Sql Server Management Studio successfully. The procedure has the task of adding ID from one table to another, but I have yet to see it appear in this table. I am not receiving an error in my catch block so I am kind of lost at the moment. I could definitely use your help.
try
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
int procedureTest = 2044;
var command = new SqlCommand("SELECT ID FROM Images WHERE ID = #id", connection);
var paramDate = new SqlParameter("#id", procedureTest);
command.Parameters.Add(paramDate);
var reader = command.ExecuteReader();
while (reader.Read())
{
var storedProcCommand = new SqlCommand("EXEC addToNotificationTable #ID", connection);
var paramId = new SqlParameter("#ID", reader.GetInt32(0));
storedProcCommand.Parameters.Add(paramId);
command.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
string exceptionCause = String.Format("An error occurred: '{0}'", e);
System.IO.File.WriteAllText(#"C:\Users\Nathan\Documents\Visual Studio 2013\Projects\MVCImageUpload\uploads\exception.txt", exceptionCause);
}
Stored Procedure:
CREATE PROCEDURE addToNotificationTable #ID int
AS
Insert NotificationTable (ID)
SELECT ID
FROM Images
Where ID = #ID
Change you code like this
while (reader.Read())
{
var storedProcCommand = new SqlCommand("EXEC addToNotificationTable #ID", connection);
var paramId = new SqlParameter("#ID", reader.GetInt32(0));
storedProcCommand.Parameters.Add(paramId);
storedProcCommand.ExecuteNonQuery();
}
First of all, you missed to specify the command type. Also using EXEC in SqlCommand is not a proper way.
Please try with the below code
while (reader.Read())
{
using(SqlCommand storedProcCommand = new SqlCommand("addToNotificationTable", connection)) //Specify only the SP name
{
storedProcCommand.CommandType = CommandType.StoredProcedure; //Indicates that Command to be executed is a stored procedure no a query
var paramId = new SqlParameter("#ID", reader.GetInt32(0));
storedProcCommand.Parameters.Add(paramId);
storedProcCommand.ExecuteNonQuery()
}
}
Since you are calling the sp inside a while loop, wrap the code in using() { } to automatically dispose the command object after each iteration

Call stored procedure with custom type parameter from c#?

I have a procedure with a custom type as follow:
CREATE PROCEDURE MyProc
#Arg1 CustomArgType readonly
AS
BEGIN
.
.
.
END
And where the custom type is:
CREATE TYPE dbo.CustomArgType as TABLE
(
SomeInt int not null
)
How can I call the above stored procedure in c#?
What kind of adapter can be used? Can an ORM like EF work with such a stored procedure?
To test that, I extended your stored proc to make it return the first row of the parameter table:
CREATE PROCEDURE MyProc
#Arg1 CustomArgType readonly
AS
BEGIN
select top 1 SomeInt from #Arg1
END
Now I can use the following code in C# to execute the stored procedure:
using (var conn = new SqlConnection("Data Source=localhost;Initial Catalog=temp;User ID=sa"))
{
conn.Open();
DataTable dt = new DataTable();
dt.Columns.Add("SomeInt", typeof(Int32));
dt.Rows.Add(new Object[] { 3 });
var command = conn.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "MyProc";
command.Parameters.Add(new SqlParameter("#Arg1", dt));
object returnValue = command.ExecuteScalar();
}
returnValue is 3 which I expected (I inserted into the 1st row in the parameter table).
Unfortunately I don't know much about EF so I can't say if you can do the same.
You can define your table parameter as "Structured", and set its value to your list/table variable in C#. Example code below:
try
{
using (var conn = new SqlConnection(myConnectionString))
using (var command = new SqlCommand("MyProc", conn)
{
CommandType = CommandType.StoredProcedure
})
{
command.Parameters.Add(new SqlParameter("#Arg1", SqlDbType.Structured));
command.Parameters["#Arg1"].Value = myArgVariable;
command.Parameters["#Arg1"].TypeName = "dbo.CustomArgType";
conn.Open();
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
throw;
}
Reference: https://blogs.msdn.microsoft.com/felixmar/2010/10/27/how-to-create-and-execute-a-stored-procedure-using-a-table-as-a-parameter/

Categories

Resources