Conversion Failing - c#

I currently have an update statement running in c# and the front end to edit some values in my sql server database. But I am getting a Conversion Failed error. I can not seem to find the source.
ERROR message
Conversion failed when converting the nvarchar value 'UPDATE T_ROLLUP_SYSTEM_EXCEPT
SET DEPT_ID = ' to data type int.
14
Sql
ALTER PROCEDURE [dbo].[USP_UPDATE_SYS_MAPPING]
-- Add the parameters for the stored procedure here
#SYSTEM VARCHAR(50),
#UNIT VARCHAR(50),
#MEDCTRLEVEL VARCHAR(50),
#MEDCTR VARCHAR(50),
#FACID VARCHAR(50),
#ENTN VARCHAR(50),
#DEPT_ID INT,
#ROLLUP_TYPE_ID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #SQL VARCHAR(MAX);
DECLARE #MEDCTRID INT;
SELECT #MEDCTRID = MED_CTR_ID FROM T_ROLLUP_MED_CTR WHERE MED_CTR = #MEDCTR
PRINT (#MEDCTRID);
-- Insert statements for procedure here
SET #SQL = N'UPDATE T_ROLLUP_SYSTEM_EXCEPT
SET DEPT_ID =
'''+#DEPT_ID''' , ROLLUP_TYPE_ID = '''+#ROLLUP_TYPE_ID+'''
, UPDATE_DT = GETDATE()
WHERE SYSTEM = '''+#SYSTEM+'''
AND ENTN = '''+#ENTN+'''
AND MED_CTR_ID = '+CONVERT(VARCHAR,#MEDCTRID)+'
AND MED_CTR_LEVEL = '''+#MEDCTRLEVEL+'''
AND FAC_ID = '''+#FACID+'''
AND UNIT = '''+#UNIT+''''
PRINT (#SQL);
EXEC (#SQL);
HTML
string[] mdctrvalue = medctr.Text.Split('[', ']');
string[] mpvalue = mpSearch.Text.Split('(', ')');
string sys = acctsys.ToString();
string unit = txtunit.ToString();
string mdctrlvl = mdctrvalue[1].ToString();
string mdctr = mdctrvalue[0].ToString();
string facid = fac.ToString();
string entn = txtentn.ToString();
string dept_id = dept.SelectedValue.ToString();
string rollup_type_id = rolluptype.SelectedValue.ToString();
SqlConnection myconn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Rollup2ConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = myconn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "USP_UPDATE_SYS_MAPPING";
cmd.Parameters.Add("#SYSTEM", SqlDbType.VarChar).Value = acctsys.ToString();
cmd.Parameters.Add("#UNIT", SqlDbType.VarChar).Value = unit.ToString();
cmd.Parameters.Add("#MEDCTRLEVEL", SqlDbType.VarChar).Value = mdctrlvl.ToString();
cmd.Parameters.Add("#MEDCTR", SqlDbType.VarChar).Value = mdctr.ToString();
cmd.Parameters.Add("#FACID", SqlDbType.VarChar).Value = facid.ToString();
cmd.Parameters.Add("#ENTN", SqlDbType.VarChar).Value = entn.ToString();
cmd.Parameters.Add("#DEPT_ID", SqlDbType.Int).Value = dept_id.ToString();
cmd.Parameters.Add("#ROLLUP_TYPE_ID", SqlDbType.Int).Value = rollup_type_id.ToString();
myconn.Open();
int retVal = cmd.ExecuteNonQuery();

Maybe change:
+#ROLLUP_TYPE_ID+
To:
+ CONVERT(VARCHAR(12), #ROLLUP_TYPE_ID) +
You should always specify a length for your varchar columns/variables...
That said, you can re-write your stored procedure to not use dynamic SQL at all - why is it being used?
ALTER PROCEDURE [dbo].[USP_UPDATE_SYS_MAPPING]
#SYSTEM VARCHAR(50),
#UNIT VARCHAR(50),
#MEDCTRLEVEL VARCHAR(50),
#MEDCTR VARCHAR(50),
#FACID VARCHAR(50),
#ENTN VARCHAR(50),
#DEPT_ID INT,
#ROLLUP_TYPE_ID INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #MEDCTRID INT;
SELECT #MEDCTRID = MED_CTR_ID FROM dbo.T_ROLLUP_MED_CTR
WHERE MED_CTR = #MEDCTR;
PRINT (#MEDCTRID);
UPDATE dbo.T_ROLLUP_SYSTEM_EXCEPT
SET DEPT_ID = CASE
WHEN #DEPT_ID > 1 THEN #DEPT_ID
WHEN #DEPT_ID = 1 THEN NULL
ELSE REG_DEPT_ID1 END
, ROLLUP_TYPE_ID = #ROLLUP_TYPE_ID
, UPDATE_DT = GETDATE()
WHERE SYSTEM = #SYSTEM
AND ENTN = #ENTN
AND MED_CTR_ID = #MEDCTRID
AND MED_CTR_LEVEL = #MEDCTRLEVEL
AND FAC_ID = #FACID
AND UNIT = #UNIT;
END
GO
If it needs to be dynamic SQL for some reason you haven't yet shared, you are still better off parameterizing as much of this as possible using sp_executesql instead of EXEC().

Related

How to use the output parameter insert stored procedure in ASP.NET

I have stored procedure as follows
ALTER PROCEDURE [dbo].[sp1]
#mat NVARCHAR(1000) = NULL,
#party NVARCHAR(1000) = NULL,
#place NVARCHAR(1000) = NULL,
#truk NVARCHAR(1000) = NULL,
#qty NUMERIC(10) = NULL,
#ptm NUMERIC(10) = NULL,
#mop NVARCHAR(100) = NULL,
#tos NVARCHAR(100) = NULL,
#driver NVARCHAR(100) = NULL,
#date1 DATE = NULL
AS
BEGIN
DECLARE #sql NVARCHAR(4000);
DECLARE #params NVARCHAR(4000);
DECLARE #rate NUMERIC(10);
SET #sql ='select #rate = ['+#mat+'] from tblcos'+ ' where [Name] = #party'
set #params = '#party nvarchar (1000), #rate NVARCHAR(10) OUTPUT'
exec sp_executesql #sql, #params,#party= #party,#rate = #rate OUTPUT
INSERT INTO tblsls([Party], [Place], [truk], [Material], [Qty], rate, [Amount], [Payment], [Balance], [MOP], [TOS], [driver], [Date])
SELECT
#party, #place, #truk, #mat, #rate, #qty, (#qty * #rate),
#ptm, (#qty * #rate - #ptm), #mop, #tos, #driver, #date1
END
My aspx.cs file
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection (#"
Data Source = ABC - PC; Initial Catalog = VRA; Integrated Security = True");
SqlCommand cmd = new SqlCommand("sp1", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("Date", Calendar1.SelectedDate);
cmd.Parameters.AddWithValue("party", Ddprt.SelectedValue);
cmd.Parameters.AddWithValue("Place", tbpls.Text);
cmd.Parameters.AddWithValue("Truk", Tbtru.Text);
cmd.Parameters.AddWithValue("Material", Ddmat.SelectedValue);
cmd.Parameters.AddWithValue("Qty", Tbqty.Text);
**cmd.Parameters.AddWithValue("Rate", );**
**cmd.Parameters.AddWithValue("Amount", );**
cmd.Parameters.AddWithValue("Payment", Tbptm.Text);
**cmd.Parameters.AddWithValue("Balance", );**
cmd.Parameters.AddWithValue("MOP", Ddmop.SelectedValue);
cmd.Parameters.AddWithValue("TOS", Ddtos.SelectedValue);
cmd.Parameters.AddWithValue("driver", Tbdri.Text);
con.Open();
int k = cmd.ExecuteNonQuery();
if (k != 0)
{
Lbmsg.Text = "Record inserted successfully into the database";
Lbmsg.ForeColor = System.Drawing.Color.CornflowerBlue;
}
con.Close();
}
How to make Rate, Amount and Balance to take the value from the stored procedure sp1 and update the value?
Create another procedure that accepts Rate, Amount, and Balance as parameters and call that one instead from your web app. That way you don't ruin the functionality of the existing sp1, but still have what you need.
I don't know much about syntax in sql, but I think it looks something like this. Somebody please correct if wrong.
ALTER PROCEDURE [dbo].[sp1_fromWeb]
#mat NVARCHAR(1000) = NULL,
#party NVARCHAR(1000) = NULL,
#place nvarchar(1000)=null,
#truk nvarchar (1000)=null,
#qty numeric (10)=null,
#ptm numeric(10)=null,
#mop nvarchar(100)=null,
#tos nvarchar(100)=null,
#driver nvarchar(100)=null,
#date1 date = null,
#rate numeric(10),
#amount numeric(10),
#balance numeric(10)
AS
BEGIN
DECLARE #sql NVARCHAR(4000);
DECLARE #params NVARCHAR(4000);
SET #sql ='select #rate = ['+#mat+'] from tblcos'+ ' where [Name] = #party'
set #params = '#party nvarchar (1000), #rate NVARCHAR(10) OUTPUT'
exec sp_executesql #sql, #params,#party= #party,#rate = #rate OUTPUT
INSERT INTO tblsls([Party],[Place],[truk], [Material],[Qty], rate,[Amount],[Payment],[Balance],[MOP],[TOS],[driver],[Date])
SELECT #party, #place, #truk, #mat, #qty, #rate, #amount, #ptm, #balance, #mop, #tos, #driver, #date1
END

Conversion failed when converting the varchar value 'AL-DMK2_1' to data type int

For a stored procedure, I get the following exception/error.
"Conversion failed when converting the varchar value AL-DMK2_1 to data type int."
Stored procedure:
ALTER PROCEDURE dbo.sp_generateNewRequestId
(
#Customer varchar(50),
#Network_Type varchar(25),
#Market_Name varchar(50),
#NewRequestId varchar(50) OUTPUT
)
AS
Begin
Declare #MarketCode as varchar(10);
Declare #CustomerPrefix as varchar(10);
SET #MarketCode = (select Market_Code from Customer_Market_Details where Customer = #Customer and Network_Type = #Network_Type and Market_Name = #Market_Name);
SET #CustomerPrefix = (select Customer_Prefix from Customer_Market_Details where Customer = #Customer and Network_Type = #Network_Type and Market_Name = #Market_Name);
Declare #RequestIDPrefix as varchar(20);
SET #RequestIdPrefix = #CustomerPrefix + #MarketCode + '_';
-- Count how many requests you already have with the same request ID Prefix.
Declare #RequestCount as int;
SET #RequestCount = (Select count (*) from request_details where request_id like #RequestIdPrefix + '%');
SET #NewRequestId = #RequestIdPrefix + CAST ((#RequestCount + 1) AS varchar);
While (Exists (Select * from request_details where request_id = #NewRequestId ) )
Begin
SET #RequestCount = #RequestCount + 1;
SET #NewRequestId = #RequestIdPrefix + CAST ((#RequestCount + 1) AS varchar);
end
RETURN #NewRequestId;
END
Calling stored procedure:
using (SqlConnection connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["dbString"].ConnectionString))
{
using (SqlCommand command = new SqlCommand("dbo.sp_generateNewRequestId", connection))
{
command.Parameters.AddWithValue("#Customer", customer);
command.Parameters.AddWithValue("#Network_Type", technology);
command.Parameters.AddWithValue("#Market_Name", market);
command.Parameters.Add("#NewRequestId", SqlDbType.VarChar).Direction = ParameterDirection.Output;
command.Parameters["#NewRequestId"].Size = 50;
command.CommandType = CommandType.StoredProcedure;
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
}
Observations:
when the output parameter is set to #RequestCount, the procedure successfully returns #RequestCount.
But if any other varchar value is attempted to output, the exception with the aforementioned error is thrown. The execution fails at the line command.ExecuteNonQuery().
None of the solutions provided online worked for this error.
Appreciate your help!
Thanks!
If you return anything from a stored procedure, it must be able to be cast to an int as the return type of SqlCommand.ExecuteNonQuery() is an int (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx) and the RETURN statement in SQL Server stored procs should only be use to return integer values (http://msdn.microsoft.com/en-us/library/ms174998.aspx), hence why ExecuteNonQuery has a return type of int, otherwise it would be object.
You're almost there, simply get rid of the return statement in the stored proc so it looks like this:
ALTER PROCEDURE dbo.sp_generateNewRequestId
(
#Customer varchar(50),
#Network_Type varchar(25),
#Market_Name varchar(50),
#NewRequestId varchar(50) OUTPUT
)
AS
Begin
Declare #MarketCode as varchar(10);
Declare #CustomerPrefix as varchar(10);
SET #MarketCode = (select Market_Code from Customer_Market_Details where Customer = #Customer and Network_Type = #Network_Type and Market_Name = #Market_Name);
SET #CustomerPrefix = (select Customer_Prefix from Customer_Market_Details where Customer = #Customer and Network_Type = #Network_Type and Market_Name = #Market_Name);
Declare #RequestIDPrefix as varchar(20);
SET #RequestIdPrefix = #CustomerPrefix + #MarketCode + '_';
-- Count how many requests you already have with the same request ID Prefix.
Declare #RequestCount as int;
SET #RequestCount = (Select count (*) from request_details where request_id like #RequestIdPrefix + '%');
SET #NewRequestId = #RequestIdPrefix + CAST ((#RequestCount + 1) AS varchar);
While (Exists (Select * from request_details where request_id = #NewRequestId ) )
Begin
SET #RequestCount = #RequestCount + 1;
SET #NewRequestId = #RequestIdPrefix + CAST ((#RequestCount + 1) AS varchar);
end
END
And modify your C# code to this:
string newRequestID = "";
using (SqlConnection connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["dbString"].ConnectionString))
{
using (SqlCommand command = new SqlCommand("dbo.sp_generateNewRequestId", connection))
{
command.Parameters.AddWithValue("#Customer", customer);
command.Parameters.AddWithValue("#Network_Type", technology);
command.Parameters.AddWithValue("#Market_Name", market);
command.Parameters.Add("#NewRequestId", SqlDbType.VarChar).Direction = ParameterDirection.Output;
command.Parameters["#NewRequestId"].Size = 50;
command.CommandType = CommandType.StoredProcedure;
connection.Open();
command.ExecuteNonQuery();
newRequestID = (string)command.Parameters["#NewRequestId"].Value;
connection.Close();
}
}

Passing comma delimited parameter to stored procedure in SQL

If I pass call my stored procedure from T-SQL:
exec [dbo].[StoredProcedureName] '''Vijay'', ''Rana'', 1, 0'
in SQL Server Mgmt Studio, it works fine but when I call it from my application it gives me error
Unclosed quotation mark after the character string ''Vijay','Rana',1,0'.
I searched on the google and find this EXEC sp_executesql #FinalQuery but its not working for me
EDIT
I am calling it like
public virtual IDataReader ImportFirefighter(String query)
{
Database database = DatabaseFactory.CreateDatabase();
DbCommand command = database.GetStoredProcCommand("[StoreProcedureName]");
database.AddInParameter(command, "#query", DbType.String, query);
IDataReader reader = null;
try
{
reader = database.ExecuteReader(command);
}
catch (DbException ex)
{
throw new DataException(ex);
}
return reader;
}
EDIT My complete Store Procedure
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
--[dbo].[ImportIntoFirefighter] '''Vijay'',''Rana'',''AC'',''AC'',''VOL'',1,0,0,1,1,''NA'','''',''VOL'','''','''',0,'''','''',0,1,1,'''',0&''Vijay21'',''Rana2'',''AC'',''AC'',''VOL'',1,0,0,1,1,''NA'','''',''VOL'','''','''',0,'''','''',0,1,1,'''',0&''Vijay32'',''Rana3'',''AC'',''AC'',''VOL'',1,0,0,1,1,''NA'','''',''VOL'','''','''',0,'''','''',0,1,1,'''',0&''Vijay42'',''Rana4'',''AC'',''AC'',''VOL'',1,0,0,1,1,''NA'','''',''VOL'','''','''',0,'''','''',0,1,1,'''',0'
ALTER PROCEDURE [dbo].[ImportIntoFirefighter]
#query VARCHAR(MAX)
AS
BEGIN
DECLARE #TotalRecord int
DECLARE #loopcount int
DECLARE #TempQueryList TABLE
(
[ID] INT IDENTITY(1,1),
[VALUE] VARCHAR(1000)
)
DECLARE #Result TABLE
(
[iff_id] INT IDENTITY(1,1),
[last_name] VARCHAR(50),
[first_name] VARCHAR(50),
[email] VARCHAR(50),
[mobile_number] VARCHAR(50),
[error] VARCHAR(max)
)
insert into #TempQueryList (VALUE) (
SELECT SUBSTRING('&' + #query + '&', Number + 1,
CHARINDEX('&', '&' + #query + '&', Number + 1) - Number -1)AS VALUE
FROM master..spt_values
WHERE Type = 'P'
AND Number <= LEN('&' + #query + '&') - 1
AND SUBSTRING('&' + #query + '&', Number, 1) = '&' )
Set #TotalRecord = (select count(*) FROM #TempQueryList)
--select * from #TempQueryList
--Loop For Each Repeated Schedule
set #loopcount = 1
WHILE #loopcount <= #TotalRecord
BEGIN
Declare #SingleQuery varchar(1000)
select #SingleQuery = Value from #TempQueryList where id = #loopcount
BEGIN TRY
--print '[AddFirefighter] ' + #SingleQuery
--SELECT 1/0;
--execute (#SingleQuery)
declare #FinalQuery varchar(max)
-- Select #SingleQuery = LEFT(RIGHT(#SingleQuery, len(#SingleQuery)-1),len(#SingleQuery)-2)
set #FinalQuery = '[AddFirefighter] ' + #SingleQuery
print #FinalQuery
EXEC (#FinalQuery)
END TRY
BEGIN CATCH
insert into #Result (last_name,first_name,email,mobile_number,error) values ( '','','','',ERROR_MESSAGE() )
-- Execute the error retrieval routine.
END CATCH
--print #loopcount
SET #loopcount = #loopcount + 1
END
select * from #Result
--execute (#query)
END
Well ' is the delimiter so it seems to me your string becomes 'Vijay','Rana',1,0 I think you are mixing strings and numerics in the same "string" what you need to do is pass 'Vijay','Rana','1','0' (a string of strings) and then sort things out inside your procedure. To do this your passed string should be something like ' '' Vijay'',''Rana'',''1'',''0'' '. Depending on how you handle things inside your stored proc you may even need '' '''' Vijay'''',''''Rana'''',''''1'''',''''0'''' '' .Best create a simple proc which just returns the string as a test bed
If you are using c# and asp.net, you should set up your parameters in code rather then building a dynamic sql statement. If you already have the stored procedure setup then I'm not seeing a reason to call a dynamic sql statement and building out the parameters in a string.
Here is a example of a parameterized call to sql with a stored procedure.
http://msdn.microsoft.com/en-us/library/yy6y35y8(v=vs.110).aspx
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create the command and set its properties.
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SalesByCategory";
command.CommandType = CommandType.StoredProcedure;
// Add the input parameter and set its properties.
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#CategoryName";
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
parameter.Value = categoryName;
// Add the parameter to the Parameters collection.
command.Parameters.Add(parameter);
// Open the connection and execute the reader.
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
If your stored procedure takes four parameters as it seems to based on your question, you can add the parameters to a SqlCommand and then execute the command.
//Build your command
SqlConnection conn = new SqlConnection(yourConnectionString);
SqlCommand cmd = new SqlCommand("stored_procedure_name", conn);
cmd.CommandType = CommandType.StoredProcedure;
//Define the parameters to pass to the stored procedure
cmd.Parameters.Add("#firstParameter", SqlDbType.NVarChar, 255);
cmd.Parameters.Add("#secondParameter", SqlDbType.NVarChar, 255);
cmd.Parameters.Add("#thridParameter", SqlDbType.Int);
cmd.Parameters.Add("#fourthParameter", SqlDbType.Int);
//Assign Values to the parameters
cmd.Parameters["#firstParameter"].Value = "Vijay";
cmd.Parameters["#secondParameter"].Value = "Rana";
cmd.Parameters["#thirdParameter"].Value = 1;
cmd.Parameters["#fourthParameter"].Value = 0;
//Execute the command
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();

SQL Server stored procedure result returned

I have a stored procedure in SQL Server :
CREATE PROCEDURE [dbo].[GET_AVAILABLE_PLACES]
-- Add the parameters for the stored procedure here
#eventGuid uniqueidentifier,
#placeGuid uniqueidentifier,
#dateGuid dateTime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #ReservedPlaces int;
DECLARE #TotalPlaces int;
SELECT #ReservedPlaces = RESERVED_PLACES FROM dbo.EVENT_DATE_PLACE
WHERE EVENT_GUID = #eventGuid
and DATE_BEGIN = #dateGuid
and PLACE_GUID = #placeGuid
SELECT #TotalPlaces = NUMBER_PLACES FROM dbo.PLACES
WHERE GUID = #placeGuid
RETURN #TotalPlaces - #ReservedPlaces;
END
But I can not seem to read the result returned
private int SelectByStoredProcedureGetAvailablePlaces(string entryParam1, string entryParam2, DateTime entryParam3)
{
int results;
//PlanningElement plan = GetPlanningElement(entryParam1, entryParam2, entryParam3.ToString(), "31/12/2012 00:00:00", "150");
using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
{
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "GET_AVAILABLE_PLACES";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("eventGuid", entryParam1);
sqlCommand.Parameters.AddWithValue("placeGuid", entryParam2);
sqlCommand.Parameters.AddWithValue("dateGuid", entryParam3);
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
results = sqlDataReader.GetInt32(0);
sqlConnection.Close();
}
return results;
}
What is the problem ?
Thanks
The GetInt32 method will read from a selected table output. You want a return value, so you can change the code to be
SqlParameter returnValueParam = sqlcomm.Parameters.Add("#ReturnValue", SqlDbType.Int);
returnValueParam.Direction = ParameterDirection.ReturnValue;
sqlCommand.Parameters.Add(returnValueParam);
...
sqlCommand.ExecuteNonQuery();
result = returnValueParam.Value;
You can alter your stored procedure, replace
RETURN #TotalPlaces - #ReservedPlaces;
By:
SELECT (#TotalPlaces - #ReservedPlaces) AS [AvailablePlaces]
RETURN;
Your can also get a return value from your stored procedure, but that requires some more modifications. See this question for more information.
That particular type of return value must be read by using an additional parameter in the SqlCommand.Parameters collection with direction of System.Data.ParameterDirection.ReturnValue
To read it as you are attempting, your SQL procedure would need to do:
SELECT #TotalPlaces - #ReservedPlaces As MyResult
Then the result will be returned as a resultset instead of a return value.
So my stored procedure must be as this ?
CREATE PROCEDURE [dbo].[GET_AVAILABLE_PLACES]
-- Add the parameters for the stored procedure here
#eventGuid uniqueidentifier,
#placeGuid uniqueidentifier,
#dateGuid dateTime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #ReservedPlaces int;
DECLARE #TotalPlaces int;
SELECT #ReservedPlaces = RESERVED_PLACES FROM dbo.EVENT_DATE_PLACE
WHERE EVENT_GUID = #eventGuid
and DATE_BEGIN = #dateGuid
and PLACE_GUID = #placeGuid
SELECT #TotalPlaces = NUMBER_PLACES FROM dbo.PLACES
WHERE GUID = #placeGuid
SELECT #TotalPlaces - #ReservedPlaces As ReturnValue;
END
And my function as this ?
private int SelectByStoredProcedureGetAvailablePlaces(string entryParam1, string entryParam2, DateTime entryParam3)
{
int results;
//PlanningElement plan = GetPlanningElement(entryParam1, entryParam2, entryParam3.ToString(), "31/12/2012 00:00:00", "150");
using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
{
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "GET_AVAILABLE_PLACES";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("eventGuid", entryParam1);
sqlCommand.Parameters.AddWithValue("placeGuid", entryParam2);
sqlCommand.Parameters.AddWithValue("dateGuid", entryParam3);
SqlParameter returnValueParam = sqlCommand.Parameters.Add("#ReturnValue", SqlDbType.Int);
returnValueParam.Direction = ParameterDirection.ReturnValue;
sqlCommand.Parameters.Add(returnValueParam);
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
result = returnValueParam.Value;
sqlConnection.Close();
}
return results;
}
Try this in yourth strored procedure.
CREATE PROCEDURE [dbo].[GET_AVAILABLE_PLACES]
-- Add the parameters for the stored procedure here
#eventGuid uniqueidentifier,
#placeGuid uniqueidentifier,
#dateGuid dateTime,
#ReservedPlaces int output,
#TotalPlaces int output
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT #ReservedPlaces = RESERVED_PLACES FROM dbo.EVENT_DATE_PLACE
WHERE EVENT_GUID = #eventGuid
and DATE_BEGIN = #dateGuid
and PLACE_GUID = #placeGuid
SELECT #TotalPlaces = NUMBER_PLACES FROM dbo.PLACES
WHERE GUID = #placeGuid
SELECT #TotalPlaces - #ReservedPlaces As ReturnValue;
END
And this in your programm
private int SelectByStoredProcedureGetAvailablePlaces(string entryParam1, string entryParam2, DateTime entryParam3)
{
int results;
//PlanningElement plan = GetPlanningElement(entryParam1, entryParam2, entryParam3.ToString(), "31/12/2012 00:00:00", "150");
using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
{
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = sqlConnection;
sqlCommand.CommandText = "GET_AVAILABLE_PLACES";
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("eventGuid", entryParam1);
sqlCommand.Parameters.AddWithValue("placeGuid", entryParam2);
sqlCommand.Parameters.AddWithValue("dateGuid", entryParam3);
SqlParameter returnValueParam = sqlCommand.Parameters.Add("#ReturnValue", SqlDbType.Int);
returnValueParam.Direction = ParameterDirection.Output;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
result = returnValueParam.Value;
sqlConnection.Close();
}
return results;

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();

Categories