【问题标题】:Calling SQL Defined function in C#在 C# 中调用 SQL 定义的函数
【发布时间】:2013-06-11 14:47:25
【问题描述】:

我已经在 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

我想在我的 C# 代码中调用这个函数。到目前为止,这是我所拥有的:

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

【问题讨论】:

标签: c# sql visual-studio-2010 sql-server-2008


【解决方案1】:

你不能只调用函数名,你需要编写一个使用 UDF 的内联 SQL 语句:

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

并删除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;
}

【讨论】:

  • 其实因为他做了Totalf.CommandType = CommandType.StoredProcedure他可以直接调用函数名。
  • 不,你是对的,我刚刚意识到他使用的是标量函数,而不是基于表的函数。我不知道这些是否可以通过设置为 StoredProcedure 的 SqlCommand 调用
  • 刷新你的页面,我现在同意你的看法。
  • 更正次数: 1. 您的方法具有 void 返回类型,并且您正在返回其他内容(返回 SAIDA;) 2. 您已初始化 SqlDataAdapter,但从未使用过。 3. 执行标量();返回一个对象,需要类型转换。
  • 它需要很多更正,毕竟它不起作用:SqlDataAdapter da2 = new SqlDataAdapter();没用过? SqlParameter code1 = new SqlParameter("@code", SqlDbType.Int);没用过?
【解决方案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
    

    【讨论】:

    • @RETURN_VALUE 来自哪里?它是由 DeriveParameters 生成的吗?除了 DeriveParameter 调用外,我一直按原样运行此程序,并不断收到“此 SqlParameterCollection 不包含具有 ParameterName '@RETURN_VALUE' 的 SqlParameter。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2013-12-17
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    相关资源
    最近更新 更多