C# 从存储过程读取时无法使用CommandBehavior.KeyInfo;“带结果集”;
在SQL Server 2012或更高版本中运行以下操作C# 从存储过程读取时无法使用CommandBehavior.KeyInfo;“带结果集”;,c#,.net,sql-server,C#,.net,Sql Server,在SQL Server 2012或更高版本中运行以下操作 CREATE TABLE TestTable1 ( Dim varchar(500), Measure money, PRIMARY KEY (Dim) ) GO CREATE TABLE TestTable2 ( Dim varchar(500), Measure money, PRIMARY KEY (Dim) ) GO CREATE PROCEDURE [dbo].[usp_InnerSp] (
CREATE TABLE TestTable1
(
Dim varchar(500),
Measure money,
PRIMARY KEY (Dim)
)
GO
CREATE TABLE TestTable2
(
Dim varchar(500),
Measure money,
PRIMARY KEY (Dim)
)
GO
CREATE PROCEDURE [dbo].[usp_InnerSp]
(
@Sql varchar(max)
)
AS
BEGIN
EXEC(@sql)
END
GO
CREATE PROCEDURE [dbo].[usp_ParentSp]
AS
BEGIN
DECLARE @sql VARCHAR(MAX);
SET @sql = 'SELECT t1.* FROM TestTable1 t1 INNER JOIN TestTable2 t2 ON t1.Dim = t2.Dim'
EXEC [dbo].[usp_InnerSp] @sql
WITH RESULT SETS (
(
[Dim] VARCHAR(500),
[Measure] MONEY
)
);
END
GO
在C中创建控制台应用程序#
运行代码时,您会得到以下System.Data.SqlClient.SqlException
exception:
EXECUTE语句失败,因为其WITH RESULT SETS子句为结果集编号1指定了2列,但该语句在运行时发送了3列
我希望.Net运行存储过程,即使出于任何原因它无法检测到主键
问题:你有什么建议?这是.Net或SQL Server中的一个错误?为什么在已经选择[Dim]列(
t1.*
)时还要使用CommandBehavior.KeyInfo
或者干脆不使用CommandBehavior.KeyInfo
(最佳方法)
或改变
WITH RESULT SETS (([Dim] VARCHAR(500), [Measure] MONEY));
WITH RESULT SETS (([Dim] VARCHAR(500), [Measure] MONEY));
到
(最坏的解决方案)
或者将t1.*
更改为t1。测量和
到
(比2好,但仍然比1差)。为什么首先要对结果集使用
?错误与无法检测PK无关;这与由于指定了CommandBehavior.KeyInfo
而添加到结果集中的额外列有关,这反过来又会在执行查询之前设置set NO\u BROWSETABLE ON
。如果运行以下命令,则SSMS中会出现相同的错误:
将不可浏览设置为打开;
EXEC dbo.usp_ParentSp;
因此,该错误也与.NET无关
没有太多的情况需要对结果集执行,所示的示例代码肯定不是其中之一,因此我建议从EXEC
中删除对结果集执行子句。并从SqlDataReader.GetSchemaTable()
获取结果集元数据
另外,使用也不会有任何帮助,因为它不支持使用动态SQL。您可能能够逃脱,因为使用动态SQL是可以的,但它还需要使用带有结果集的子句。当然,将与结果集一起使用
最终没有多大用处,因为“is\u part\u Of_unique\u key”字段为空(至少就您的测试用例而言)。来自MSDN:查询返回列和主键信息。当commandBehavior.KeyInfo用于命令执行时,提供程序将向现有主键和时间戳列的结果集中附加额外的列。也许这是你的问题?你是否尝试过在结果集中为基于keyinfo的主键添加空间?只是一个旁注,如果你需要这样复杂的东西,请重新考虑编写简单的C#代码。如果答案对你有帮助,请接受它,否则奖金将被浪费(你仍然会失去它)提交给Microsoft Connect的bug“简单地不使用CommandBehavior.KeyInfo(最佳方法)”…这意味着Sql客户端的.Net代码基本上是有缺陷的。你证实了我的怀疑。对不起,但我没有说这样的话-你只是用错了,我只是给出了一个快速而肮脏的解决方案…有关更多信息,请参阅srutzky的答案
WITH RESULT SETS (([Dim] VARCHAR(500), [Measure] MONEY, [PrimaryKey] VARCHAR(500)));
WITH RESULT SETS (([Dim] VARCHAR(500), [Measure] MONEY));
WITH RESULT SETS (([Measure] MONEY, [PrimaryKey] VARCHAR(500)));