LINQ“无法检测到以下存储过程的返回类型”(非临时表)

时间:2012-08-14 18:53:24

标签: sql-server linq

长期潜伏者,这里的第一次海报:)

我决定在这里问,因为我已经厌倦了在Google,SO等搜索。将存储过程从SQL 2005 DB导入到我的网站(FW 4.0,C#)LINQ项目时遇到此错误:

“无法检测到以下存储过程的返回类型”

我有两个问题。 我想说明我没有使用临时表。对于安全措施,这些查询仅以变量名称进行编辑。无论如何,这是工作

ALTER PROCEDURE [dbo].[spMyWorkingProc]
@OS numeric
AS
BEGIN
SET NOCOUNT ON;

DECLARE @sql varchar(5000)

set @sql = '
        SELECT
        *
        FROM MYDB.dbo.MYVIEW 
        WHERE OS = ' + CONVERT(varchar, @OS)

EXEC('
SET NOCOUNT ON
SELECT * FROM
OPENROWSET(''SQLOLEDB'', ''MYDB''; ''user''; ''password'', ''' + @sql + ''')')

END

这是

的那个
ALTER PROCEDURE [dbo].[spNotWorking]
@IDCLIENT int,
@PPNO char(10)
AS
BEGIN
SET NOCOUNT ON;

DECLARE @sql varchar(5000)

set @sql = '
        SELECT
        *
        FROM MYDB.dbo.MYOTHERVIEW
        WHERE ID = ' + CONVERT(VARCHAR, @IDCLIENT) + ' AND PASSPORTNO = ' + @PPNO + ' ORDER BY AGE'

EXEC('
SET NOCOUNT ON
SELECT * FROM
OPENROWSET(''SQLOLEDB'', ''MYDB''; ''user''; ''password'', ''' + @sql + ''')')  

END

以下是我尝试过的内容,以及一些注释和问题:

  • 用户(LINQ和远程服务器)都是db_owner。

  • 如果我只使用一个参数(与哪个参数无关),则非工作存储过程有效。如果我添加一个新的,它就不起作用。

  • 如果我用任何表中的一个简单的select *和两个或多个参数创建一个空SP,它就可以工作(所以没有意义)。

  • 让我们说问题出在EXEC上。如果是这样,第一个SP如何运作?好吧,问题不在那里。 (这是逻辑告诉我的,我猜?)

  • 问题不在于视图,因为如果我使用在工作SP中访问的视图,它就不起作用。

  • 我需要使用提供的查询来执行此操作。我不能使用链接服务器或任何类似的东西来连接到6.5数据库,并且它没有解决或解释为什么第一个SP工作而第二个没有,同时使用相同的方法。 / p>

  • 我尝试将一个参数(取自非工作SP)添加到工作SP并且它可以工作,所以它必须是第二个SP的东西,但我不知道:/

    < / LI>
  • 好的,如果我修改第二个SP并删除@VAR风格的参数并将它们硬编码为单个@sql变量,它就可以完美地运行。所以,我认为必须将变量包含在动态查询(或其他东西)中。

我实际上是在脱掉头发,所以欢迎任何想法和建议!

提前致谢! - DARKGuy

3 个答案:

答案 0 :(得分:7)

ORM代码生成工具(例如Linq2Sql函数导入中的代码生成工具通常在启用SHOWPLAN_ALL设置的情况下运行您的SPROC,而不实际执行proc,以“嗅探”结果集。 / p>

正如您所发现的,这种方法具有动态SQL的局限性,并且通常也存在使用TempDB或具有使用不同模式返回数据的分支的问题。

你的解决方案是一个很好的解决方案,即用一个硬编码替换真正的proc,但它返回代表实际数据的模拟数据。

修改

我看到的另一种模式是将硬编码的“模式”结果嵌入到一个不可调用的条件中,如下所示:

ALTER PROCEDURE [dbo].[someProc]
AS
BEGIN
  SET NOCOUNT ON;
  IF (1 = 0)
    BEGIN
      -- "Cheat" the ORM resultset sniffing by returning an example of the schema.
      -- Casting and name aliasing to ensure the ORM derives the correct types
      SELECT CAST('Hello' AS NVARCHAR(50)) AS Name, CAST (1 AS BIT) AS IsOnline, ...
      RETURN;
    END
    .. rest of the REAL proc goes here

答案 1 :(得分:1)

我也有同样的问题。并且解决方案是在http://developwith.net/2012/07/16/unknown-return-type-linq-to-sql/检查许多站点说明了这个链接中提到的那些3点,但没有提到导致问题的事务。在我的情况下,这是试图阻止提高地狱。删除后,LINQ to SQL表现正常。后来介绍了尝试回收。

答案 2 :(得分:1)

Use below format for writing proc ..

CREATE PROCEDURE PROC_NAME
@variableName nvarchar(150)
AS
IF 1=0 BEGIN
SET FMTONLY OFF
END
BEGIN
SET NOCOUNT ON;
DECLARE @Sql nvarchar(MAX)
SET @Sql = 'SELECT Column1, Column2, Column3 FROM' ;
EXEC sp_executesql @Sql
END

Difference in above format is IF 1=0 BEGIN SET FMTONLY OFF END

Which helps to solve this problem and determine the return type .