sql - CASE when EXISTS (SELECT ...) 似乎总是返回 true

标签 sql oracle plsql

我需要测试一个表是否存在。如果它存在,我需要获取该表的行数,否则我需要将行数值设置为 NULL。

这是我正在使用的查询的一个片段:

SELECT 
    CASE 
    -- TABLE A does not exists
        WHEN EXISTS (Select TABLE_NAME from ALL_TABLES where TABLE_NAME ='A') 
            THEN (SELECT COUNT(*) FROM SYS."A") 
            ELSE NULL
        END AS TABLE_count
FROM dual; 

执行此查询时,出现以下错误消息:

SQL Error [942] [42000]: ORA-00942: table or view does not exist

似乎即使 EXISTS 返回 0 行,THEN 子句也总是被执行,而不是进入 ELSE 子句。

我不明白这里的行为。 有什么想法吗?

谢谢

最佳答案

你不能在纯 sql 中执行此操作,因为查询是作为一个整体来解析的,包括部分 SELECT COUNT(*) FROM SYS."A" 因此,如果表 SYS."A" 不存在,则整个查询将无法解析。

另一种方法是使用 pl/sql。您创建一个函数,如果表存在则对行进行计数,如果不存在则返回 null。

考虑以下示例:

create or replace function get_table_count(sTableName varchar2)
return number
is
  iCount number;
begin
  for c in (
    select null
    from   ALL_TABLES 
    where  TABLE_NAME = sTableName
  ) loop
    execute immediate 'select count(*) from '||sTableName into iCount;
    return iCount;
  end loop;
  return null;
end;
/

select get_table_count('DUAL') c1, get_table_count('ABSENT_TABLE') c2  from dual

返回

C1 C2
1  (null)

关于sql - CASE when EXISTS (SELECT ...) 似乎总是返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50904429/

相关文章:

sql - 在 Postgres 中使用行版本实现增量客户端更新

java - 我们可以添加多个 sql 驱动程序,如 OTD、MySQL Connector/J、PostgreSQL、SyBase JConnect 等吗?

linux - 无法通过 SSH 连接到 Oracle 云实例

sql - 如何找到Oracle数据库中两条记录(两个不同列)之间的时间间隔(以分钟为单位)

java - 在应该是数字的地方发现了非数字字符

mysql - 多个左连接时避免重复数据

sql - MySQL 左连接错误

linux - 从 crontab 运行时找不到 Sqlplus 命令

plsql - 如何在 PL SQL 中将日期时间转换为字符串?

mysql - 如何使用联合从表中选择记录,以便第一个查询的结果将每个结果与第二个查询的相应结果连接起来?