SQL Server 存储过程在查询分析器中执行,但在 C# 中无法正常运行
Posted
技术标签:
【中文标题】SQL Server 存储过程在查询分析器中执行,但在 C# 中无法正常运行【英文标题】:SQL Server stored procedure executes in query analyzer, but does not function properly from C# 【发布时间】:2012-07-18 14:24:17 【问题描述】:我有一个更新我的数据库的存储过程。
它在查询分析器中运行良好,但是当我尝试从我的 C# Web 应用程序运行它时,表没有更新。
我收到以下错误,因此我将 ARITHABORT 设置为“ON”,但我仍然收到错误。
更新失败,因为以下 SET 选项的设置不正确:“ARITHABORT”。验证 SET 选项是否正确使用 在计算列和/或查询上具有索引视图和/或索引 通知和/或 xml 数据类型方法。
C#代码:
p = new SqlParameter("@userAnswers", SqlDbType.VarChar, 1000);
p.Value = "";
p.Value = exam.ExamQuestions.Rows[0].ItemArray[0] + ":" + exam.UserAnswerChoices[0];
for (int x = 1; x < exam.NumQuestions; x++)
p.Value+= ", " + exam.ExamQuestions.Rows[x].ItemArray[0] + ":" + exam.UserAnswerChoices[x];
conn.query("insertAnswers", p);
return p.Value.ToString();
存储过程代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ARITHABORT ON
GO
ALTER PROCEDURE [dbo].[insertAnswers]
@userAnswers VarChar(1000)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @input XML
Set @input = '<Questions><Question id="' + Replace(Replace(@userAnswers, ':', '">'), ', ', '</Question><Question id="') + '</Question>' + '</Questions>'
;WITH ParsedXML AS
(
SELECT
ID = C.value('(@id)[1]', 'int'),
ColumnName = C.value('(.)[1]', 'varchar(10)')
FROM @input.nodes('/Questions/Question') AS T(C)
)
UPDATE CourseQuestions
SET a = CASE WHEN p.ColumnName = 'a' THEN t.a + 1 ELSE t.a END,
b = CASE WHEN p.ColumnName = 'b' THEN t.b + 1 ELSE t.b END,
c = CASE WHEN p.ColumnName = 'c' THEN t.c + 1 ELSE t.c END,
d = CASE WHEN p.ColumnName = 'd' THEN t.d + 1 ELSE t.d END,
e = CASE WHEN p.ColumnName = 'e' THEN t.e + 1 ELSE t.e END,
f = CASE WHEN p.ColumnName = 'f' THEN t.f + 1 ELSE t.f END
FROM CourseQuestions t
INNER JOIN ParsedXml p ON t.QuestionID = p.ID
END
@userAnswers
基本上是一个逗号分隔的字符串(因为我无法将数组发送到 SQL Server)。它看起来像:'1:d,2:a,3:b'
【问题讨论】:
您可以发布您在应用中使用的代码和存储过程代码吗? 什么是SP,你怎么称呼它?编辑; @bluefeet 击败了我 +1 上面添加了SP和C#代码 我在执行查询之前返回了一个值。我修改了我的问题。我现在收到更新失败错误。 如果您在 C# 中构建字符串(不使用 stringbuilder)然后将其重新解析为 XML,那么为什么不首先将其作为 XML 传递呢?我在 2012 年早些时候写了一篇关于这个的博客文章(在 VB.NET 中,但你应该能够弄清楚):nycdotnet.blogspot.com/2012/05/… 【参考方案1】:需要检查的几件事;
Management Studio 中的执行/常规 + 高级选项,确保您没有在那里设置一些奇怪的东西。默认开启的常见嫌疑人是:
QUOTED_IDENTIFIER
ANSI_NULL_DFLT_ON
ANSI_PADDING
ANSI_WARNINGS
ANSI_NULLS
CONCAT_NULL_YIELDS_NULL
ARITHABORT(您已经检查过)
您是否有机会实际发布正在执行的查询,否则我们有点盲目。
【讨论】:
+1 @Mister Bee。每当从 SSMS 执行查询但从代理或外部代码失败时,高级选项通常是罪魁祸首。将数据库选项与 SSMS 中的高级选项进行比较,您可能会发现问题。 @蜜蜂先生。 - 谢谢。这非常有用。我没有将 ARITHABORT 设置在正确的位置,因此没有针对此过程进行更改【参考方案2】:SET ARITHABORT ON 不在存储过程中
ALTER PROCEDURE [dbo].[insertAnswers]
@userAnswers VarChar(1000)
AS
BEGIN
SET NOCOUNT ON
SET ARITHABORT ON
.....
尚未测试。如果这不起作用,请尝试
strSQL = "SET ARITHABORT ON" & chr(13) & chr(10) & "EXEC MySPRoc ..."
conn.Execute strSQL
【讨论】:
就是这样。谢谢!效果很好。【参考方案3】:这里很疯狂,但是 C# 代码是否可以处理已经包含 : 或 ' 的文本?或者您传递的串联字符串是否超过 1000 个字符?
另一方面,您应该使用 StringBuilder 进行连接,因为它在大多数情况下提供了更好的性能,尤其是当您进行许多连接时。
【讨论】:
没有。我打印出字符串以验证它看起来没问题。不过,我会采纳你的建议并使用 StringBuilder。以上是关于SQL Server 存储过程在查询分析器中执行,但在 C# 中无法正常运行的主要内容,如果未能解决你的问题,请参考以下文章