Load stored procedure results into data table - c#

I've been searching the net for answers but have come up empty again and again.
What I'm trying to do:
Load the results from a stored procedure into a DataTable.
What's going wrong:
I'm not getting any rows returned.
Here is my stored proc (SQL Server 2012). It gets the next auto incremented ID of a table you input and returns it.
ALTER procedure [dbo].[GET_NEXT_AUTO_ID_OF_TABLE]
#TABLE_NAME nvarchar(128),
#NEXT_ID int output
as
declare #latest_id int, #row_count int
begin
set #latest_id = (select IDENT_CURRENT(#TABLE_NAME))
end
if #latest_id = 1
begin
declare #lRowCountSql nvarchar(1000)
set #lRowCountSql = N'select #row_count = count(*) from ' + #TABLE_NAME
exec sp_executesql #lRowCountSql, N'#row_count int out', #row_count out
if #row_count > 0
set #next_id = #latest_id + 1
else
set #next_id = #latest_id
end
else
set #next_id = #latest_id + 1
return
Is the problem my proc (I'm not good with sql)? When I test the proc in SQL Server I get the result I expect.
But not from my C# code:
List<SqlParameter> aSqlParams = new List<SqlParameter>();
aSqlParams.Add(new SqlParameter("#TABLE_NAME", "your table name") { Direction = System.Data.ParameterDirection.Input, SqlDbType = System.Data.SqlDbType.NVarChar });
aSqlParams.Add(new SqlParameter() { ParameterName = "#NEXT_ID", Direction = System.Data.ParameterDirection.Output, SqlDbType = SqlDbType.Int });
DataTable lDt = SQLServerUtils.ExecuteStoredProc("GET_NEXT_AUTO_ID_OF_TABLE", aSqlParams);
int lNextID = lDt.Rows[0].Field<int>("NEXT_ID");
public static DataTable ExecuteStoredProc(string aProcName, List<SqlParameter> aSqlParams)
{
DataTable lResults = new DataTable();
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand(aProcName, conn);
cmd.CommandType = CommandType.StoredProcedure;
if (aSqlParams != null)
foreach (SqlParameter lP in aSqlParams)
cmd.Parameters.Add(lP);
conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(lResults);
}
return lResults;
}

An output parameter is returned by itself, not included in a datatable.
I think you need a different procedure that executes these kind of query,
public static int ExecuteOutputIntParam(string aProcName, string outputParamName, List<SqlParameter> aSqlParams)
{
int outValue = -1;
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(aProcName, conn);
cmd.CommandType = CommandType.StoredProcedure;
if (aSqlParams != null)
foreach (SqlParameter lP in aSqlParams)
cmd.Parameters.Add(lP);
int result = cmd.ExecuteNonQuery();
if (aSqlParams != null)
{
outValue = Convert.ToInt32(aSqlParams[outputParamName].Value);
}
}
return outValue;
}
EDIT
I have copy/pasted your example and I haven't noticed that you rely on the SqlDataAdapter to open/close the connection. In my example the connection should be explicitly opened

The trick here is that the value I want comes back inside the out parameter.
The fixed code looks like this...
SQL proc:
ALTER procedure [dbo].[GET_NEXT_AUTO_ID_OF_TABLE]
#TABLE_NAME nvarchar(128),
#NEXT_ID int output
as
declare #latest_id int, #row_count int
begin
set #latest_id = (select IDENT_CURRENT(''+#TABLE_NAME+''))
end
if #latest_id = 1
begin
declare #lRowCountSql nvarchar(1000)
set #lRowCountSql = N'select #row_count = count(*) from ' + #TABLE_NAME
exec sp_executesql #lRowCountSql, N'#row_count int out', #row_count out
if #row_count > 0
set #next_id = #latest_id + 1
else
set #next_id = #latest_id
end
else
set #next_id = #latest_id + 1
return
C#:
public static int GetNextIdOfTable(string aTableName)
{
int lNextID = 0;
using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
{
SqlCommand cmd = new SqlCommand("GET_NEXT_AUTO_ID_OF_TABLE", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#TABLE_NAME", aTableName) { Direction = System.Data.ParameterDirection.Input, SqlDbType = System.Data.SqlDbType.NVarChar });
cmd.Parameters.Add(new SqlParameter() { ParameterName = "#NEXT_ID", Direction = System.Data.ParameterDirection.Output, SqlDbType = SqlDbType.Int });
conn.Open();
cmd.ExecuteReader();
if (cmd.Parameters["#NEXT_ID"] != null && cmd.Parameters["#NEXT_ID"].Value != DBNull.Value)
return int.Parse(cmd.Parameters["#NEXT_ID"].Value.ToString());
}
return lNextID;
}

Related

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";
}

Why a SqlParameter does not get value?

I am trying to initialize the value of a SqlParameter with a string. but why does it not get the value ?
This is what I tried:
int loadChart(string status)
{
connect();
SqlParameter[] parameters ={
new SqlParameter("status", SqlDbType.VarChar, 10),
new SqlParameter("count", SqlDbType.Int, 4)
};
parameters[0].Value = status;
parameters[1].Direction = ParameterDirection.Output;
SqlCommand cmd = new SqlCommand("sp_Arsenic_getSourceStatusCount", objConnection);
foreach (SqlParameter param in parameters)
{
cmd.Parameters.Add(param);
}
cmd.ExecuteNonQuery();
disConnect();
int count;
count =(int) parameters[1].Value;
return count;
}
}
The stored procedure:
alter procedure sp_Arsenic_getSourceStatusCount
#status varchar(10),
#count int
as
select #count=COUNT(status) from Arsenic_WaterSource where status=#status
return 1
Inserting a breakpoint I have discovered that the string variable status gets its value "safe" but at parameters[0].Value = (string) status; line parameters[0].value gets null. How to resolve this issue ?
You did not define your #count parameter as an OUTPUT parameter in your procedure:
alter procedure sp_Arsenic_getSourceStatusCount
#status varchar(10),
#count int OUTPUT /* <-------------- */
as
select #count=COUNT(status) from Arsenic_WaterSource where status=#status
return 1
Try this:
connect();
SqlCommand cmd = new SqlCommand("sp_Arsenic_getSourceStatusCount", objConnection);
cmd.Parameters.Add(new SqlParameter("#status", status));
SqlParameter pCount = new SqlParameter("#count", 0);
pCount.Direction = System.Data.ParameterDirection.Output;
cmd.Parameters.Add(pCount);
cmd.ExecuteNonQuery();
disConnect();
int count = Convert.ToInt32(parameters[1].Value);
return count;
And this:
alter procedure sp_Arsenic_getSourceStatusCount
#status varchar(10),
#count int = 0 OUTPUT
as
set nocount on
select #count=COUNT(status) from Arsenic_WaterSource where status=#status
go

Return value from stored procedure to c#

I got same problem in one more stored procedure.
I want to add leave request to a SQL Server 2008 database. I can run a stored procedure successfully but from page I can't return status whether operation is complete or incomplete.
I am sending data through SP but not able to get status through program.
My stored procedure is:
ALTER Procedure [dbo].[Check_LeaveDays](
#EmpCode int,
#LV_Type int,
#Leave_AppDt DateTime,
#Leave_ToDate Datetime ,
#LV_Days int
,#Status_Id int Output
)
as
Begin
Declare #Dt_join datetime ,#LastDate Datetime
Declare #Count int
Declare #Leave_Status_Id int
Declare #Leave_period int
Declare #Rule_id int
Declare #Leave_AllocatedDays int
Declare #Leave_MaxDays int
Declare #Days_diff int
-- Declare #Status_Id int
-- Set #Status_Id= 0
Select #Dt_Join =Emp_DOJ from LTS_Employee_Master where Emp_ID =4
Select #LastDate= DATEADD(year, DATEDIFF(year, -1, getdate()), -1)
Select #Days_diff=0
If(YEAR(#Dt_Join) = YEAR(GETDATE()))
Begin
Select #Days_diff = DATEDIFF(D, #Dt_Join,#LastDate)
End
--Select #Leave_AppDt = dateadd(M, -2, getdate())
Select #Rule_id = Case when #LV_Type =1 then ISNULL(Emp_Casual_rule,0)
when #LV_Type =2 then ISNULL(Emp_Medical_rule,0)
when #LV_Type =3 then ISNULL(Emp_PL_rule,0)
else 0 End
from LTS_Employee_Master where Emp_ID =#Empcode
If #LV_Type =1
Begin
Select #Leave_AllocatedDays = LPM_Allocated_Days ,#Leave_MaxDays =LPM_Max_Days ,#Leave_period =LPM_Count
from LTS_Leave_Policy_Master where LPM_Id =#Rule_Id
If #Days_diff <> 0
Begin
Select #Leave_AllocatedDays = 365/#Leave_AllocatedDays
Select #Leave_AllocatedDays = #Days_diff / #Leave_AllocatedDays
End
Select #Count =Sum(Leave_Days)
from LTS_Emp_Leave_Requests where Leave_Emp_ID =#empcode and Leave_type_Id=1 and Leave_Status_ID=1 and YEAR(#Leave_ToDate) =YEAR(leave_to_Date)
Select #Count = ISNULL(#Count,0) + ISNULL(Sum(Leave_Days),0)
from LTS_Emp_Leave_Requests where Leave_Emp_ID =#empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(#Leave_ToDate) =YEAR(leave_to_Date)
and Req_id not in(Select Req_id from LTS_Emp_Leave_Requests where Leave_Emp_ID =#empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(#Leave_ToDate) =YEAR(leave_to_Date))
Select #Count = ISNULL(#Count,0) + ISNULL(Sum(Leave_Days),0)
from LTS_Emp_Leave_Requests where Leave_Emp_ID =#empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(#Leave_ToDate) =YEAR(leave_to_Date)
and Req_id not in(Select Req_id from LTS_Emp_Leave_Requests where Leave_Emp_ID =#empcode and Leave_type_Id=1 and Leave_Status_ID=3 and YEAR(#Leave_ToDate) =YEAR(leave_to_Date))
Select #count,#Leave_MaxDays
if(#LV_Days > #Leave_MaxDays)
Begin
Set #Status_Id=1 -- Status appliation leave days is more than allowance max days at a time
End
If(#Count > #Leave_AllocatedDays)
Begin
Select #Status_Id =2 --Status 2 applies for numbers of maximum days applied is more than actual allocated maximum number of days
End
Select #Count =Sum(Leave_Days)
from
(Select top 1 * from LTS_Emp_Leave_Requests order by Leave_ID desc) Temp
where Leave_Emp_ID =#empcode and Leave_type_Id=1 and Leave_Status_ID =1 group by Leave_Emp_Id
Declare #tbl table(Leave_Id int , Leave_Status_Id int , Leave_To_date datetime,leave_days int,
Leave_Emp_Id int,Leave_off_Id int,Req_Id int,leave_LPM_ID int, leave_type_Id int)
Insert into #tbl
Select top 1
Leave_Id , Leave_Status_Id , Leave_To_date ,
Leave_days ,Leave_Emp_Id ,Leave_off_Id ,Req_Id ,leave_LPM_ID , Leave_type_Id
from LTS_Emp_Leave_Requests where Leave_Emp_ID =#empcode and Leave_Status_ID in(1,3,5) order by Leave_ID desc
Select #Leave_ToDate =Leave_To_date from #tbl
If( DATEDIFF(D,#Leave_ToDate, DATEADD(D,-1, #Leave_AppDt)) > #Leave_AllocatedDays)
Begin
Select #Status_Id =3
End
End
Return #Status_Id
End
My stored procedure calling functions:
public string SendRequestDataSql(int empid, int leavetype, DateTime fromdate, DateTime todate, int leavedays)
{
string retunvalue="0";
DataTable dt = new DataTable();
try
{
SqlConnection sqlConnection = new SqlConnection();
string conString = Connection.GetConnection;
using (SqlConnection con = new SqlConnection(conString))
{
//sqlConnection.Open();
using (SqlCommand cmd = new SqlCommand("Check_LeaveDays", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#EmpCode", SqlDbType.VarChar, 10).Value = empid;
cmd.Parameters.Add("#LV_Type", SqlDbType.VarChar, 10).Value = leavetype;
cmd.Parameters.Add("#Leave_AppDt", SqlDbType.VarChar,15).Value = fromdate;
cmd.Parameters.Add("#Leave_ToDate", SqlDbType.VarChar,15).Value = todate;
cmd.Parameters.Add("#LV_Days", SqlDbType.VarChar,10).Value = leavedays;
SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
con.Open();
int itrrr = Convert.ToInt32( cmd.ExecuteNonQuery());
int returnValue = (int)returnParameter.Value;
//message = Convert.ToInt32(objparm.Value);
con.Close();
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
da.Fill(ds);
dt = ds.Tables[0];
}
}
}
}
catch (SqlException ex)
{
}
return retunvalue;
}
Please Edit Your Code as:
Remove this line:
cmd.Parameters.Add("#Status", SqlDbType.Int).Value = status;
Add this Code:
SqlParameter abc = cmd.Parameters.Add("#Status", SqlDbType.Int);
abc.Direction = ParameterDirection.Output;
Then you can get your Status result in abc.
Hope this will help you.
In Stored Procedure
RETURN #status
in C#
string retunvalue = (string)sqlcomm.Parameters["#status"].Value;
public int? AddNewDesigDataSql(string desig_name, string Details, int AddedBy)
{
int? status = 0;
DataTable dt = new DataTable();
try
{
SqlConnection sqlConnection = new SqlConnection();
string conString = Connection.GetConnection;
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("SP_Dedignation_Add", con))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param1=cmd.Parameters.Add("#Desig_Name", SqlDbType.varchar,500).Value = desig_name;
param1.Direction = ParameterDirection.Input;
SqlParameter param2=cmd.Parameters.Add("#Desig_Desc", SqlDbType.varchar,500).Value = Details;
param2.Direction = ParameterDirection.Input;
SqlParameter param3=cmd.Parameters.Add("#Desig_AddedBy", SqlDbType.int,8).Value = AddedBy;
param3.Direction = ParameterDirection.Input;
SqlParameter param4=cmd.Parameters.Add("#Status", SqlDbType.Int).Value = status;
param4.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
con.Close();
status = (int)param4.Value;
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
da.Fill(ds);
dt = ds.Tables[0];
}
}
}
}
catch (SqlException ex)
{
}
return status;
}

Getting return value from stored procedure in ADO.NET

I have a stored procedure, which returns the unique identifier after insertion ##identity. I tried it in the server explorer and it works as expected #RETURN_VALUE = [identifier].
In my code I added a parameter called #RETURN_VALUE, with ReturnValue direction first, than any other parameters, but when I run my query with ExecuteNonQuery() that parameter remains empty. I don't know what I've done wrong.
Stored Procedure
ALTER PROCEDURE dbo.SetAuction
(
#auctionID int,
#itemID int,
#auctionType tinyint,
#reservationPrice int,
#maxPrice int,
#auctionEnd datetime,
#auctionStart datetime,
#auctionTTL tinyint,
#itemName nchar(50),
#itemDescription nvarchar(MAX),
#categoryID tinyint,
#categoryName nchar(50)
) AS
IF #auctionID <> 0
BEGIN
BEGIN TRAN T1
UPDATE Auction
SET AuctionType = #auctionType,
ReservationPrice = #reservationPrice,
MaxPrice = #maxPrice,
AuctionEnd = #auctionEnd,
AuctionStart = #auctionStart,
AuctionTTL = #auctionTTL
WHERE AuctionID = #auctionID;
UPDATE Item
SET
ItemName = #itemName,
ItemDescription = #itemDescription
WHERE
ItemID = (SELECT ItemID FROM Auction WHERE AuctionID = #auctionID);
COMMIT TRAN T1
RETURN #auctionID
END
ELSE
BEGIN
BEGIN TRAN T1
INSERT INTO Item(ItemName, ItemDescription, CategoryID)
VALUES(#itemName, #itemDescription, #categoryID);
INSERT INTO Auction(ItemID, AuctionType, ReservationPrice, MaxPrice, AuctionEnd, AuctionStart, AuctionTTL)
VALUES(##IDENTITY,#auctionType,#reservationPrice,#maxPrice,#auctionEnd,#auctionStart,#auctionTTL);
COMMIT TRAN T1
RETURN ##IDENTITY
END
C# Code
cmd.CommandText = cmdText;
SqlParameter retval = new SqlParameter("#RETURN_VALUE", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
cmd.Parameters.AddRange(parameters);
cmd.Connection = connection;
connection.Open();
cmd.ExecuteNonQuery();
return (int)cmd.Parameters["#RETURN_VALUE"].Value;
Just tried on my box and this works for me:
In SQL Server:
DROP PROCEDURE TestProc;
GO
CREATE PROCEDURE TestProc
AS
RETURN 123;
GO
In C#
string cnStr = "Server=.;Database=Sandbox;Integrated Security=sspi;";
using (SqlConnection cn = new SqlConnection(cnStr)) {
cn.Open();
using (SqlCommand cmd = new SqlCommand("TestProc", cn)) {
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter returnValue = new SqlParameter();
returnValue.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(returnValue);
cmd.ExecuteNonQuery();
Assert.AreEqual(123, (int)returnValue.Value);
}
}
I solved the problem:
you have to set SqlCommand.CommandType to CommandType.StoredProcedure in order to get return values and/or output parameters. I haven't found any documentation about that, but now everything works.
Do you get the value of you EXEC in TSQL? I wonder if refactoring the TSQL would help (and using SCOPE_IDENTITY():
so change:
COMMIT TRAN T1
RETURN ##IDENTITY
to:
SET #auctionID = SCOPE_IDENTITY()
COMMIT TRAN T1
RETURN #auctionID
(I would also change the other ##IDENTITY to SCOPE_IDENTITY())
As a minor optimisation, you could also use:
return (int)retval.Value;
but this side of things should have worked "as is" from what I can see (hence why I'm focusing on the TSQL).
Some one can also use this simple and short method to calculate return value from SP
In SQL:
Create Table TestTable
(
Int Id
)
CREATE PROCEDURE Proc_TestProc
#Id
AS
Begin
Set NOCOUNT ON //Use this line if you don't want to return any message from SQL
Delete from TestTable where Id = #Id
return 1
Set NOCOUNT OFF //NOCOUNT OFF is Optional for NOCOUNT ON property
End
Sql Server always returns Int type value only.
and in C#
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ToString()))
using (SqlCommand cmd = new SqlCommand("Proc_TestProc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Id", 1);
var returnParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
You can also check your return value in SQL by using this command:
DECLARE #return_status int;
EXEC #return_status = dbo.[Proc_TestProc] 1;
SELECT 'Return Status' = #return_status;
print 'Returned value from Procedure: ' + Convert(varchar, #return_status); // Either previous or this line both will show you the value of returned value
you can use standart ways that you use before in normal queries but in Sql command you must write EXEC before your store procedure name and dont use commandtype like this :
SqlConnection con = new SqlConnection(["ConnectionString"])
SqlCommand com = new SqlCommand("EXEC _Proc #id",con);
com.Parameters.AddWithValue("#id",["IDVALUE"]);
con.Open();
SqlDataReader rdr = com.ExecuteReader();
ArrayList liste = new ArrayList();
While(rdr.Read())
{
liste.Add(rdr[0]); //if it returns multiple you can add them another arrays=> liste1.Add(rdr[1]) ..
}
con.Close();

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