DumbCoderX Ответов: 1

C# SQL хранимый proc с возвращаемым параметром


После многих лет отсутствия технологий я снова пытаюсь научиться программировать.. На этот раз с помощью C# (установка сцены, чтобы вы не смеялись)

Я действительно борюсь с возвращением возвращаемого параметра из SQL, хранящегося в моем коде C#..
Надеюсь, вы, ребята, сможете помочь..

Мой Хранимой Процедуре
(И да, я знаю, что это не очень эффективно, но это не моя проблема, и я приведу ее в порядок позже, как только докажу основную концепцию)

Alter PROCEDURE [dbo].[GetFinancialTargetPerformance_12Month] @Year INT, @ReturnVal VarChar(1000) OUTPUT 

AS

Declare @Month1 as varchar(20);
Declare @Month2 as varchar(20);
Declare @Month3 as varchar(20);
Declare @Month4 as varchar(20);
Declare @Month5 as varchar(20);
Declare @Month6 as varchar(20);
Declare @Month7 as varchar(20);
Declare @Month8 as varchar(20);
Declare @Month9 as varchar(20);
Declare @Month10 as varchar(20);
Declare @Month11 as varchar(20);
Declare @Month12 as varchar(20);



Set @Month1 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 1 AND DATEPART(year, WI_Date) = @Year) 
Set @Month2 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 2 AND DATEPART(year, WI_Date) = @Year)
Set @Month3 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 3 AND DATEPART(year, WI_Date) = @Year)
Set @Month4 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 4 AND DATEPART(year, WI_Date) = @Year)
Set @Month5 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 5 AND DATEPART(year, WI_Date) = @Year)
Set @Month6 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 6 AND DATEPART(year, WI_Date) = @Year)
Set @Month7 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 7 AND DATEPART(year, WI_Date) = @Year)
Set @Month8 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 8 AND DATEPART(year, WI_Date) = @Year)
Set @Month9 =  (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 9 AND DATEPART(year, WI_Date) = @Year)
Set @Month10 = (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 10 AND DATEPART(year, WI_Date) = @Year)
Set @Month11 = (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 11 AND DATEPART(year, WI_Date) = @Year)
Set @Month12 = (Select SUM(CAST(Revenue AS MONEY)) From Work_Items  Where DATEPART(month, WI_Date) = 12 AND DATEPART(year, WI_Date) = @Year)

IF(@Month1 is Null) SET @Month1 = '0.00'
IF(@Month2 is Null) SET @Month2 = '0.00'
IF(@Month3 is Null) SET @Month3 = '0.00'
IF(@Month4 is Null) SET @Month4 = '0.00'
IF(@Month5 is Null) SET @Month5 = '0.00'
IF(@Month6 is Null) SET @Month6 = '0.00'
IF(@Month7 is Null) SET @Month7 = '0.00'
IF(@Month8 is Null) SET @Month8 = '0.00'
IF(@Month9 is Null) SET @Month9 = '0.00'
IF(@Month10 is Null) SET @Month10 = '0.00'
IF(@Month11 is Null) SET @Month11 = '0.00'
IF(@Month12 is Null) SET @Month12 = '0.00'

Set @ReturnVal = ( CONCAT( @Month1 + ',', @Month2 + ',', @Month3 + ',',  @Month4 + ',' ,  @Month5 + ',' ,  @Month6 + ',' ,  @Month7 + ',' ,  @Month8 + ',' ,  @Month9 + ',', @Month10 + ',' , @Month11 + ',' ,  @Month12 ))

Select @ReturnVal




Мой код вызова C#

private void CreateChart()
        {
            string RevenueString = string.Empty;
            int Year = 0;

            //Grab Year - Hardcoded for now (TO DO) 
            Year = 2020;




 SqlConnection SQLCONNECT = new SqlConnection(sSQLConnection);


            try
            {
                if (SQLCONNECT.State == ConnectionState.Closed)
                {
                    SQLCONNECT.Open();

//My connection opens so this isnt the issue...(ive not included my connection string but its good and works..
                }

                SqlCommand cmd = new SqlCommand("dbo.GetFinancialTargetPerformance_12Month", SQLCONNECT);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Year", Year);
                
                SqlParameter RuturnValue = new SqlParameter("@ReturnVal", SqlDbType.VarChar);
                RuturnValue.Direction = ParameterDirection.Output;
                cmd.Parameters.Add("@ReturnVal", System.Data.SqlDbType.VarChar).Direction = System.Data.ParameterDirection.ReturnValue;

//Here lies the issue... The next command just bombs out with a generic error message 
                cmd.ExecuteNonQuery();

                RevenueString = (string)cmd.Parameters["@ReturnVal"].Value;
            }
            catch
            {

            }
            finally
            {
                SQLCONNECT.Close();
            }





Спасибо, что нашли время почитать...



Что я уже пробовал:

Разные статьи, но безрезультатно..

ZurdoDev

Мое личное предпочтение-не использовать выходные параметры, а просто использовать оператор select.

Тогда вы можете использовать команду.ExecuteScalar (), если возвращается только одна строка и один столбец, или вы можете использовать ExecuteReader() и получить DataReader и получить доступ ко всем возвращаемым полям и строкам.

MadMyche

Этот SP фактически заканчивается оператором SELECT

ZurdoDev

Да, но ошибка связана с выходным параметром.

MadMyche

Любопытно, что это за общее сообщение об ошибке... Какой-то код в Catch блок скорее всего поможет

DumbCoderX

Когда я копался в исключении, оно было немного более значимым, чем то, о котором сообщалось origioanlly (предположительно, свернутое каким-то образом)

Сообщение Об Исключении =
"Процедура или функция 'GetFinancialTargetPerformance_12month' ожидает параметр '@ReturnVal', который не был указан."


Но из моего кода я считаю, что это предусмотрено

Confused.com

MadMyche

Вы правы, что это предусмотрено; однако для него нет значения, установленного в вызывающем коде, и нет значения по умолчанию в SProc. Я обновлю свой ответ тем, как исправить это

1 Ответов

Рейтинг:
8

MadMyche

Возможно, вы захотите попробовать это для вызова C#

   SqlCommand cmd = new SqlCommand("dbo.GetFinancialTargetPerformance_12Month", SQLCONNECT);

   cmd.CommandType = CommandType.StoredProcedure;
   cmd.Parameters.AddWithValue("@Year", Year);

   SqlParameter RuturnValue = new SqlParameter("@ReturnVal", SqlDbType.VarChar);
   RuturnValue.Direction = ParameterDirection.Output;

// cmd.Parameters.Add("@ReturnVal", System.Data.SqlDbType.VarChar).Direction = System.Data.ParameterDirection.ReturnValue;
   cmd.Parameters.Add(RuturnValue);

// Here lies the issue... The next command just bombs out with a generic error message 
   cmd.ExecuteNonQuery();

// RevenueString = (string)cmd.Parameters["@ReturnVal"].Value;
   RevenueString = (string)RuturnValue.Value;
Или другой вариант, который вы представили, заключается в том, что последний оператор в нашей хранимой процедуре
Select @ReturnVal
Так что во всей реальности вы можете использовать ExecuteScalar метод в вашем вызывающем коде, сжимающийся таким образом вниз
SqlCommand cmd = new SqlCommand("dbo.GetFinancialTargetPerformance_12Month", SQLCONNECT);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Year", Year);
cmd.Parameters.AddWithValue("@ReturnVal", string.Empty);
RevenueString = (string)cmd.ExecuteScalar();

Обновление основываясь на фактическом сообщении об ошибке теперь в комментариях

Есть 2 параметра, определенные в хранимой процедуре, и есть 2, определенные в вызывающем коде. Тем не менее, @ReturnValue не имеет значения, связанного с ним в вызывающем коде, но процедура ожидает его; таким образом, сообщение.

Я нахожу самый простой способ исправить это для выход parameters-это установка значений по умолчанию для них в части определения параметров хранимой процедуры; что-то вроде этого должно позаботиться об этом
ALTER PROCEDURE dbo.GetFinancialTargetPerformance_12Month (
   @Year      INT,
   @ReturnVal VARCHAR (1000) = '' OUTPUT 
) AS


DumbCoderX

Большое вам спасибо..

Идиопатический должен добавить размер param к следующей строке

SqlParameter("@ReturnVal", SqlDbType.VarChar,1000);

Но в остальном это доставляло удовольствие..

Еще раз спасибо, научил меня многому