7

长期潜伏者,第一次在这里发帖:)

我决定在这里问,因为我已经厌倦了在 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 工作而第二个不工作,同时使用相同的方法。

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

  • 好的,如果我修改第二个 SP 并删除 @VAR 样式的参数并将它们硬编码到单个 @sql 变量中,它会完美运行。所以,我认为它必须是将变量包含到动态查询(或其他东西)中。

我真的是在扯我的头发,所以欢迎任何想法和建议!

提前致谢!- 黑暗小子

4

3 回答 3

8

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

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

您的解决方案是一个很好的解决方案,即将实际过程替换为硬编码但返回代表实际数据的模拟数据。

编辑

我见过的另一种解决此问题的模式是将硬编码的“模式”结果嵌入到不可调用的条件中,如下所示:

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
于 2012-08-14T19:55:00.080 回答
1

I too had same issue. And solution was at http://developwith.net/2012/07/16/unknown-return-type-linq-to-sql/ Checking many sites says about those 3 points mentioned in this link but nowhere mentioned about transaction causing the problem. In my case, it was try catch block raising the hell. After removing it, LINQ to SQL behaved normal. Later introduced the try catch back.

于 2014-08-29T17:54:29.133 回答
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 .

于 2016-04-21T22:26:24.730 回答