calling procedure from sql - c#

I am coding winform application where i call procedure in my datagrid.
I have method where I define parameters of procedure
public int Add_Nastavenie(out int typNastav, int nastavID, string hod)
{
ResetParameters();
cmd.CommandText = "add_Nastav";
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter sqlParameter;
var sqlParameterOut = new SqlParameter("#TypNastav", SqlDbType.Int);
sqlParameterOut.Direction = ParameterDirection.Output;
sqlParameter = new SqlParameter("#NastavenieID", SqlDbType.Int);
sqlParameter.Direction = ParameterDirection.Input;
sqlParameter.Value = nastavID;
cmd.Parameters.Add(sqlParameter);
sqlParameter = new SqlParameter("#Hodnota", SqlDbType.NVarChar, 100);
sqlParameter.Direction = ParameterDirection.Input;
sqlParameter.Value = hod;
cmd.Parameters.Add(sqlParameter);
var sqlParameterRet = new SqlParameter("retValue", SqlDbType.Int);
sqlParameterRet.Direction = ParameterDirection.ReturnValue;
cmd.ExecuteNonQuery();
typNastav = (int)sqlParameterOut.Value;
return (int)cmd.Parameters["retvalue"].Value;
}
then i call procedure this way
dataConnector.Add_Nastavenie(typNastav,nastavID,hod);
I have an error Argument 1 must be passed with the 'out' keyword
I change it to dataConnector.Add_Nastavenie(out typNastav,nastavID,hod);
error dissapear but application is not working, procedure do nothing .
My try catch exception show : Procedure or function 'add_Nastav' expects parameter '#TypNastav', which was not supplied.
Can somebody help find solution ? Thanks .

You haven't added the OUTPUT parameter the stored procedure is expecting:
cmd.Parameters.Add(sqlParameterOut);

Example:
SqlCommand com = new SqlCommand("update_outptu_Stock", connect.con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#cg_id ", 1);
SqlParameter par = new SqlParameter("#id", SqlDbType.Int)
{
Direction = ParameterDirection.Output
};
SQL:
Create proc update_outptu_Stock
#cg_id int,
#id int output
as
begin
insert into example(cg_id) values (#cg_id)
set #id = SCOPE_IDENTITY() -- get value of id created
end
Go
Get parameter id:
var parvalue = id.value;

Related

How to add return value to stored procedure parameter in C#?

I am trying to invoke a stored procedure in my database I have called InsertJ in c#.
My procedure has an output parameter, which is an integer.
When I run my program, and input the values to insert, I get an exception sayings: InsertJ expects parameter '#code' which was not supplied.
To my knowledge I am supplying it correctly. Can anyone help me figure out what im doing wrong?
if(input == "insert")
{
insertCmd = new SqlCommand(insertStmt, conn);
insertCmd.CommandType = CommandType.StoredProcedure;
insertCmd.Parameters.Add("#jnum", SqlDbType.VarChar, 5);
insertCmd.Parameters.Add("#jname", SqlDbType.VarChar, 20);
insertCmd.Parameters.Add("#city", SqlDbType.VarChar, 10);
SqlParameter ret = insertCmd.Parameters.Add("#code", SqlDbType.Int);//here
ret.Direction = ParameterDirection.ReturnValue;//here
insertCmd.Prepare();
ret.Direction = ParameterDirection.ReturnValue;
should be:
ret.Direction = ParameterDirection.Output;

SQL error with Stored Procedure

I am inserting rows in sql table through my c# code , which calls a Stored procedure .
C# code:
SqlCommand myCommand = thisConnection.CreateCommand();
myCommand.CommandText = "FederationUpdateCTRAndImpressionCountsForAllYPIds";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#bid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#uid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#imp", SqlDbType.VarChar);
myCommand.Parameters.Add("#ctr", SqlDbType.VarChar);
while (myfederationReader.Read())
{
myCommand.Parameters["#bid"].Value = myfederationReader["BusinessId"];
myCommand.Parameters["#uid"].Value = myfederationReader["UId"];
myCommand.Parameters["#imp"].Value = myfederationReader["Impression"];
myCommand.Parameters["#ctr"].Value = myfederationReader["CTR"];
rowsAffected = myCommand.ExecuteNonQuery();
}
Stored proc:
CREATE PROCEDURE [dbo].[FederationUpdateCTRAndImpressionCountsForAllYPIds]
#bid uniqueidentifier,
#uid uniqueidentifier,
#imp varchar(255),
#ctr varchar(255)
AS BEGIN
UPDATE BasicBusinessInformation
SET BasicBusinessInformation.CTR = #ctr , BasicBusinessInformation.Impression = #imp
WHERE BasicBusinessInformation.BusinessId = #bid AND BasicBusinessInformation.UId = #uid
END
On executing it , following error is reported:
procedure has no parameters and arguments were supplied
Try clearing the Command parametres
[C#]
public bool ExportAndClear() {
SqlParameter[] myParamArray = new SqlParameter[myCmd.Parameters.Count - 1];
myCmd.Parameters.CopyTo(myParamArray, 0);
myCmd.Parameters.Clear();
return true;
}
try to fetch data from reader before you fire this command
like
1)Fetch data from reader and store in list or datatable
2)For loop on list or datatable
3)in for loop fire this command
Try moving the following
SqlCommand myCommand = thisConnection.CreateCommand();
myCommand.CommandText = "FederationUpdateCTRAndImpressionCountsForAllYPIds";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("#bid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#uid", SqlDbType.UniqueIdentifier);
myCommand.Parameters.Add("#imp", SqlDbType.VarChar);
myCommand.Parameters.Add("#ctr", SqlDbType.VarChar);
In the while loop, see if you get different results.

Get Return Value from Stored procedure in asp.net

i have a stored procedure
ALTER PROC TESTLOGIN
#UserName varchar(50),
#password varchar(50)
As
Begin
declare #return int;
set #return = (SELECT COUNT(*)
FROM CPUser
WHERE UserName = #UserName
AND Password = #password);
return #return;
End
and in c#
SqlConnection con = db.con;
SqlCommand cmd = new SqlCommand("TESTLOGIN", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parm = new SqlParameter("#return", SqlDbType.Int);
parm.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(parm);
cmd.Parameters.Add(new SqlParameter("#UserName", txtUserName.Text.ToString().Trim()));
cmd.Parameters.Add(new SqlParameter("#password", txtPassword.Text.ToString().Trim()));
cmd.ExecuteNonQuery();
con.Close();
int id = Convert.ToInt32(parm.Value);
but it always return 0. Please help me to solve this problem
You need a parameter with Direction set to ParameterDirection.ReturnValue in code but no need to add an extra parameter in SP. Try this
SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
cmd.ExecuteNonQuery();
int id = (int) returnParameter.Value;
2 things.
The query has to complete on sql server before the return value is sent.
The results have to be captured and then finish executing before
the return value gets to the object.
In English, finish the work and then retrieve the value.
this will not work:
cmm.ExecuteReader();
int i = (int) cmm.Parameters["#RETURN_VALUE"].Value;
This will work:
SqlDataReader reader = cmm.ExecuteReader();
reader.Close();
foreach (SqlParameter prm in cmd.Parameters)
{
Debug.WriteLine("");
Debug.WriteLine("Name " + prm.ParameterName);
Debug.WriteLine("Type " + prm.SqlDbType.ToString());
Debug.WriteLine("Size " + prm.Size.ToString());
Debug.WriteLine("Direction " + prm.Direction.ToString());
Debug.WriteLine("Value " + prm.Value);
}
if you are not sure
check the value of the parameter
before during and after the results have been processed by the reader.
you can try this.Add the parameter as output direction and after executing the query get the output parameter value.
SqlParameter parmOUT = new SqlParameter("#return", SqlDbType.Int);
parmOUT.Direction = ParameterDirection.Output;
cmd.Parameters.Add(parmOUT);
cmd.ExecuteNonQuery();
int returnVALUE = (int)cmd.Parameters["#return"].Value;
Procedure never returns a value.You have to use a output parameter in store procedure.
ALTER PROC TESTLOGIN
#UserName varchar(50),
#password varchar(50)
#retvalue int output
as
Begin
declare #return int
set #return = (Select COUNT(*)
FROM CPUser
WHERE UserName = #UserName AND Password = #password)
set #retvalue=#return
End
Then you have to add a sqlparameter from c# whose parameter direction is out.
Hope this make sense.
If you want to to know how to return a value from stored procedure to Visual Basic.NET. Please read this tutorial: How to return a value from stored procedure
I used the following stored procedure to return the value.
CREATE PROCEDURE usp_get_count
AS
BEGIN
DECLARE #VALUE int;
SET #VALUE=(SELECT COUNT(*) FROM tblCar);
RETURN #VALUE;
END
GO
Do it this way (make necessary changes in code)..
SqlConnection con = new SqlConnection(GetConnectionString());
con.Open();
SqlCommand cmd = new SqlCommand("CheckUser", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("username", username.Text);
SqlParameter p2 = new SqlParameter("password", password.Text);
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
SqlDataReader rd = cmd.ExecuteReader();
if(rd.HasRows)
{
//do the things
}
else
{
lblinfo.Text = "abc";
}

Trouble executing SQL stored procedure from C#

I have an existing stored procedure in SQL Server that I need to call from my C# code and get result. Here is how this SP looks like
CREATE PROCEDURE [dbo].[sp_MSnextID_DDB_NextID]
#tablesequence varchar(40)
AS
declare #next_id integer
begin transaction
update DDB_NextID
set DDB_SEQUENCE = DDB_SEQUENCE + 1
where DDB_TABLE = #tablesequence
select #next_id = DDB_SEQUENCE from DDB_NextID
where DDB_TABLE = #tablesequence
commit transaction
RETURN #next_id
Here is my C# code
using (OdbcConnection connection = new OdbcConnection(GetConnectionString()))
{
using (IDbCommand command = new OdbcCommand())
{
command.CommandText = "sp_MSnextID_DDB_NEXTID";
command.CommandType = CommandType.StoredProcedure;
IDbDataParameter parameter1 = command.CreateParameter();
parameter1.DbType = DbType.String;
parameter1.ParameterName = "#tablesequence";
parameter1.Value = "ddb_dc_document";
parameter1.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter1);
IDbDataParameter parameter2 = command.CreateParameter();
parameter2.DbType = DbType.Int32;
parameter2.ParameterName = "#Return_Value";
parameter2.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter2);
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
IDbDataParameter o = (command.Parameters)["#Return_Value"] as IDbDataParameter;
//Got return value from SP in o.Value
}
}
The trouble is I am getting exception
[42000] [Microsoft][SQL Native Client][SQL Server]Procedure or function 'sp_MSnextID_DDB_NextID' expects parameter '#tablesequence',
which was not supplied.
which I can't explain or fix. What I am missing?
To find a way around, I was trying different approach: executing the following query that sets data in a temp table
create table #temp (i integer); insert into #temp exec sp_MSNextID_DDB_NEXTID #tablesequence='ddb_dc_document';select * from #temp;
In this case SP is executed correctly but select returns zero rows!
Unfortunately, you can't use named parameters with OdbcCommand. You will need to instead execute a call statement to your stored procedure.
using (OdbcConnection connection = new OdbcConnection(GetConnectionString()))
{
using (IDbCommand command = new OdbcCommand())
{
command.CommandText = "{ ? = CALL sp_MSnextID_DDB_NEXTID(?) }";
command.CommandType = CommandType.StoredProcedure;
IDbDataParameter parameter2 = command.CreateParameter();
parameter2.DbType = DbType.Int32;
parameter2.ParameterName = "#Return_Value";
parameter2.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter2);
IDbDataParameter parameter1 = command.CreateParameter();
parameter1.DbType = DbType.String;
parameter1.ParameterName = "#tablesequence";
parameter1.Value = "ddb_dc_document";
parameter1.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter1);
command.Connection = connection;
connection.Open();
command.ExecuteNonQuery();
IDbDataParameter o = (command.Parameters)["#Return_Value"] as IDbDataParameter;
//Got return value from SP in o.Value
}
}
To make your workaround work you should replace
RETURN #next_id
in your procedure with
SELECT #next_id

How to get the return value and rows in c# thru stored procedure

In the below Stored procedure, i am returning a row if all the conditions satisfies, orelse i am returning a message like which condition is nor satisfied.
The Stored proc is working perfectly...
ALTER PROCEDURE dbo.BookingCheck
(
#int_duration_of_stay int ,
#int_number_of_guests int,
#date_of_application date,
#date_of_checkin date,
#date_of_checkout date,
#str_room_type varchar(50),
#ret_value varchar(100) = '' output
)
AS
DECLARE #MaxPer int
DECLARE #BasicCharge int
DECLARE #SurCharge int
DECLARE #TotalAmount int
DECLARE #NoOfDays int
DECLARE #Free VARCHAR(10)
IF #int_duration_of_stay > 6
BEGIN
SET #NoOfDays = #int_duration_of_stay
SET #Free = 'Yes'
END
ELSE
BEGIN
SET #NoOfDays = #int_duration_of_stay - 1
SET #Free = 'No'
END
SELECT #MaxPer = int_max_pax, #BasicCharge = flt_basic_charge, #SurCharge = flt_surcharge_per_pax
FROM RoomTypes WHERE UPPER(str_room_type) = UPPER(#str_room_type)
IF DATEDIFF(DAY, GETDATE(), #date_of_checkin) < 40
BEGIN
IF #int_number_of_guests <= #MaxPer
BEGIN
SET #TotalAmount = (#NoOfDays * #int_number_of_guests * #SurCharge) + #BasicCharge
SET #ret_value = 'Success'
SELECT #str_room_type as 'Room Type', #MaxPer as 'Max Persons Allowed', #int_number_of_guests as 'No. of persons requested',
#int_duration_of_stay as 'No. of days stay', #BasicCharge as 'Basic Charge', #SurCharge as 'Sur Charge', #Free as 'Complimentary',
#TotalAmount as 'Total Amount'
END
ELSE
BEGIN
SET #ret_value = 'Max persons allowed is ' + CONVERT(VARCHAR(20), #MaxPer)
END
END
ELSE
BEGIN
SET #ret_value = 'The check in date should be less than 40 days from current date.'
END
RETURN
The problem is dont know how to get the return message or return row from the SP using c#.
The below code returns me the rows if the condition is satisfied in SP. if not, i am not getting the return message. How to get that ?
public DataSet BookingCheck(int duration_of_stay, int number_of_guests,
string date_of_application, string date_of_checkin, string date_of_checkout,
string room_type)
{
DataSet dsGetBookingCheck = new DataSet();
SqlConnection conn = new SqlConnection(Con);
SqlCommand command = new SqlCommand("BookingCheck", conn);
command.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
SqlParameter param = new SqlParameter();
param = command.Parameters.Add("#int_duration_of_stay", SqlDbType.Int);
param.Value = duration_of_stay;
param = command.Parameters.Add("#int_number_of_guests", SqlDbType.Int);
param.Value = number_of_guests;
param = command.Parameters.Add("#date_of_application", SqlDbType.Date);
param.Value = date_of_application;
param = command.Parameters.Add("#date_of_checkin", SqlDbType.Date);
param.Value = date_of_checkin;
param = command.Parameters.Add("#date_of_checkout", SqlDbType.Date);
param.Value = date_of_checkout;
param = command.Parameters.Add("#str_room_type", SqlDbType.VarChar, 50);
param.Value = room_type;
conn.Open();
command.ExecuteNonQuery();
da.SelectCommand = command;
da.Fill(dsGetBookingCheck);
conn.Close();
return dsGetBookingCheck;
}
You need to add an out parameter:
command.Parameters.Add("#ret_value", SqlDbType.String);
command.Parameters["#ret_value"].Direction = ParameterDirection.Output;
then after executing the SP
message = command.Parameters["#ret_value"].Value.ToString();
Here is function with out param:
public DataSet BookingCheck(int duration_of_stay, int number_of_guests,
string date_of_application, string date_of_checkin, string date_of_checkout,
string room_type, out string message)
{
DataSet dsGetBookingCheck = new DataSet();
SqlConnection conn = new SqlConnection(Con);
SqlCommand command = new SqlCommand("BookingCheck", conn);
command.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
SqlParameter param = new SqlParameter();
param = command.Parameters.Add("#int_duration_of_stay", SqlDbType.Int);
param.Value = duration_of_stay;
param = command.Parameters.Add("#int_number_of_guests", SqlDbType.Int);
param.Value = number_of_guests;
param = command.Parameters.Add("#date_of_application", SqlDbType.Date);
param.Value = date_of_application;
param = command.Parameters.Add("#date_of_checkin", SqlDbType.Date);
param.Value = date_of_checkin;
param = command.Parameters.Add("#date_of_checkout", SqlDbType.Date);
param.Value = date_of_checkout;
param = command.Parameters.Add("#str_room_type", SqlDbType.VarChar, 50);
param.Value = room_type;
command.Parameters.Add("#ret_value", SqlDbType.String);
command.Parameters["#ret_value"].Direction = ParameterDirection.Output;
conn.Open();
command.ExecuteNonQuery();
da.SelectCommand = command;
da.Fill(dsGetBookingCheck);
message = command.Parameters["#ret_value"].Value.ToString();
conn.Close();
return dsGetBookingCheck;
}
NOTE: I have never done with with using ExecuteNonQuery and then using Fill on a data adapter. That might mess this up.
What is ExecuteNonQuery doing in your code when you are not inserting anything?
There are ways to do this. One, use a DataReader. It is a bit more helpful in these kind of scenarios. Or you can add a output parameter to the stored procedure and check that after you execute the proc through C#.
That's not doable in C#. You can only either return a DataTable with a single row (using the Fill method in your example) or you can return a single value (using an SqlCommand with a return parameter or ExecuteScalar).
Instead you should do a SELECT in both cases but with different fields depending on the IF statement. I.e.,
SET #ret_value = 'Max persons allowed is ' + CONVERT(VARCHAR(20), #MaxPer)
is converted to be
SELECT 'Max persons allowed is ' + CONVERT(VARCHAR(20), #MaxPer) AS Return_Value
And then you check for the field name in your return DataTable. E.g.
if (BookingCheck(...).Tables[0].Columns.Contains("Return_Value")) {
// Handle my special condition here
}

Categories