Вызов функции SQL Defined в С#

Я написал эту скалярную функцию в TSQL:

create function TCupom (@cupom int)
returns float
as
begin
    declare @Tcu float;

    select @Tcu = sum (total) from alteraca2 where pedido = @cupom 

    if (@tcu is  null)
        set @tcu = 0;

    return @tcu;
end

Я хочу вызвать эту функцию в моем коде С#. Вот что у меня так далеко:

public void TotalCupom(int cupom)
{ 
    float SAIDA;           
    SqlDataAdapter da2 = new SqlDataAdapter();

    if (conex1.State == ConnectionState.Closed)
    { 
        conex1.Open();
    }

    SqlCommand Totalf = new SqlCommand("Tcupom", conex1);
    SqlParameter code1 = new SqlParameter("@code", SqlDbType.Int);
    code1.Value = cupom ;
    Totalf.CommandType = CommandType.StoredProcedure ;
    SAIDA = Totalf.ExecuteScalar();

    return SAIDA;
}

Ответ 1

Вы не можете просто вызвать имя функции, вам нужно написать встроенный SQL-оператор, который использует UDF:

SqlCommand Totalf = new SqlCommand("SELECT dbo.Tcupom(@code)", conex1);

И удалите CommandType, это не CommandType процедура, а определяемая пользователем функция.

В целом:

public void TotalCupom(int cupom)
{ 
    float SAIDA;           
    SqlDataAdapter da2 = new SqlDataAdapter();
    if (conex1.State == ConnectionState.Closed)
    {
        conex1.Open();
    }
    SqlCommand Totalf = new SqlCommand("SELECT dbo.Tcupom(@code)", conex1);
    SqlParameter code1 = new SqlParameter("@code", SqlDbType.Int);
    code1.Value = cupom;
    SAIDA = Totalf.ExecuteScalar();

    return SAIDA;
}

Ответ 2

...

try
{
    if (connectionState != ConnectionState.Open)
        conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = "udfName";
        cmd.CommandType = CommandType.StoredProcedure;

        foreach (var cmdParam in sqlParams)
        {
            cmd.Parameters.Add(cmdParam);
        }


        var retValParam = new SqlParameter("RetVal", SqlDbType.Int)
        {
            //Set this property as return value
            Direction = ParameterDirection.ReturnValue 
        };

        cmd.Parameters.Add(retValParam);
        cmd.ExecuteScalar();

        retVal = retValParam.Value;
    }
}
finally
{
    if (connectionState == ConnectionState.Open)
        conn.Close();
}

...

Ответ 3

Я хотел вызвать функцию SQL так же, как я вызываю хранимые процедуры, то есть с помощью DeriveParameters, а затем устанавливая значения параметров. Оказывается, это работает со скалярными функциями из коробки, и вы можете использовать ExecuteNonQuery и прочитать RETURN_VALUE. Пожалуйста, посмотрите пример кода ниже:

    public int GetLookupCodeFromShortCode(short tableType, string shortCode)
    {
        using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString))
        {
            conn.Open();

            using (var cmd = new SqlCommand("dbo.fnGetLookupCodeFromShortCode", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandTimeout = 30;
                SqlCommandBuilder.DeriveParameters(cmd);

                cmd.Parameters["@sintTableType"].Value = tableType;
                cmd.Parameters["@vchrShortCode"].Value = shortCode;
                cmd.Parameters["@chrLanguage"].Value = "en";
                cmd.Parameters["@chrCountry"].Value = "en";

                cmd.ExecuteNonQuery();

                return (int)cmd.Parameters["@RETURN_VALUE"].Value;
            }
        }

    }

Код скалярной функции выглядит следующим образом:

CREATE FUNCTION [dbo].[fnGetLookupCodeFromShortCode]( @sintTableType SMALLINT, @vchrShortCode VARCHAR(5), @chrLanguage CHAR(2), @chrCountry CHAR(2))

RETURNS INT

AS

BEGIN

    DECLARE @intLookupCode  INT

    SELECT @intLookupCode = LV.intLookupCode 
    FROM    
    tblLookupValueDesc LVD
        INNER JOIN tblLookupValue LV ON LV.sintLookupTableType = LVD.sintLookupTableType AND LV.intTableKey = LVD.intTableKey
    WHERE   
    LVD.sintLookupTableType = @sintTableType
    AND LVD.vchrShortCode = @vchrShortCode
    AND LVD.chrCountry = @chrCountry
    AND LVD.chrLanguage = @chrLanguage

    RETURN @intLookupCode 

END

GO