【问题标题】:T-SQL If clause is evaluating regardless of condition无论条件如何,T-SQL If 子句都在计算
【发布时间】:2018-07-21 00:56:23
【问题描述】:

我想做的是评估如下 SQL 表达式:

IF HAS_DBACCESS('ExampleDB') = 1
BEGIN
    USE ExampleDB
    --Other stuff
END

根据此查询,如果执行此查询的用户有权访问 ExampleDB,它应该只执行与 ExampleDB 相关的操作。

当我以无法访问此数据库的用户身份运行此查询时,我收到以下错误消息:

服务器主体“MY_USERNAME”无法访问数据库 当前安全上下文下的“ExampleDB”。

这对我来说很奇怪。我没有可以访问 ExampleDB。因此,HAS_DBACCESS('ExampleDB') 的计算结果为 0。我通过选择它的值确认了这一点。事实上,如果我将 USE ExampleDB 替换为 USE 语句以外的任何内容(例如,SELECT 'Test'),它不会评估,这是正确的行为。

出于某种原因,它甚至会在检查条件之前尝试评估 USE ExampleDB 的访问权限。这是预期的行为吗?如果是这样,有什么办法可以解决这个问题?

【问题讨论】:

  • 我可能从我的大脑深处错误地提取了这个,但是,我认为无论它在批处理中的哪个位置,我都认为派生了 USE 语句,甚至是可能无法运行的部分。您可能需要使用动态 SQL 来完成您想要做的任何事情。
  • USE DB that may not exist的可能重复
  • 上面链接的副本不是完全相同的副本,但问题和答案是相同的。归结为 USE 语句在编译时和执行时都执行。

标签: sql sql-server


【解决方案1】:

我不会这样做,因为,是的,它会抛出那个错误。尝试做这样的事情,它可以工作,但它不适用于您的 USE 语句:

IF HAS_DBACCESS('blahhhhhhh') = 1
begin
print 'hello'
end
else 
begin
print 'bad'
end

一个选项是在您的分支中使用 db 名称完全限定内容:

IF HAS_DBACCESS('ExampleDB') = 1
BEGIN
    SELECT * FROM ExampleDB.dbo.Your_table
END
ELSE 
BEGIN 
    SELECT * FROM otherDB.dbo.Your_table
END

【讨论】:

  • 我没有完全限定的原因是因为我特别想用 OBJECT_DEFINITION(my_obj) 获取存储过程或视图的对象定义。我无法做到 OBJECT_DEFINITION(ExampleDB.dbo.my_obj) ,还有其他方法吗?我知道这与我所问的问题不同,但我仍然想知道是否有解决方案
  • @JonWarren 正如您获得的链接所述,USE 在编译时进行评估。要继续这条路,您必须使用动态 sql。如果您只对过程和视图感兴趣,您可以从 sys.sql_modules 检索相同的信息
猜你喜欢
  • 2015-05-31
  • 2011-05-28
  • 2011-03-16
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
相关资源
最近更新 更多