【问题标题】:The return types for the following stored procedures could not be detected无法检测到以下存储过程的返回类型
【发布时间】:2022-02-11 04:54:31
【问题描述】:

在 dbml 文件中拖放存储过程时出现此错误:

未知返回类型
无法检测到以下存储过程的返回类型。在“属性”窗口中设置每个存储过程的返回类型。

我该如何解决这个错误?

【问题讨论】:

    标签: linq-to-sql


    【解决方案1】:

    当设计者无法确定 SP 的返回类型时,就会出现此问题。
    相同的问题和解决方案描述here
    如何使用LINQ to SQL获取多个结果集的过程

    基本上这是链接中的解决方案:

    避免在存储过程中使用 #temp 表,而是可以使用如下表类型变量 (@TempTable)

    例如:

    DECLARE @TempTable TABLE
    (
      AttributeID INT,
      Value NVARCHAR(200)
    )
    
    INSERT INTO @TempTable Select * from Attribute
    
    OR
    
    --Execute SP and insert results into @TempTable
    INSERT INTO @TempTable Exec GetAttribute @Id
    

    您可以执行您对#Temp 表执行的所有操作,例如 加入、插入、选择等。

    【讨论】:

    • 这篇博文可能有一天会消失。您可以在答案中包含解决方案吗? (当然,保留原始出处。)谢谢!
    • 博客文章状态基本上是:将#TempTables 转换为@TableVariables。我这样做了,这解决了这个问题。感谢您的信息。
    • 在此处发布答案的解决方案 - 用表变量替换临时表对我来说是可行的解决方案。
    • 感谢您的参考,节省我的时间:)
    【解决方案2】:

    在参数声明之后添加这些行

    AS
    IF 1=0 BEGIN
     SET FMTONLY OFF
    END
    

    在此之后,编写BEGIN并开始您的程序工作。

    【讨论】:

      【解决方案3】:

      我在我的 SQL 中使用了一个临时表并收到此错误。我将临时表转换为表变量,这解决了我的问题。

      【讨论】:

      • 来自:--------- CREATE TABLE #tmptable( [Start Time] DATE, [End Time] DATE );从@tmptable中选择*; ---------- to this: ---------- 声明@tmptable table ( [Start Time] DATE, [End Time] DATE );从@tmptable中选择*; ----------
      【解决方案4】:

      这也可能是访问权限的问题。如果存储过程无权访问该表,则会出现相同的错误。我有一个查询从另一个我没有权限的数据库中选择数据(实际上运行 Visual Studio 连接的帐户没有权限)并且我收到了同样的错误。添加适当的权限后,一切正常。

      尝试在 VS2010 中执行存储过程(通过右键单击服务器资源管理器并选择“执行”)帮助我解决了问题。

      【讨论】:

      • 这是我的问题。我有一个存储过程正在访问另一个数据库中的表。我在设计时有访问权限,但我忘记了我的应用程序是作为没有访问权限的受限帐户运行的。
      • 出现此问题的sql登录没有数据库的所有者角色。为其分配所有者角色后,问题就消失了。
      【解决方案5】:

      我刚刚向我的 DBML 添加了大约 300 个存储过程,并且遇到了这里和其他地方提到的许多问题。

      根据我的亲身经历,总结一下“无法检测到以下存储过程的返回类型”错误的原因和解决方案。请注意,下面描述的问题可能发生在您遇到错误的 SP 中,或者 从该 SP 直接或间接调用的任何其他 SP 中。

      • 使用“+”符号将整数与字符串连接起来。 对整数使用 CAST(),或者在 SQL2012 或更高版本中使用 CONCAT() 语句。
      • 引用其他数据库中的表。 显然是权限问题。我无法解决这个问题。
      • 对 XP_CMDSHELL 的任何直接或间接调用。 我无法解决这个问题。
      • 直接或间接调用其他存储过程的任何语法错误。 修复对 SP 的调用。
      • 临时表。 用表变量替换临时表。
      • SET QUOTED_IDENTIFIER OFF 正在使用中,但正在编辑的表上有一个索引视图。 *将 set 语句更改为 SET QUOTED_IDENTIFIER ON。*

      【讨论】:

        【解决方案6】:

        原因:您的存储过程将返回一个复杂类型。即多个结果或使用临时表。

        分辨率

        这完全取决于您的存储过程在做什么。有用的链接

        1. http://odetocode.com/code/365.aspx
        2. http://riteshkk2000.blogspot.com/2010/08/error-unknown-return-type-return-types.html

        【讨论】:

        • 更简洁的答案只是说使用表变量代替存储过程中的任何临时表。这就是我的解决方法。
        【解决方案7】:

        以防万一其他人遇到这种情况,我自己也经历过。

        在我的例子中,我在插入语句中引用了一个表,该表不再存在于我的架构中。仔细检查我的代码,发现我正在插入一个名为“Account”的表,该表现在称为“tblAccount”。 Visual Studio 在保存 sp 时没有抛出任何错误,但我在尝试将 sp 添加到 dbml 文件时遇到了同样的错误。

        希望这对其他人有帮助。

        【讨论】:

          【解决方案8】:

          我也遇到了这个问题 - 必须注释掉构建多边形的代码:

          declare
              @MapBounds geography
              ;
          
          select
              @MapBounds = geography::STGeomFromText('POLYGON((' + 
                  cast(@NorthEastLng as varchar) + ' ' + cast(@NorthEastLat as varchar) + ', ' +  
                  cast(@SouthWestLng as varchar) + ' ' + cast(@NorthEastLat as varchar) + ', ' +  
                  cast(@SouthWestLng as varchar) + ' ' + cast(@SouthWestLat as varchar) + ', ' +  
                  cast(@NorthEastLng as varchar) + ' ' + cast(@SouthWestLat as varchar) + ', ' + 
                  cast(@NorthEastLng as varchar) + ' ' + cast(@NorthEastLat as varchar) + 
                  '))', 4326)
              ;
          

          将它添加到 dmbl 后,我取消了对代码的注释,它就像一个冠军!

          【讨论】:

            【解决方案9】:

            我也遇到了问题(VS 2012,SQL Server 2008R2)。在我的例子中,它是 + 运算符和代码中各种 CAST 语句的组合。我还没有找到用 VisualStudio 喜欢的东西替换它们的方法,但我想出了一个解决方法:

            解决方法“虚拟 SELECT”

            • 创建一个包含您需要返回的所有字段的虚拟 SELECT 语句。例如:
                select 'bla bla' as field1, 123123 as field2, 'asñfs' as field3
            
            • 注释掉您的 SP 代码,然后将虚拟 SELECT 留在您的 SP 中。
            • 在 O/R 设计器中添加您的 SP 并保存(它应该知道没有错误消息)
            • 恢复您的原始 SP(保留虚拟 SELECT 作为注释以供将来使用)

            【讨论】:

              【解决方案10】:

              您不妨考虑使用 CONCAT() 方法而不是 '+' 来连接字符串。由于我没有使用临时表,但仍然遇到这个问题。我发现使用 '+' 连接字符串会触发此操作。

              就我而言,我使用的是这个:

              SET @errorMessage = CONCAT('Update (ID=', @pnID, ') failed. Name already exists.');
              

              代替:

              SET @errorMessage = 'Update (ID=' + @pnID + ') failed. Name already exists.';
              

              【讨论】:

                【解决方案11】:

                在尝试将存储过程添加到 DBML (LINQ) 文件时遇到了这个问题。

                做了一些研究,我发现这通常发生在存储过程返回多个结果或使用#temp 表作为最终选择时。

                对我有用的解决方案是创建一个新的存储过程,将原始存储过程结果的结果包装到与临时表具有相同列的表变量中。

                我的包装存储过程看起来像这样:

                DECLARE @NewPrograms TABLE (
                    Campaign_Number int,
                    Campaign_Display nvarchar(255)
                )
                
                INSERT INTO @NewPrograms
                    EXEC [dbo].[Original_Stored_Proc_With_Temp_Table_Result] @Program_ID
                
                
                Select * 
                From @NewPrograms
                

                打开您的 DBML 文件,拖放到您的新包装存储过程中。

                【讨论】:

                • 没有其他解决方案对我有用,除了这个。我有一个相当复杂的 SP,其中包含多个 WITH 子句和生成的临时表。在我将上述技术与包装器 SP 一起使用之前,无法将临时表转换为表变量。谢谢!
                【解决方案12】:

                确保存储过程运行时不会出错。刚遇到这个问题,我假设制作存储过程的人已经测试过了,但自己没有尝试。

                【讨论】:

                  【解决方案13】:

                  我找到的解决方案...我在顶部 (IF) 上放置了一个条件不正确的 SELECT,并创建了一个变量表,其中包含他想要退出的结果,然后“ELSE”使事情正确。第一部分只有在您了解我想要的流程输出的情况下。看我的例子

                  ALTER PROCEDURE [dbo].[SS_getSearchedProductsDetailsNew]
                  (
                   @mk int,
                   @md int,
                   @yr int = 0,
                   @caroption int = 0,
                   @condition int = 0,
                   @producttype int = 0 ,
                   @option int = 0, 
                   @coloroption int = 0
                  )
                  AS
                  
                  declare @sql nvarchar(max)
                  
                  Begin
                    if  @mk = 0 and @md = 0 and @yr = 0
                      begin
                          Declare @TempTable2 TABLE(
                              ProductID numeric(10),
                              TypeName nvarchar(50),
                              MakeID numeric(10),
                              ModelID numeric(10),
                              ConditionID numeric(10),
                              CarOptionsID numeric(10),
                              OptionsID numeric(10),
                              ColorOptionsID numeric(10),
                              Make nvarchar(50),
                              Model nvarchar(50),
                              YearID numeric(5),
                              Color  nvarchar(50),
                              ProductType nvarchar(50),
                              CarOptionName nvarchar(50),
                              OptionName nvarchar(50),
                              ColorOptionName nvarchar(50),
                              ConditionName nvarchar(50),
                              Notes  nvarchar(500),
                              Price money,
                              cog money)
                  
                              select * from @TempTable2
                  
                      end 
                  
                     else
                     begin
                  
                  
                    select @sql = '
                      declare @theNotes  nvarchar(500)
                      declare @theMake numeric(10), @theModel numeric(10), @theYear numeric(10)
                      declare @makeName nvarchar(50), @modelName nvarchar(50), @ID numeric(5)
                      declare @theProductType nvarchar(50), @theTypeName nvarchar(50)
                      declare @theColor nvarchar(50),@theProductID numeric(10)
                      declare @theCondition numeric(10),@theCarOption numeric(10) , @theOption numeric(10), @theColorOption numeric(10)
                      declare @theConditionName nvarchar(50),@theCarOptionName nvarchar(50), @theOptionName nvarchar(50),@theColorOptionName nvarchar(50)
                      declare @thePrice money, @theCog money
                  
                  
                      declare @HoldingTable table(
                          ID numeric identity,
                          ProductID numeric(10),
                          MakeID numeric(10),
                          ModelID numeric(10),
                          ConditionID numeric(10),
                          CarOptionsID numeric(10),
                          OptionsID numeric(10),
                          ColorOptionsID numeric(10),
                          Make nvarchar(50),
                          Model nvarchar(50),
                          YearID numeric(5),
                          Color  nvarchar(50),
                          ProductType nvarchar(50),
                          Notes  nvarchar(500),
                          Price money,
                          cog money);
                  
                          INSERT INTO @HoldingTable (ProductID,MakeID, ModelID , ConditionID, CarOptionsID,OptionsID,ColorOptionsID, Make ,Model,YearID,Color,    ProductType, Notes, Price, cog) 
                          SELECT   
                              ProductNumber as ProductID,
                              tblProductsForSale.MakeID as MakeID,
                              tblProductsForSale.ModelID as ModelID ,
                              ConditionID,
                              CarOptionsID,
                              OptionsID,
                              ColorOptionsID,
                              tblVehicleMake.Make as Make ,
                              tblVehicleModel.Model as Model,
                              YearID,
                              Color,
                              ProductType, Notes,
                              tblProductsForSale.ResalePrice as Price,
                              tblProductsForSale.SellPrice as cog
                                  from    tblProductsForSale, tblVehicleMake, tblVehicleModel where 
                                  tblProductsForSale.MakeID = tblVehicleMake.MakeID and  
                                  tblProductsForSale.ModelID = tblVehicleModel.ModelID 
                                  and tblProductsForSale.ProductStatus=''available'' and tblProductsForSale.Custom=0'
                  
                          if(@mk > 0)
                          begin       
                              select @sql = @sql + ' and tblProductsForSale.MakeID = ' + convert(varchar, @mk)
                          end
                          if @md > 0
                          Begin
                              select @sql = @sql + ' and tblProductsForSale.ModelID = ' + convert(varchar, @md)
                          End
                          if @yr > 0
                          begin
                              select @sql = @sql + ' and tblProductsForSale.YearID = ' + convert(varchar, @yr)            
                          end
                          if @caroption > 0
                          begin
                              select @sql = @sql + ' and tblProductsForSale.CarOptionsID = ' + convert(varchar, @caroption)
                          end 
                          if @producttype > 0
                          begin
                              select @sql = @sql + ' and tblProductsForSale.ProductType = ''' + convert(varchar,@producttype)  + ''''
                          end 
                          if @option > 0
                          begin
                              select @sql = @sql + ' and tblProductsForSale.OptionsID = ' + convert(varchar, @option)
                          end 
                          if @coloroption > 0
                          begin
                              select @sql = @sql + ' and tblProductsForSale.ColorOptionsID = ' + convert(varchar, @coloroption)
                          end     
                  
                          --select @sqlInsert = 'INSERT INTO @HoldingTable (ProductID,MakeID, ModelID , ConditionID, CarOptionsID,OptionsID,ColorOptionsID, Make ,Model,YearID,Color, ProductType, Price, cog) '
                          --select @sqlExec = @sqlInsert + @sql
                  
                  
                          --select * from @HoldingTable
                          select @sql = @sql + 'Declare @TempTable2 TABLE(
                              ProductID numeric(10),
                              TypeName nvarchar(50),
                              MakeID numeric(10),
                              ModelID numeric(10),
                              ConditionID numeric(10),
                              CarOptionsID numeric(10),
                              OptionsID numeric(10),
                              ColorOptionsID numeric(10),
                              Make nvarchar(50),
                              Model nvarchar(50),
                              YearID numeric(5),
                              Color  nvarchar(50),
                              ProductType nvarchar(50),
                              CarOptionName nvarchar(50),
                              OptionName nvarchar(50),
                              ColorOptionName nvarchar(50),
                              ConditionName nvarchar(50),
                              Notes  nvarchar(500),
                              Price money,
                              cog money)
                  
                          WHILE Exists(Select * from @HoldingTable )
                              begin
                                  Select @ID = ID FROM @HoldingTable 
                                  Select @theProductId = ProductID from @HoldingTable
                                  Select @theMake = MakeID  from @HoldingTable
                                  Select @theModel = ModelID  from @HoldingTable
                                  Select @theCondition = ConditionID  from @HoldingTable
                                  Select @theCarOption = CarOptionsID  from @HoldingTable
                                  Select @theOption = OptionsID  from @HoldingTable
                                  Select @theColorOption = ColorOptionsID  from @HoldingTable
                                  Select @theYear = YearID from @HoldingTable
                                  Select @theColor = Color from @HoldingTable
                                  Select @theProductType = ProductType from @HoldingTable
                                  Select @theTypeName = TypeName from tblProductType WHere ProductTypeID = cast (@theProductType as numeric(10))
                  
                                  Select @thePrice = Price from @HoldingTable
                                  Select @theCog = cog from @HoldingTable
                  
                                  Select @theConditionName = ConditionName from tblConditions Where ConditionID = @theCondition
                                  Select @makeName = Make from tblVehicleMake Where MakeID = @theMake
                                  Select @modelName = Model from tblVehicleModel Where ModelID = @theModel
                                  Select @theCarOptionName = CarOptionsName from tblCarOptions Where CarOptionsID = @theCarOption
                                  Select @theOptionName = OptionsName from tblOptions Where OptionsID = @theOption
                                  Select @theColorOptionName = ColorOptionsName from tblColorOptions Where ColorOptionsID = @theColorOption
                  
                                  Select @theNotes = Notes from @HoldingTable
                                  Select @theProductType = ProductType from @HoldingTable
                  
                                  INSERT INTO @TempTable2  (ProductID,TypeName,MakeID,ModelID,ConditionID ,CarOptionsID,OptionsID ,ColorOptionsID ,Make , Model , YearID ,Color,   ProductType, CarOptionName ,OptionName,ColorOptionName ,ConditionName, Notes, Price, cog)
                                  VALUES (@theProductId,@theTypeName, @theMake, @theModel, @theCondition, @theCarOption,@theOption,@theColorOption, @makeName,@modelName, @theYear, @theColor,@theProductType, @theCarOptionName, @theOptionName, @theColorOptionName, @theConditionName, @theNotes,  @thePrice , @theCog )
                                  DELETE FROM @HoldingTable  Where ID = @ID
                              end
                  
                              Select * from @TempTable2 order by ProductID '
                  
                  
                              end
                              exec ( @sql )
                  
                      End
                  

                  【讨论】:

                    【解决方案14】:

                    我在这方面做了很多努力并得出结论,如果您的存储过程是动态的并且与字符串结合,您有时会遗漏一些东西。所以在导入 Visual Studio DBML 导入/更新时无法执行/测试该过程,因此返回类型保持未定义,一旦您更正了过程(您正在构建以执行的查询字符串),您就可以毫无问题地添加过程。

                    【讨论】:

                      【解决方案15】:

                      我也有这个错误,最后我发现我已经更改了一个表字段名称,并且在程序中它还没有更改它,所以在添加到 dbml 时它显示了一个错误。 现在您可以在您的程序和表格中检查这些字段是否相同。

                      我希望这个经验是有用的。

                      【讨论】:

                        【解决方案16】:

                        解决此问题的简单方法是(2019 年 12 月)

                        • 1 只需在#tmp 前面加上双# => ##tmp
                        • 2 注释掉 DROP TABLE #tmp => --DROP TABLE #tmp
                        • 执行存储过程并确保数据显示出来
                        • 再次拖动存储过程就可以了,它会生成返回类型
                        • 最后,将您的商店恢复到第一种情况,然后保存。

                        希望我能帮上忙。

                        【讨论】:

                          【解决方案17】:

                          我在拖放存储过程的时候也遇到了同样的错误,所以我就按照错误说的:

                          未知的返回类型 无法检测到以下存储过程的返回类型。在“属性”窗口中设置每个存储过程的返回类型。

                          我选择了存储过程,然后选择了属性选项卡,有一个名为 ReturnType 的选项为空,然后点击其上的下拉按钮并选择了创建 SP 的表并解决了问题。

                          如果这没有帮助,您可以尝试上述任何答案。

                          【讨论】:

                            【解决方案18】:

                            对我来说,问题是我设置了 OPTION (RECOMPILE) 来解决参数嗅探问题。我在添加 SP 时暂时删除了它,一切正常。

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2019-01-16
                              • 1970-01-01
                              相关资源
                              最近更新 更多