【发布时间】:2022-02-11 04:54:31
【问题描述】:
在 dbml 文件中拖放存储过程时出现此错误:
未知返回类型
无法检测到以下存储过程的返回类型。在“属性”窗口中设置每个存储过程的返回类型。
我该如何解决这个错误?
【问题讨论】:
标签: linq-to-sql
在 dbml 文件中拖放存储过程时出现此错误:
未知返回类型
无法检测到以下存储过程的返回类型。在“属性”窗口中设置每个存储过程的返回类型。
我该如何解决这个错误?
【问题讨论】:
标签: linq-to-sql
当设计者无法确定 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 表执行的所有操作,例如 加入、插入、选择等。
【讨论】:
在参数声明之后添加这些行
AS
IF 1=0 BEGIN
SET FMTONLY OFF
END
在此之后,编写BEGIN并开始您的程序工作。
【讨论】:
我在我的 SQL 中使用了一个临时表并收到此错误。我将临时表转换为表变量,这解决了我的问题。
【讨论】:
这也可能是访问权限的问题。如果存储过程无权访问该表,则会出现相同的错误。我有一个查询从另一个我没有权限的数据库中选择数据(实际上运行 Visual Studio 连接的帐户没有权限)并且我收到了同样的错误。添加适当的权限后,一切正常。
尝试在 VS2010 中执行存储过程(通过右键单击服务器资源管理器并选择“执行”)帮助我解决了问题。
【讨论】:
我刚刚向我的 DBML 添加了大约 300 个存储过程,并且遇到了这里和其他地方提到的许多问题。
根据我的亲身经历,总结一下“无法检测到以下存储过程的返回类型”错误的原因和解决方案。请注意,下面描述的问题可能发生在您遇到错误的 SP 中,或者 从该 SP 直接或间接调用的任何其他 SP 中。
【讨论】:
原因:您的存储过程将返回一个复杂类型。即多个结果或使用临时表。
分辨率
这完全取决于您的存储过程在做什么。有用的链接
【讨论】:
以防万一其他人遇到这种情况,我自己也经历过。
在我的例子中,我在插入语句中引用了一个表,该表不再存在于我的架构中。仔细检查我的代码,发现我正在插入一个名为“Account”的表,该表现在称为“tblAccount”。 Visual Studio 在保存 sp 时没有抛出任何错误,但我在尝试将 sp 添加到 dbml 文件时遇到了同样的错误。
希望这对其他人有帮助。
【讨论】:
我也遇到了这个问题 - 必须注释掉构建多边形的代码:
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 后,我取消了对代码的注释,它就像一个冠军!
【讨论】:
我也遇到了问题(VS 2012,SQL Server 2008R2)。在我的例子中,它是 + 运算符和代码中各种 CAST 语句的组合。我还没有找到用 VisualStudio 喜欢的东西替换它们的方法,但我想出了一个解决方法:
解决方法“虚拟 SELECT”:
select 'bla bla' as field1, 123123 as field2, 'asñfs' as field3
【讨论】:
您不妨考虑使用 CONCAT() 方法而不是 '+' 来连接字符串。由于我没有使用临时表,但仍然遇到这个问题。我发现使用 '+' 连接字符串会触发此操作。
就我而言,我使用的是这个:
SET @errorMessage = CONCAT('Update (ID=', @pnID, ') failed. Name already exists.');
代替:
SET @errorMessage = 'Update (ID=' + @pnID + ') failed. Name already exists.';
【讨论】:
在尝试将存储过程添加到 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 文件,拖放到您的新包装存储过程中。
【讨论】:
确保存储过程运行时不会出错。刚遇到这个问题,我假设制作存储过程的人已经测试过了,但自己没有尝试。
【讨论】:
我找到的解决方案...我在顶部 (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
【讨论】:
我在这方面做了很多努力并得出结论,如果您的存储过程是动态的并且与字符串结合,您有时会遗漏一些东西。所以在导入 Visual Studio DBML 导入/更新时无法执行/测试该过程,因此返回类型保持未定义,一旦您更正了过程(您正在构建以执行的查询字符串),您就可以毫无问题地添加过程。
【讨论】:
我也有这个错误,最后我发现我已经更改了一个表字段名称,并且在程序中它还没有更改它,所以在添加到 dbml 时它显示了一个错误。 现在您可以在您的程序和表格中检查这些字段是否相同。
我希望这个经验是有用的。
【讨论】:
解决此问题的简单方法是(2019 年 12 月)
希望我能帮上忙。
【讨论】:
我在拖放存储过程的时候也遇到了同样的错误,所以我就按照错误说的:
未知的返回类型 无法检测到以下存储过程的返回类型。在“属性”窗口中设置每个存储过程的返回类型。
我选择了存储过程,然后选择了属性选项卡,有一个名为 ReturnType 的选项为空,然后点击其上的下拉按钮并选择了创建 SP 的表并解决了问题。
如果这没有帮助,您可以尝试上述任何答案。
【讨论】:
对我来说,问题是我设置了 OPTION (RECOMPILE) 来解决参数嗅探问题。我在添加 SP 时暂时删除了它,一切正常。
【讨论】: