C# 从存储过程读取时无法使用CommandBehavior.KeyInfo;“带结果集”;

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] (

在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]
(
       @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)));