I'm struggling with this thing for the past hour and I'm sure I'm missing something small, I have a stored procedure in SQL Server 2008 and C# code that I want to return the output parameters of my stored procedure.
SQL :
Alter Procedure dbo.GetAssessment
#UserID int,
#AssessmentName varchar(255),
#Score varchar(100) output,
#Completed varchar(10) output,
#DisplayName nvarchar(128) output,
#Result varchar(2500) output
as
begin
select #Score = A.Score, #Completed = A.Completed, #DisplayName = U.Displayname, #Result = A.Result
from Assessment A
inner join Users U
on U.UserId = A.UserID
where U.UserID = #UserId
and AssessmentName = #AssessmentName
end
GO
C#
String SScore, SName, SResult, SComp;
lblAsse.Text = Request.QueryString["AID"];
InsertAssessment(lblAsse.Text, "No", 2, "N/A", "N/A");
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SiteSqlServer"].ConnectionString))
{
SqlParameter outScore = new SqlParameter("#Score", SqlDbType.VarChar,100){ Direction = ParameterDirection.Output };
SqlParameter outComp = new SqlParameter("#Completed", SqlDbType.VarChar,10){ Direction = ParameterDirection.Output };
SqlParameter outName = new SqlParameter("#DisplayName", SqlDbType.NVarChar, 128) { Direction = ParameterDirection.Output };
SqlParameter outResult = new SqlParameter("#Result", SqlDbType.VarChar,2500){ Direction = ParameterDirection.Output };
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "GetAssessment";
cmd.Parameters.AddWithValue("#AssessmentName", lblAsse.Text);
cmd.Parameters.AddWithValue("#UserId", 2);
cmd.Parameters.Add(outScore);
cmd.Parameters.Add(outComp);
cmd.Parameters.Add(outName);
cmd.Parameters.Add(outResult);
cmd.ExecuteScalar();
SScore = outScore.ToString();
SName = outName.ToString();
SResult = outResult.ToString();
SComp = outComp.ToString();
conn.Close();
lblAsse.Text = SScore;`
Output :
#Score
What can possibly be wrong with me or my code. Please help!
You just need to read out the actual values from your output parameters:
SScore = outScore.Value;
The .ToString() doesn't return the value - it returns the name of the parameter instead...
See the MSDN documentation on SqlParameter for more details.
just need to do this.
Before getting the output parameters you must close the Data reader as
reader.Close();
and then you get output parameters as
SScore = outScore.Value.Tostring();
for more help consult this http://msdn.microsoft.com/en-us/library/ms971497
>Try this its working fine for the multiple output parameter:
using (SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["conStringEndicia"].ConnectionString)){
using (var sqlCmd = new SqlCommand("endicia.credentialLookup", sqlConnection))
{
sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("#accountNumber", accountNumber);
SqlParameter outLogin = new SqlParameter("#login", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output };
sqlCmd.Parameters.Add(outLogin);
SqlParameter outPassword = new SqlParameter("#password", SqlDbType.NVarChar, 100) { Direction = ParameterDirection.Output };
sqlCmd.Parameters.Add(outPassword);
sqlConnection.Open();
sqlCmd.ExecuteNonQuery();
string login, password;
login = outLogin.Value.ToString();
password = outPassword.Value.ToString();
}
}
Related
I'm beginner in C# and SQL Server, and I wrote this query for creating a stored procedure in SQL Server:
create procedure newBehzad
#id bigint
as
DECLARE #ResultValue int
select *
from TABLEA
where id > #id
SET #ResultValue = -5
go
Everything is working, and I wrote this C# code to call that stored procedure and it return a single value:
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("newBehzad", conn)
{
CommandType = CommandType.StoredProcedure
})
{
conn.Open();
command.Parameters.Add("#id", SqlDbType.BigInt).Value = 2;
command.Parameters.Add("#ResultValue", SqlDbType.Int);
SqlParameter retval = command.Parameters.Add("#ResultValue", SqlDbType.Int);
retval.Direction = ParameterDirection.ReturnValue;
retunvalue = (string)command.Parameters["#ResultValue"].Value;
//SqlParameter retval = sqlcomm.Parameters.Add("#b", SqlDbType.VarChar);
command.ExecuteNonQuery();
conn.Close();
}
MessageBox.Show(returnValue);
But when I run the C# windows application, I get this error:
Procedure or function newBehzad has too many arguments specified.
How can I solve that? Thanks.
Change you procedure to:
create procedure newBehzad #id bigint, #ResultValue int OUT
as
SET #ResultValue = 0
BEGIN
select *from TABLEA
where id>#id
SET #ResultValue = -5
END
go
Please try somethink like this:
object returnValue = null;
using (var conn = new System.Data.SqlClient.SqlConnection(AbaseDB.DBFactory.GetInstance().GetConnectionString()))
{
using (System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("newBehzad", conn) { CommandType = CommandType.StoredProcedure })
{
conn.Open();
command.Parameters.Add("#id", SqlDbType.BigInt).Value = 2;
command.Parameters.Add("#ResultValue", SqlDbType.Int).Direction = ParameterDirection.Output;
command.ExecuteNonQuery();
returnValue = command.Parameters["#ResultValue"].Value;
conn.Close();
}
if (returnValue != null)
MessageBox.Show(returnValue.ToString());
}
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("newBehzad", conn)
{
CommandType = CommandType.StoredProcedure
})
{
conn.Open();
command.Parameters.Add("#id", SqlDbType.BigInt).Value = 2;
// command.Parameters.Add("#ResultValue", SqlDbType.Int); Comment this line
SqlParameter retval = command.Parameters.Add("#ResultValue", SqlDbType.Int);
retval.Direction = ParameterDirection.ReturnValue;
retunvalue = (string)command.Parameters["#ResultValue"].Value;
//SqlParameter retval = sqlcomm.Parameters.Add("#b", SqlDbType.VarChar);
command.ExecuteNonQuery();
conn.Close();
}
MessageBox.Show(returnValue);
First of all you need to change the stored proc to return the value:
create procedure newBehzad #id bigint
as
DECLARE #ResultValue int
select *from TABLEA
where id>#id
SET #ResultValue = -5
Return #ResultValue
go
Then grab it with:
using (var conn = new SqlConnection(connectionString))
{
conn.Open();
using (var cmd = new SqlCommand("newBehzad", conn)
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter retval = new SqlParameter();
retval.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("#id", SqlDbType.BigInt).Value = 2;
cmd.Parameters.Add(retval);
cmd.ExecuteNonQuery();
returnValue = (int)retval.Value;
}
}
But I really can not get why are you selecting data in the stored proc...
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;
procedure select_card_transaction(trans_id nvarchar2,
usr_id number,
Quantity out number) is
begin
select count(*)
into Quantity
from user_cards u
where u.transaction_id = trans_id
and u.user_id = usr_id;
end;
and Consuming it:
using(var conn = new OracleConnection(Settings.Default.OraWUConnString))
{
var cmd = conn.CreateCommand();
cmd.CommandText = "for_temporary_testing.select_card_transaction";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("trans_id", TransactionID);
cmd.Parameters.AddWithValue("usr_id", UserID);
var q = new OracleParameter("Quantity", OracleType.Number);
q.Direction = ParameterDirection.Output;
cmd.Parameters.Add(q);
//cmd.Parameters[0].OracleType = OracleType.NVarChar;
//cmd.Parameters[1].OracleType = OracleType.Number;
conn.Open();
var obj = cmd.ExecuteNonQuery();
conn.Close();
return (int)q.Value == 1;
}
It returns the following error.
ORA-06550 wrong number or types of arguments when calling Oracle stored procedure...
ANY IDEA?
I have had the same problem before. Are you using the ODP.Net drivers? I was able to solve the problem by adding the output parameter first. This needs to be done before the input parameters. In your case it would look like
using(var conn = new OracleConnection(Settings.Default.OraWUConnString))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "for_temporary_testing.select_card_transaction";
cmd.CommandType = CommandType.StoredProcedure;
// Return value parameter has to be added first !
var Quantity = new OracleParameter();
Quantity.Direction = ParameterDirection.ReturnValue;
Quantity.OracleDbType = OracleDbType.Int32;
cmd.Parameters.Add(Quantity);
//now add input parameters
var TransID = cmd.Parameters.Add("trans_id", TransactionID);
TransID.Direction = ParameterDirection.Input;
TransID.OracleDbType = OracleDbType.NVarchar2;
var UsrID = cmd.Parameters.Add("usr_id", UserID);
UsrID.Direction = ParameterDirection.Input;
UsrID.OracleDbType = OracleDbType.Int32;
cmd.ExecuteNonQuery();
conn.Close();
return Convert.ToInt32(Quantity.Value);
}
The problem was in the parameter. It was null and oracle returned error. I got that if argument is null, it should be sent as DBNULL
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
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
}