【问题标题】:SELECT returns different result when used in a stored procedureSELECT 在存储过程中使用时返回不同的结果
【发布时间】:2012-08-04 21:32:32
【问题描述】:

我们开始从 SQL Server 2000 升级到 SQL Server 2008,然后是 SQL Server 2012(我们不能直接从 2000 升级到 2012)。

SQL Server 2000 中的一个存储过程将@ErrorMsg 的值设置为sys.objects 视图中的名称列,其中name 是给定值。出于这些目的,假设我正在寻找名称 zz_BICWS_PersonInfo_Search_1000000000000000000,它确实存在于 sys.objects 视图中。

该过程在 SQL Server 2000 中有效,如果我在 SQL Server 2012 中运行以下代码,它将返回正确的名称,但在 SQL Server 2012 中的存储过程中没有。

declare @ErrorMsg varchar(1000)

set @ErrorMsg = 'xxxxxxx'

select @ErrorMsg = name
    from bic.dbo.sysobjects 
    Where name = 'zz_BICWS_PersonInfo_Search_10000000000000000000'

print 'test ' + @ErrorMsg

这些相同的行存在于存储过程中,除了打印行,@ErrorMsg 被输出到调用该过程的应用程序。但它返回初始值xxxxxx,使用应用程序中的消息框显示返回值。

但如果我将 where 子句更改为

Where name Like ‘zz_BICWS_PersonInfo_Search_%’  

(大约有 40 行与此匹配)然后我将获取找到的第一行的名称。

【问题讨论】:

  • 那么,您是否在 SQL 2012 中实现了完全相同的功能,却没有得到您期望的结果?基于这句话These same lines exist in a stored procedure, except the print line 让我想知道。
  • 你有没有考虑过调用存储过程时,对象不存在?

标签: sql-server-2008 stored-procedures sql-server-2000 sql-server-2012


【解决方案1】:

感谢另一个论坛,我收到了答案。我将其发布在这里,以供其他可能遇到相同问题的人使用。

SQL 2000 和更高版本之间有一个重要的区别。在 SQL 2000 中,每个人都可以看到所有元数据,并且无法更改它。

在 SQL 2005 及更高版本中,只有在您有权限的情况下才能查看元数据。当您的 SELECT 语句由您的应用程序中的普通用户执行时,它不会命中任何行。但是,当您在 SSMS 中以 sa 连接或至少使用 db_owner 权限运行 SELECT 时,一切正常。

如果您依赖可见的元数据,您需要将权限 VIEW DEFINITION 授予相应的用户。

向应用用户授予视图定义

会将数据库中所有对象的 VIEW DEFINITION 授予角色 appusers。此语句授予对 dbo 架构中所有对象的权限:

将 SCHEMA::dbo 上的视图定义授予应用程序用户

如果您对对象具有 SELECT 或 EXECUTE 权限,则该对象隐含 VIEW DEFINITION 权限。

【讨论】:

    【解决方案2】:

    我很难在其中找到问题,但我认为问题在于您试图将 40 行塞入一个变量中。

    尝试删除@ErrorMsg 变量,然后运行它:

    select name
    from bic.dbo.sysobjects 
    Where name = 'zz_BICWS_PersonInfo_Search_10000000000000000000'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      相关资源
      最近更新 更多