CommandType.Text与CommandType.StoredProcedure的区别

16

显式使用存储过程的CommandType是否有任何好处,而不是只使用文本Command?换句话说,就是

cmd = new SqlCommand("EXEC StoredProc(@p1, @p2)");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("@p1", 1);
cmd.Parameters.Add("@p2", 2);

比...更糟糕

cmd = new SqlCommand("StoredProc");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@p1", 1);
cmd.Parameters.Add("@p2", 2);

编辑:修复了错误的复制粘贴工作(再次)。此外,问题的整个重点是一个数据访问类。我更倾向于能够在一行中传递存储过程名称和参数,而不是为每个参数添加额外的行。

2个回答

9
一种不同之处在于消息泵的处理方式。
我曾经工作的地方有许多批处理程序在晚上运行。其中许多只涉及运行存储过程。我们过去使用SQL Server作业进行调度,但现在改为从.Net程序中调用这些过程。这使我们能够将所有计划任务都放在一个地方,即使是与Sql Server无关的任务也是如此。
它还允许我们在调用过程的.Net程序中构建更好的日志功能,以便来自所有过夜处理的日志记录是一致的。存储过程将使用SQL的print和raiserror函数,而.Net程序将接收并记录这些信息。我们得出的结论是,CommandType.StoredProcedure始终将这些消息缓冲为大约50个一组。无论您在连接上设置了什么选项或在SQL中执行了什么操作,.Net代码都不会看到任何日志事件,直到过程完成或刷新缓冲区为止。CommandType.Text为我们解决了这个问题。
作为一个副问题,我建议在查询参数中使用显式类型。让.Net尝试推断您的参数类型可能会在某些情况下引起问题。

对于服务提供商而言,它的影响比临时查询要小得多。SQL Server只需要进行额外的一次nvarchar到varchar的转换,而不是废弃整个索引。但仍然很糟糕。以datetime为例:如果.Net获取datetime列时出错,而SQL Server无法隐式转换,则会出现问题。 - Joel Coehoorn
我可以看出来,如果你不使用显式的日期时间类型。我会记住的。 - Lurker Indeed
在使用 raiserror 时,您可以使用 WITH NOWAIT 提示来避免消息缓冲。 - MarkPflug
@Mark 现在已经有些年头了,但我还记得当时测试 NOWAIT 时,CommandType.StoredProcedure 仍然被缓冲。但那是四年前的事了。更近期的 .Net 发布可能已经解决了这个问题。 - Joel Coehoorn
@JoelCoehoorn 哦,你可能是正确的。我记得通过存储过程以某种方式使其工作。WITH NOWAIT 是其中一部分解决方案,我认为我还必须设置 SqlConnection.FireInfoMessageEventOnUserErrors 或类似的东西。 - MarkPflug
显示剩余4条评论

4

更简洁。

你正在调用存储过程,为什么不直接使用 CommandType.StoredProcedure


因为我正在编写一个数据库层,允许使用参数数组作为参数。 - Lurker Indeed
5
+1 - “CLARITY”是任何需要考虑可维护性等长期项目的魔法词汇! :) - marc_s

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