当调用标量值函数时,ExecuteScalar总是返回null

7
为什么会返回 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' 

当我从代码中调用它时,我期望看到的结果是什么?

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

3个回答

28

为什么每个人都坚持使用 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();

}

6
我不知道那个没有留下评论的投票者是否真的证明了上述内容是错误的,还是只是认为:“嘿,这不是我通常的做法。” - GSerg
可能是第一个,我同意你的答案:D,它是一个函数,应该可以工作,我猜他给了一个踩因为它与帖子无关,对于文本框和日历。CropTime和日期参数xD,也许因为这个(+1)。 - Hector Sanchez
2
只是作为评论,如果我记得正确的话,为了明确起见,当您使用函数时,返回值必须是参数集合的第一个参数,如果该函数需要更多参数。 - Hector Sanchez
1
+1 - 这种技术是可行的。但请注意以下警告 - 如果将UDF视为存储过程使用,这种方法只适用于标量值UDF。如果UDF是表值函数(内联或多语句),则会出现错误,如:“由于'Name_Of_UDF'是一个表值函数对象,因此'Name_Of_UDF'的过程请求失败。” - Moe Sisko
2
@Moe 是的。调用标量UDF是OP问题的关键点。 - GSerg

8

尝试:

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唯一特殊的地方就是它使用递归...那可能是个问题吗?这会很奇怪。 - Icarus
fn_last_business_date实际上是一个存储过程吗?如果不是,请确保添加SELECT并将命令类型更改为文本(请参阅我的编辑)。 - jenson-button-event
哈哈哈,我刚刚回复了gbn,说我曾考虑过这样做,但我觉得这不够优雅;我会尝试一下,如果行得通的话,我会给你应有的荣誉。谢谢。 - Icarus
为什么要给信用?阅读我回答中的链接,然后将原始SQL更改为某些.NET?请参见“编辑:xx分钟前”链接... - gbn
好的,我最终做出了这个:SqlCommand command = new SqlCommand("select dbo.fn_last_business_date('"+seedDate.ToShortDateString()+"')", con),它起作用了。我只能接受这个结果了。赞同了你的建议。谢谢! - Icarus
@gbn 不要自作多情了,我没有看到任何链接。 - jenson-button-event

1

谢谢,您有如何调用函数的示例吗?我考虑创建一个语句,例如:new SqlCommand("select dbo.fn_last_business_date("+seedDate.ToString()+"),然后执行command.CommandType=CommandType.Text,但那看起来不太“优雅” :P - Icarus
@gbn:感谢提供链接。它们都很有帮助。我不知道这是在.NET中调用SQL函数的“正确”方式。我也点赞了你的答案。 - Icarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接