I am new to writing Stored Procedure. So I wrote one with output parameters and want to access the output value, hot to do it.
My Stored Procedure:
ALTER PROCEDURE selQuery
(
#id int, #code varchar(50) OUTPUT
)
AS
SELECT RecItemCode = #code, RecUsername from Receipt where RecTransaction = #id
RETURN #code
If trying to set "#code=RecItemCode" getting error as : "A SELECT statement that assigns a value to a variable must not be combined with Data Retrieval operations."
And I am using the Stored Procedure as:
con.Open();
cmd.Parameters.AddWithValue("#id", textBox1.Text);
SqlParameter code = new SqlParameter("#code", SqlDbType.Int);
code.Direction = ParameterDirection.Output;
cmd.Parameters.Add(code);
SqlDataReader sdr = cmd.ExecuteReader();
MessageBox.Show(cmd.Parameters["#code"].Value.ToString()); // getting error
con.Close();
Error : "Object reference not set to an instance of an object."
I want to get the value of output parameter. How to get that?
Thanks.
There are a several things you need to address to get it working
The name is wrong its not #ouput its #code
You need to set the parameter direction to Output.
Don't use AddWithValue since its not supposed to have a value just you Add.
Use ExecuteNonQuery if you're not returning rows
Try
SqlParameter output = new SqlParameter("#code", SqlDbType.Int);
output.Direction = ParameterDirection.Output;
cmd.Parameters.Add(output);
cmd.ExecuteNonQuery();
MessageBox.Show(output.Value.ToString());
The SQL in your SP is wrong. You probably want
Select #code = RecItemCode from Receipt where RecTransaction = #id
In your statement, you are not setting #code, you are trying to use it for the value of RecItemCode. This would explain your NullReferenceException when you try to use the output parameter, because a value is never assigned to it and you're getting a default null.
The other issue is that your SQL statement if rewritten as
Select #code = RecItemCode, RecUsername from Receipt where RecTransaction = #id
It is mixing variable assignment and data retrieval. This highlights a couple of points. If you need the data that is driving #code in addition to other parts of the data, forget the output parameter and just select the data.
Select RecItemCode, RecUsername from Receipt where RecTransaction = #id
If you just need the code, use the first SQL statement I showed you. On the offhand chance you actually need the output and the data, use two different statements
Select #code = RecItemCode from Receipt where RecTransaction = #id
Select RecItemCode, RecUsername from Receipt where RecTransaction = #id
This should assign your value to the output parameter as well as return two columns of data in a row. However, this strikes me as terribly redundant.
If you write your SP as I have shown at the very top, simply invoke cmd.ExecuteNonQuery(); and then read the output parameter value.
Another issue with your SP and code. In your SP, you have declared #code as varchar. In your code, you specify the parameter type as Int. Either change your SP or your code to make the types consistent.
Also note: If all you are doing is returning a single value, there's another way to do it that does not involve output parameters at all. You could write
Select RecItemCode from Receipt where RecTransaction = #id
And then use object obj = cmd.ExecuteScalar(); to get the result, no need for an output parameter in the SP or in your code.
You need to define the output parameter as an output parameter in the code with the ParameterDirection.Output enumeration. There are numerous examples of this out there, but here's one on MSDN.
SqlCommand yourCommand = new SqlCommand();
yourCommand.Connection = yourSqlConn;
yourCommand.Parameters.Add("#yourParam");
yourCommand.Parameters["#yourParam"].Direction = ParameterDirection.Output;
// execute your query successfully
int yourResult = yourCommand.Parameters["#yourParam"].Value;
You need to close the connection before you can use the output parameters.
Something like this
con.Close();
MessageBox.Show(cmd.Parameters["#code"].Value.ToString());
Related
I am trying to insert data into a SQL Server database by calling a stored procedure, but I am getting the error
Procedure or function 'SHOWuser' expects parameter '#userID', which was not supplied.
My stored procedure is called SHOWuser. I have checked it thoroughly and no parameters is missing.
My code is:
public void SHOWuser(string userName, string password, string emailAddress, List<int> preferences)
{
SqlConnection dbcon = new SqlConnection(conn);
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = dbcon;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "SHOWuser";
cmd.Parameters.AddWithValue("#userName", userName);
cmd.Parameters.AddWithValue("#password", password);
cmd.Parameters.AddWithValue("#emailAddress", emailAddress);
dbcon.Open();
int i = Convert.ToInt32(cmd.ExecuteScalar());
cmd.Parameters.Clear();
cmd.CommandText = "tbl_pref";
foreach (int preference in preferences)
{
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#userID", Convert.ToInt32(i));
cmd.Parameters.AddWithValue("#preferenceID", Convert.ToInt32(preference));
cmd.ExecuteNonQuery();
}
}
catch (Exception)
{
throw;
}
finally
{
dbcon.Close();
}
and the stored procedure is:
ALTER PROCEDURE [dbo].[SHOWuser]
(
#userName varchar(50),
#password nvarchar(50),
#emailAddress nvarchar(50)
)
AS
BEGIN
INSERT INTO tbl_user(userName, password, emailAddress)
VALUES (#userName, #password, #emailAddress)
SELECT
tbl_user.userID, tbl_user.userName,
tbl_user.password, tbl_user.emailAddress,
STUFF((SELECT ',' + preferenceName
FROM tbl_pref_master
INNER JOIN tbl_preferences ON tbl_pref_master.preferenceID = tbl_preferences.preferenceID
WHERE tbl_preferences.userID = tbl_user.userID
FOR XML PATH ('')), 1, 1, ' ' ) AS Preferences
FROM
tbl_user
SELECT SCOPE_IDENTITY();
END
This is the second stored procedure tbl_pref which is used in the same function:
ALTER PROCEDURE [dbo].[tbl_pref]
#userID int,
#preferenceID int
AS
BEGIN
INSERT INTO tbl_preferences(userID, preferenceID)
VALUES (#userID, #preferenceID)
END
In my case I received this exception even when all parameter values were correctly supplied but the type of command was not specified :
cmd.CommandType = System.Data.CommandType.StoredProcedure;
This is obviously not the case in the question above, but exception description is not very clear in this case, so I decided to specify that.
I came across this issue yesterday, but none of the solutions here worked exactly, however they did point me in the right direction.
Our application is a workflow tool written in C# and, overly simplified, has several stored procedures on the database, as well as a table of metadata about each parameter used by each stored procedure (name, order, data type, size, etc), allowing us to create as many new stored procedures as we need without having to change the C#.
Analysis of the problem showed that our code was setting all the correct parameters on the SqlCommand object, however once it was executed, it threw the same error as the OP got.
Further analysis revealed that some parameters had a value of null. I therefore must draw the conclusion that SqlCommand objects ignore any SqlParameter object in their .Parameters collection with a value of null.
There are two solutions to this problem that I found.
In our stored procedures, give a default value to each parameter, so from #Parameter int to #Parameter int = NULL (or some other default value as required).
In our code that generates the individual SqlParameter objects, assigning DBNull.Value instead of null where the intended value is a SQL NULL does the trick.
The original coder has moved on and the code was originally written with Solution 1 in mind, and having weighed up the benefits of both, I think I'll stick with Solution 1. It's much easier to specify a default value for a specific stored procedure when writing it, rather than it always being NULL as defined in the code.
Hope that helps someone.
Your stored procedure expects 5 parameters as input
#userID int,
#userName varchar(50),
#password nvarchar(50),
#emailAddress nvarchar(50),
#preferenceName varchar(20)
So you should add all 5 parameters to this SP call:
cmd.CommandText = "SHOWuser";
cmd.Parameters.AddWithValue("#userID",userID);
cmd.Parameters.AddWithValue("#userName", userName);
cmd.Parameters.AddWithValue("#password", password);
cmd.Parameters.AddWithValue("#emailAddress", emailAddress);
cmd.Parameters.AddWithValue("#preferenceName", preferences);
dbcon.Open();
PS: It's not clear what these parameter are for. You don't use these parameters in your SP body so your SP should looks like:
ALTER PROCEDURE [dbo].[SHOWuser] AS BEGIN ..... END
In my case I got the error on output parameter even though I was setting it correctly on C# side I figured out I forgot to give a default value to output parameter on the stored procedure
ALTER PROCEDURE [dbo].[test]
(
#UserID int,
#ReturnValue int = 0 output --Previously I had #ReturnValue int output
)
In my case, It was returning one output parameter and was not Returning any value.
So changed it to
param.Direction = ParameterDirection.Output;
command.ExecuteScalar();
and then it was throwing size error. so had to set the size as well
SqlParameter param = new SqlParameter("#Name",SqlDbType.NVarChar);
param.Size = 10;
After researching, I realized that I did not specify
command.CommandType = System.Data.CommandType.StoredProcedure;
After adding this, my application ran properly.
in my case, I was passing all the parameters but one of the parameter my code was passing a null value for string.
Eg: cmd.Parameters.AddWithValue("#userName", userName);
in the above case, if the data type of userName is string, I was passing userName as null.
Sorry if someone has already given an answer to this, I have been browsing the site and trying tips and bits of code for hours, to no avail.
I have a stored procedure which basically retrieves the id of an element, if this element exists, and zero if it doesn't.
Here we go:
PROCEDURE [dbo].[ChecksProductExistence]
#Product_Name varchar(50),
#Return_Value Int output
AS
BEGIN
IF EXISTS (SELECT prod.ProductID
FROM dbo.Products prod
WHERE prod.ProductName = #Product_Name)
SET #Return_Value = 1;
ELSE
SET #Return_Value = 0;
END
Okay, so far so good. Execute that in my database, and it works like a charm... not that it's such complex code.
Then, in Visual Studio, I coded the following:
private static bool checkExistingProduct(ShoppingListContext ctx, Product product)
{
var cmd = ctx.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[ChecksProductExistence]";
ctx.Database.Connection.Open();
int bla = 0;
SqlParameter inParameter = new SqlParameter();
inParameter.ParameterName = "#Product_Name";
inParameter.SqlDbType = SqlDbType.NVarChar;
inParameter.Direction = ParameterDirection.Input;
inParameter.Value = product.ProductName;
SqlParameter outParameter = new SqlParameter();
outParameter.ParameterName = "#Return_Value";
outParameter.SqlDbType = SqlDbType.Int;
outParameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add(inParameter);
cmd.Parameters.Add(outParameter);
bla = cmd.ExecuteNonQuery();
Console.WriteLine(outParameter.Value);
Console.ReadLine();
if ((int)outParameter.Value == 1) return true; else return false;
}
As you can see... simple enough. I create a command, add parameters, execute it, try some decision making on the output.
But... I get an error on the
cmd.ExecuteNonQuery();
line. I have changed it to ExecuteScalar, for example, but still no luck. I have executed it without the "bla = ...", and still the same.
The error I get is
An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll
Additional information: Procedure or function 'ChecksProductExistence' expects parameter '#Product_Name', which was not supplied.
But then again, not only can you see clearly in the code that I AM IN FACT SUPPLYING IT, but also on the debug session I can explore the cmd object and browse the parameters, and I can see that IT IS THERE, and the values are correct...
So what else can I do?? Am I making some silly mistake I can't see...?
As stated in the documentation for SqlCommand.CommandType you have to set it to CommandType.StoredProcedure and set the CommandText to the name of the stored procedure. It defaults to CommandType.Text where you have to include the named parameters in the text of the query.
When you set the CommandType property to StoredProcedure, you should
set the CommandText property to the name of the stored procedure. The
command executes this stored procedure when you call one of the
Execute methods.
The Microsoft .NET Framework Data Provider for SQL
Server does not support the question mark (?) placeholder for passing
parameters to a SQL Statement or a stored procedure called with a
CommandType of Text. In this case, named parameters must be used. For
example:
SELECT * FROM Customers WHERE CustomerID = #CustomerID
So, just add the following
cmd.CommandType = CommandType.StoredProcedure;
somewhere before executing it.
I am trying to INSERT my data into two tables Services and Service-line
Explaining my stored procedure:
It checks for existing ID in the Form
If not found it creates a new record in the Services table the info in the Form, then gets the ID using scope_identity and uses the ID for the Service-Line table.
Also the ID is returned to the Form and stays tre.
Later while inserting second record in Service-Line, the stored procedure checks for existing ID; if found, this time, it takes the ID from the Form and uses it in the Service-Line
This Is my stored procedure
please bear with me, as I am working in this code and testing, a lot of line are commented out
ALTER PROCEDURE [dbo].[InsertServiceServiceLine] (
--Services Entry
--FOR IF CONDITION ---CHECK THE DEFAULT VALUE IN THE FORM on SID
#ExistingSID int,
--SEELCT PARAMETES DEF VALUES
#ComboBoxSelectedBike varchar(100),
-- INPUT PARAMETERES FOR NEW RECORD
#CID int,
#Status bit = 1,
#CurrentMeter int,
#Labor decimal(20,0),
#GrandTotal decimal(20,0) = ISNULL,
--#NextService datetime,
--Service Line
#Spare nvarchar(500),
#Quantity int,
#Uprice decimal(20,2),
#Subtotal decimal(20,2)
)
AS
BEGIN
IF (#ExistingSID <= 0)
BEGIN
SET NOCOUNT ON;
DECLARE #BikeID int
SELECT #BikeID = (SELECT BikeID FROM TblBikeNames WHERE BikeName = #ComboBoxSelectedBike)
INSERT INTO [AutoDB_Sample].[dbo].[TblServices]
(CID,BikeID,Status,CurrentMeter,Labor,DateOfService)
VALUES
(#CID,#BikeID,#Status,#CurrentMeter,#Labor,GETDATE())
DECLARE #SID int
SET #SID = SCOPE_IDENTITY()
INSERT INTO [AutoDB_Sample].[dbo].[TblServiceLine]
(SID,Spare,Quantity,Uprice,Subtotal,DateCreated)
VALUES
(#SID,#Spare,#Quantity,#Uprice,#Subtotal,GETDATE())
RETURN #SID
END
ELSE
BEGIN
INSERT INTO [AutoDB_Sample].[dbo].[TblServiceLine]
(SID,Spare,Quantity,Uprice,Subtotal,DateCreated)
VALUES
(#ExistingSID,#Spare,#Quantity,#Uprice,#Subtotal,GETDATE())
END
END
It gives me an error when I use this stored procedure in a C# Windows Forms
Procedure or Function has too many Arguments
Here's a screenshot of the error
I thought that Putting my login in SP would be great and improve the performance of my application. But now am stuck.
This is my C# Code
public void AddItemIntoServices_ServiceLine()
{
ConnectionStringSettings consetting = ConfigurationManager.ConnectionStrings["AutoDB"];
String ConnectionString = consetting.ConnectionString;
SqlConnection con = new SqlConnection(ConnectionString);
try
{
con.Open(); // open the connection
// Specify the name of the Stored Procedure you will call
String SP_Name = "InsertServiceServiceLine";
// Create the SQL Command object and specify that this is a SP.
SqlCommand cmd = new SqlCommand(SP_Name, con);
cmd.CommandType = CommandType.StoredProcedure;
// Specify values for the input parameters of our Stored Procedure
// Parameters MUST be named the same as the parameters defined in the Stored Procedure.
//~~ If Condition Parameter ****************************************************************************~~//
int exitstingSID;
if (int.TryParse(LblSID_Data.Text, out exitstingSID)) ;
SqlParameter ExistingSID = new SqlParameter("#ExistingSID", exitstingSID);
ExistingSID.Direction = ParameterDirection.Input;
ExistingSID.DbType = DbType.Int16;
cmd.Parameters.Add(ExistingSID);
//Parameter to select Bike ID from Selected Bike Name
SqlParameter ParamBikeID = new SqlParameter("#ComboBoxSelectedBike", ComboBx_BikeNames.Text);
ParamBikeID.Direction = ParameterDirection.Input;
ParamBikeID.DbType = DbType.String;
cmd.Parameters.Add(ParamBikeID);
//~~ Customer Info ************************************************************************************~~//
//CID Convertion
int P_CID;
if (int.TryParse(LblCID_Data.Text, out P_CID)) ;
cmd.Parameters.AddWithValue("#CID", P_CID);
cmd.Parameters.AddWithValue("#Cname", this.TxtBx_CustomerName.Text);
cmd.Parameters.AddWithValue("#Vnum", this.TxtBx_VehicleNumber.Text);
//~~ Service Info ************************************************************************************~~//
//Labor Convertion
int Laborint;
if (int.TryParse(TxtBxLabor.Text, out Laborint)) ;
SqlParameter ParamLabor = new SqlParameter("#Labor", Laborint);
ParamLabor.Direction = ParameterDirection.Input;
ParamLabor.DbType = DbType.Int16;
cmd.Parameters.Add(ParamLabor);
//CurrentMeterConversion
int currentMeterint;
if (int.TryParse(TxtBx_CurrentMeter.Text, out currentMeterint)) ;
SqlParameter ParamCurrentMeter = new SqlParameter("#CurrentMeter", currentMeterint);
ParamCurrentMeter.Direction = ParameterDirection.Input;
ParamCurrentMeter.DbType = DbType.Int16;
cmd.Parameters.Add(ParamCurrentMeter);
//Return Value
SqlParameter ParamReturn = new SqlParameter("#SID", SqlDbType.Int);
ParamReturn.Direction = ParameterDirection.Output;
ParamReturn.DbType = DbType.Int16;
cmd.Parameters.Add(ParamReturn);
//~~ Service Info ************************************************************************************~~//
//Converstions
Decimal UP, ST;
if (Decimal.TryParse(TxtBx_UnitPrice.Text, out UP)) ;
if (Decimal.TryParse(TxtBxTotal.Text, out ST)) ;
//SpareName
cmd.Parameters.AddWithValue("#Spare", ComboBx_SparesName.Text);
//Quantity
cmd.Parameters.AddWithValue("#Qty", NumericBx_Quantity.Value);
//Unit Price
SqlParameter ParamUp = new SqlParameter("#Uprice", UP);
ParamUp.Direction = ParameterDirection.Input;
ParamUp.DbType = DbType.Decimal;
cmd.Parameters.Add(ParamUp);
//Total
SqlParameter ParamTot = new SqlParameter("Subtotal", ST);
ParamTot.Direction = ParameterDirection.Input;
ParamTot.DbType = DbType.Decimal;
cmd.Parameters.Add(ParamTot);
cmd.ExecuteNonQuery();
String _returnedSID = cmd.Parameters["#SID"].Value.ToString();
LblSID_Data.Text = _returnedSID;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
clear();
ToolStripLable_Status.Text = "New Service Record Created";
}
}
The list of parameters passed through the command collection should match exactly what the stored procedure expects by name, type and direction.
Your list of parameters included in the command collection doesn't match with the parameters required by the stored procedure and thus you get the error.
At first sight I could say:
cmd.Parameters.AddWithValue("#Cname", this.TxtBx_CustomerName.Text);
cmd.Parameters.AddWithValue("#Vnum", this.TxtBx_VehicleNumber.Text);
SqlParameter ParamReturn = new SqlParameter("#SID", SqlDbType.Int);
are parameters added to the command collection but are not present in the stored procedure list of parameters.
On the contrary we have the parameters #status bit and #GrandTotal decimal(20,0) = ISNULL, required by the stored procedure but not present in the list. (By The way, the default syntax for a NULL parameter is #GrandTotal decimal(20,0) = NULL
Finally the stored procedure names a parameter #Quantity but you add a parameter named #Qty.
Now there is also the problem of the parameter types that should match otherwise you risk an automatic conversion at best or a error message stating about type mismatches.
You have numerous parameter of type int but you pass parameters of type Int16 while the correct type is Int32. And there is also a more clear error in the type of the parameter #Labor that is expected to be a decimal by the sp but you add it as an integer (16)
You have 12 parameters in the stored procedure definition (if I counted correctly), however, your code may have more or less than that. There is either one too many parameters defined within the code, or the stored procedure expects a 13th parameter. I think the error mentions the former, but I sometimes get them confused.
Anyway that error is always due to a mismatch in the number of parameters, and make sure the direction (input/output) is setup correctly, and everything is typed OK.
I hope this is not one of those questions where I slap myself afterwards, but this is really confusing me. I have this working for another one of my stored procedures which is why this is so confusing. It's basically the same setup in both. Here's what's happening.
Here's an example of my stored procedure:
ALTER PROCEDURE [dbo].[CreateRecord]
-- Add the parameters for the stored procedure here
#Link1Id INT = NULL,
#Link2Id INT = NULL,
#Amount MONEY,
#Output int out
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SET #Output = 0
-- Insert statements for procedure here
IF #Link1Id = NULL
BEGIN
IF NOT EXISTS(SELECT * FROM dbo.Records WHERE Link2Id = #Link2Id)
INSERT INTO [dbo].[Records]
([Link1Id]
,[Link2Id])
VALUES
(#Link1Id
,#Link2Id)
SET #Output = (SELECT RecordId FROM dbo.Records WHERE Link2Id = #Link2Id)
END
ELSE
BEGIN
IF NOT EXISTS(SELECT * FROM dbo.Records WHERE Link1Id = #Link1Id)
INSERT INTO [dbo].[Records]
([Link1Id]
,[Link2Id])
VALUES
(#Link1Id
,#Link2Id)
SET #Output = (SELECT RecordId FROM dbo.Records WHERE Link1Id = #Link1Id)
END
END
Now, I have created a unit test that basically runs this procedure, and tries to Assert that the returned #Output is greater than 0, but the #Output parameter never has a value on the SqlCommand in the code. Here's some of the C# code:
private int ExecuteNonQueryWithOutput(string procedureName, SqlParameter[] parameters)
{
SqlCommand command = this.GenerateCommand(procedureName, parameters);
connection.Open();
command.ExecuteNonQuery();
int retval = (int)command.Parameters[OUTPUT].Value;
connection.Close();
return retval;
}
Now, I can step over the line that calls ExecuteNonQuery(), and verify in the database that the new (and correct) record is there, but then on the next line, it throws an exception when it calls (int)command.Parameters[OUTPUT].Value; as the Value is not there.
This is working perfectly for another procedure that I have which is setup in the same exact fashion. Do you know why it wouldn't be working here?
Thanks, I'm kind of stumped. I've debugged for a while now with no luck.
Edit:
Code that generates the parameters array:
List<SqlParameter> parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter { ParameterName = "#Link1Id", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = link1Val });
parameters.Add(new SqlParameter { ParameterName = "#Link2Id", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = link2Val });
parameters.Add(new SqlParameter { ParameterName = OUTPUT, SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output });
return this.ExecuteNonQueryWithOutput("CreateRecord", parameters.ToArray());
I don't see where you've declared #Output. Did you mean:
ALTER PROCEDURE [dbo].[CreateRecord]
-- Add the parameters for the stored procedure here
#Link1Id INT = NULL,
#Link2Id INT = NULL,
#Amount MONEY,
#Output INT = NULL OUTPUT
AS
Also I'm not 100% sure you have the syntax right for retrieving a named output parameter. But the parameter has to exist before you can reference it anyway. How did you save that stored procedure without declaring #Output?
There are numerous things wrong with the code that go beyond the output parameter issue.
To answer the actual question, you are likely passing a NULL value back as the Output. When it tries to convert this to an Int you are getting an error.
Also the sql line:
IF #Link1ID = null
Will ALWAYS fail. In SQL parlance, null is an indeterminate value, so (null != null). The way to test for null values is to use IS. For example:
IF (#Link1ID is null)
Which leads me to believe that you are actually getting a primary key violation in the sql code.
Now, onto the bigger issue. Your C# code is flawed. The command object is never disposed of and if there are any issues your connection object won't be disposed of either. This will lead to fun sql errors due running out of available sql connections..
It should look something like the following:
private int ExecuteNonQueryWithOutput(string procedureName, SqlParameter[] parameters)
{
int retval = 0;
using (SqlConnection conn = new SqlConnection("connection string here"))
using (SqlCommand command = this.GenerateCommand(procedureName, parameters)) {
connection.Open();
command.ExecuteNonQuery();
retval = (int)command.Parameters[OUTPUT].Value;
}
return retval;
}
Note that this declares, uses and disposes of your connection and command objects locally. If there is a problem this will make sure the resources are properly disposed of.
Also note that it does not use a global "connection" object. Connection pooling offered by the operating system is incredibly efficient at opening/closing connections as needed. Because of this the best practice is to instantiate and keep them around only long enough to deal with the current operation. The longer it's open the more likely you'll run into issues.
Does anyone know how can I read the output variable from .net c#?
Example:
If I have the following stored proc which will return the output variables (#customer_id, #customer_name, #customer_address, #customer_age) instead of the select variable, how can I read the output variable with the following?
mySqlCommand.CommandText = "EXEC app_customers #name=" + sName.Text;
mySqlConnection.Open();
SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
while (mySqlDataReader.Read())
{
}
When the result is a single value (or if you're just interested in the first value in the first column), use the method ExecuteScalar.
It returns an object, simply cast it to the expected type.
int id = (int)mySqlCommand.ExecuteScalar();
Note: the way you're invoking a procedure is not the normal way to do it. Set the command to reference the stored procedure, then add appropriate parameters to the command.Parameters collection. Invoking the procedure using "exec ..." is not a best practice and may even leave you vulnerable. If you need more info on executing such a call, start here.
Edit:
If it is truly an output parameter you need to capture (I believe I misread your question), then the above paragraph is even more applicable. Consider this approach:
mySqlCommand.CommandText = "app_customers";
mySqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
mySqlCommand.Parameters.AddWithValue("#name", theValue);
var customerIdParam = mySqlCommand.Parameters.Add("#customer_id", System.Data.SqlDbType.Int);
customerIdParam.Direction = System.Data.ParameterDirection.Output;
// add more parameters, setting direction as appropriate
mySqlCommand.ExecuteNonQuery();
int customerId = (int)customerIdParam.Value;
// read additional outputs