在 SQL 中检查 IF 条件,即使它不匹配

Posted

技术标签:

【中文标题】在 SQL 中检查 IF 条件,即使它不匹配【英文标题】:IF condition being checked in SQL even if it doesn't match 【发布时间】:2017-05-25 14:53:03 【问题描述】:

我的代码中有 2 个 if 条件。如果它属于条件号 1,它会从某个视图执行选择,这没关系。但是,如果它属于条件 2,它会从另一个视图中选择,该视图已损坏(尽管它存在),因为它引用了不再存在的表中的列。

我的目的是不费心修复视图(或删除它),因为我有一个逻辑可以操作变量以使其处于引用工作视图的条件下。

然而,SQL 似乎验证了代码中的所有视图,即使它位于从未执行的 IF 块内,也会产生错误:

Msg 207, Level 16, State 1, Procedure vtest_table, Line 21
Invalid column name 'name'.
Msg 4413, Level 16, State 1, Line 32
Could not use view or function 'vtest_table' because of binding errors.

例子:

create database test

create table test_table (
id int identity(1,1),
name varchar(20)
)
go

create view vtest_table
as 
select id, name
from test_table
go

-- breaking the view
alter table test_table
drop column name
go

declare @var int
set @var = 2
if (@var = 2)     -- it should fall under this condition and execute this block
begin
print 'test'
end

-- however, the view in the select statement in this block is checked, and as the view is broken, it returns the error.
else if (@var = 1)
begin
select * from vtest_table
end

值得注意的是:如果我引用一个根本不存在的视图,请说:

else if (@var = 1)
begin
select * from viewthatdoesntexist
end

它正确执行。如果视图存在,SQL 似乎只检查依赖关系。

【问题讨论】:

也许你可以使用exec('select * from vtest_table') 这行得通,但它真的是唯一的方法吗?难道没有办法阻止 SQL Server 验证不属于其他 IF 条件的对象吗? 您为什么想要修复损坏的视图? 权限、企业内部流程耗时过长等……原因很多。在我的过程中实现一个根本不使用该视图的逻辑更容易。 【参考方案1】:

更新您的视图,因为您从表中删除名称列

alter view vtest_table
as 
select id
from test_table

【讨论】:

这正是我想要避免做的事情。【参考方案2】:

好吧,SQL 是一种声明性语言,不是命令式的,所以就是这样……我只需删除对视图的引用,或者将其包装在 TRY / CATCH 块中。

begin try
    exec('select * from vtest_table')
end try
begin catch
    print 'your try failed'
end catch

【讨论】:

以上是关于在 SQL 中检查 IF 条件,即使它不匹配的主要内容,如果未能解决你的问题,请参考以下文章

即使第一个条件为假,是不是所有条件都在 if 语句中进行检查?

CASE WHEN SQL 查询在 else 中执行条件,即使第一个条件为真

SQL多对多,如何检查多行的条件

Liquibase:Migrate.sql 不检查前提条件

SQL语句中Case 的用法

在 MySQL 查询的 IF 条件中使用逻辑 OR 来检查 NoneType 或 float