【问题标题】:Stored Procedure works fine from SQL Mgt Studio but throws Invalid Object name #AllActiveOrders from MVC app存储过程在 SQL Mgt Studio 中运行良好,但从 MVC 应用程序中抛出 Invalid Object name #AllActiveOrders
【发布时间】:2014-11-17 20:31:52
【问题描述】:

我可以将我的存储过程的“胆量”作为一个巨大的查询来运行。在 SQL Management Studio 中就可以了。此外,我什至可以从 SQL Management Studio 右键单击​​并“执行”存储过程 - .. 你知道 .. 将其作为存储过程运行。

当我的 ASP.NET MVC 应用程序运行这个存储过程时,我遇到了问题..

System.Data.SqlClient.SqlException:无效的对象名称“#AllActiveOrders”。

运行 ASP.NET 的模拟帐户是否需要特殊权限?不可能……即使我从我的 Visual Studio 本地运行它(在我的登录帐户下),我也会收到临时表错误消息。


编辑:此外,当从一个 ASP.NET 应用程序(使用 WCF 服务/ADO.NET 调用存储过程)调用时,它似乎工作正常,但 从不同的 ASP.NET 应用程序(直接使用 ADO.NET 调用存储过程)


FURTHERMORE:不崩溃的 MVC 应用程序,确实将一些参数传递给存储过程,而崩溃的应用程序使用默认参数运行存储过程(不传递任何参数) . FWIW - 当我在 SQL Mgt 中运行存储过程时。 Studio,它带有默认参数(并且不会崩溃)。


如果它有任何价值,我确实必须在这种情况之前修复“字符串或二进制数据将被截断”问题。我进入了这个庞大的查询并修复了我知道是问题的诱人定义(一个不同的定义)(因为我大约一天前刚刚编辑过它)。我能够在 SQL Mgt 中看到“字符串/二进制截断”问题。 Studio / 以及解决 SQL Mgt Studio 中的问题。但是,我真的很困惑为什么我在 SQL Mgt 中看不到“无效的对象名称”问题。工作室

【问题讨论】:

  • 您确定 MVC 应用程序正在运行相同的存储过程吗?不是不同的实例,数据库?用户是否解析到相同的架构?
  • 感谢@ShannonSeverance 的提问,我刚刚验证过:我的 MVC/WCF 应用程序可以运行 DEV 和 PROD 版本的存储过程而不会出现错误。我的其他 MVC 应用程序在 DEV 和 PROD 数据库上崩溃。应用程序调用存储过程的方式之间存在差异,我将添加到我的问题中

标签: asp.net sql-server stored-procedures temp-tables


【解决方案1】:

存储过程和临时表通常不能很好地与数据库对象的强类型实现(ado、数据集,我相信还有其他)混合。

如果您将#temp 表更改为应该可以解决您的问题的@variable 表。

(显然)这在某些情况下有效:

IF 1=0 BEGIN
    SET FMTONLY OFF
END

尽管根据http://msdn.microsoft.com/en-us/library/ms173839.aspx,该功能被视为已弃用。

关于如何从临时表更改为 var 表的示例如下:

create table #tempTable (id int, someVal varchar(50))

到:

declare @tempTable table (id int, someval varchar(50))

您应该考虑 temp 和 var 表之间的一些差异:

What's the difference between a temp table and table variable in SQL Server?

When should I use a table variable vs temporary table in sql server?

【讨论】:

  • 是的,这是一个包含大量“资源”表的大型查询,我在构建主输出表之前加载了这些表。我曾经将所有资源表编码为@TableVariables,但最近切换到#TempTables,因为我听说性能更好(因为我的资源表本身就是相当大的数据集)。嗯..当我仔细考虑时,几周前我切换到了#TempTables,并且直到今天都能够根据数据开发我的网络应用程序。嗯。
  • 我自己没有使用过它们,但另一个可能的选项可能是用户定义的表类型:technet.microsoft.com/en-us/library/bb522526(v=sql.105).aspx - 虽然这是用于 SQL 2008 及更高版本
  • 感谢您的回答 - 它很有用,并且确实是解决问题的准确方法。出于我之前评论中所述的原因,这不是我为我的场景所采用的方式。我已经发布了我最终用来解决我的困境的答案。
【解决方案2】:

好的。在我的同事的帮助下解决了这个问题,他的 Google-fu 比我以前做得更好..

首先,我们确实可以通过添加 FMTONLY 选项使 SQL Management Studio 对我的存储过程产生影响:

SET FMTONLY ON;

EXEC    [dbo].[My_MassiveStackOfSubQueriesToProduceADigestDataSet]

GO

现在,看看我的两个相互竞争的 ASP.NET 应用程序……为什么其中一个可以工作而一个不能?在幕后,两者本质上都使用了 ADO.NET System.Data.SqlClient.SqlDataAdapter 来获取数据,并且每个都执行了 .Fill(DataSet1)

但是,崩溃的是试图在数据之前获取架构,而不是事后推导出架构。所以,正是这行代码扼杀了它:

da.FillSchema(DataSet1, SchemaType.Mapped)

如果您正在为我遇到的同样问题而苦苦挣扎,您可能已经在互联网上看到了forums like this from MSDN - 这充分解释了正在发生的事情的细节。我从来没有想过,当我调用“FillSchema”时,我实际上是被同样的问题绊倒了。

现在我知道了!!!

【讨论】:

    【解决方案3】:

    继 bkwdesign 的关于发现问题的答案是由于 ADO.NET DataAdapter.FillSchema 使用 SET FMTONLY ON 之后,我遇到了类似的问题。我是这样处理的:

    我发现最简单的解决方案是短路存储的过程,返回一个虚拟记录集FillSchema 可以使用。所以在存储过程的顶部,我添加了类似的内容:

    IF 1 = 0 
    BEGIN;
        SELECT CAST(0 as INT) AS ID, 
            CAST(NULL AS VARCHAR(10)) AS SomTextCol, 
            ...; 
    
        RETURN 0;
    END;
    

    select 语句的列在名称、数据类型和顺序上与正常执行时从存储过程返回的记录集的模式相同。

    RETURN 确保FillSchema 不会查看存储过程的其余部分,从而避免临时表出现问题。

    【讨论】:

      猜你喜欢
      • 2016-10-09
      • 2022-08-19
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 2017-01-18
      相关资源
      最近更新 更多