【问题标题】:ExecuteScalar always returns null when calling a scalar-valued function调用标量值函数时,ExecuteScalar 始终返回 null
【发布时间】:2011-10-19 10:03:43
【问题描述】:

为什么返回 null?

//seedDate is set to DateTime.Now; con is initialized and open. Not a problem with that
using (SqlCommand command = new SqlCommand("fn_last_business_date", con))
{
       command.CommandType = CommandType.StoredProcedure;
       command.Parameters.AddWithValue("@seed_date", seedDate);//@seed_date is the param name
       object res = command.ExecuteScalar(); //res is always null 
}

但是当我直接在数据库中这样调用它时:

select dbo.fn_last_business_date('8/3/2011 3:01:21 PM') 
returns '2011-08-03 15:01:21.000' 

这是我从代码中调用它时期望看到的结果

为什么,为什么,为什么?

【问题讨论】:

    标签: c# sql sql-server sql-function


    【解决方案1】:

    尝试:

    using (SqlCommand command = new SqlCommand("select dbo.fn_last_business_date(@seed_date)", con))
    {
           command.CommandType = CommandType.Text;
           command.Parameters.AddWithValue("@seed_date", seedDate);//@seed_date is the param name
           object res = command.ExecuteScalar(); //res is always null 
    }
    

    【讨论】:

    • 从 sql 函数返回值没有问题。它做它应该做的。我的问题出在 c# 代码上。如果我传入有效的@seed_date,我不明白为什么结果总是为空;如果有帮助,我可以粘贴 sql_function 代码。我的 sql_function 唯一特别的地方是它使用递归……这可能是我的问题吗?那会很奇怪。
    • fn_last_business_date 实际上是一个存储过程吗?如果不确定,请确保添加选择并使命令类型为文本(请参阅我的编辑)
    • 呵呵呵呵,我刚刚回复 gbn 我曾想过这样做,但我认为它不优雅;)我会尝试它,如果它有效,我会给予你应有的信任。谢谢。
    • 归功于什么?阅读我的答案中的链接,然后将原始 SQL 更改为某些 .net?请参阅“已编辑:xx 分钟前”链接...
    • 好的,我最终这样做了:SqlCommand command = new SqlCommand("select dbo.fn_last_business_date('"+seedDate.ToShortDateString()+"')", con) 并且它起作用了。我得带着这个离开。赞成你的建议。谢谢!
    【解决方案2】:

    您实际上得到了一个未被捕获的错误。不像调用存储过程那样调用标量 udf。

    要么将 udf 包装在存储过程中,要么更改语法。我实际上不确定那是什么,因为它并不常见......

    啊哈:看看这些问题:

    【讨论】:

    • 谢谢,有没有调用函数的例子?我想创建一个这样的语句: new SqlCommand("select dbo.fn_last_business_date("+seedDate.ToString()+") 然后执行 command.CommandType=CommandType.Text 但这看起来并不“优雅”:P
    • @gbn:感谢您的链接。他们都很有帮助。我不知道这是在 .NET 中调用 sql 函数的“正确”方式。也赞成您的回答。
    【解决方案3】:

    为什么大家都坚持select这个语法?..

    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("calendar.CropTime", c))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@RETURN_VALUE", SqlDbType.DateTime).Direction = ParameterDirection.ReturnValue;
        cmd.Parameters.AddWithValue("@d", DateTime.Now);
    
        cmd.ExecuteNonQuery();
    
        textBox1.Text = cmd.Parameters["@RETURN_VALUE"].Value.ToString();
    
    }
    

    【讨论】:

    • 我想知道没有发表评论的投票者是否真的证明了上述错误,或者只是想嘿,这不是我通常的做法。
    • 可能是第一个,我同意你的回答:D,这是一个功能,它应该可以工作,我猜他投了反对票,因为它与帖子无关,对于文本框和calendar.CropTime 和日期参数 xD,也许是为了那个 (+1)
    • 就像注释一样,如果我没记错的话,只是为了明确一点,当你使用函数时,返回值必须是参数集合的第一个参数,如果函数需要更多的参数。
    • +1 - 这种技术有效。但请注意以下警告 - 仅当 UDF 是标量值 UDF 时,以这种方式将 UDF 视为存储过程才有效。如果 UDF 是一个值为 1 的表(内联或多语句),那么您将收到如下错误消息:“对过程 'Name_Of_UDF' 的请求失败,因为 'Name_Of_UDF' 是一个表值函数对象。”
    • @Moe 哦,是的。调用 scalar UDF 是 OP 问题的重点。
    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 2023-03-14
    • 2015-07-03
    • 2012-11-30
    • 1970-01-01
    相关资源
    最近更新 更多