Oracle只读库中如何筛选记录列?排除指定记录下全为null的列
在Oracle中排除指定列查询的替代方案
Oracle本身并不支持SELECT * EXCEPT [列名]这类简洁的排除列语法,不过有几种间接方式可以不用手动罗列所有字段就能实现排除FAILDATE列的需求:
1. 创建视图(需对应权限)
如果你的账号拥有创建视图的权限(只读库指原表不可修改,你可以在自己的schema下创建视图),可以先创建包含原表所有列的视图,再移除不需要的FAILDATE列:
-- 创建包含所有列的视图 CREATE VIEW WORKORDER_NO_FAILDATE AS SELECT * FROM MAXSCHEMA.WORKORDER; -- Oracle 12c及以上版本支持直接从视图中删除列 ALTER VIEW WORKORDER_NO_FAILDATE DROP COLUMN FAILDATE; -- 之后直接查询视图即可 SELECT * FROM WORKORDER_NO_FAILDATE WHERE WONUM = '101319066';
如果是12c以下的Oracle版本,创建视图时就需要显式指定除FAILDATE外的所有列,这种方式的缺点是原表结构变更后视图可能失效。
2. 动态生成查询语句
通过查询数据字典表ALL_TAB_COLUMNS自动拼接出排除FAILDATE的SELECT语句,省去手动列字段的麻烦:
SELECT 'SELECT ' || LISTAGG(COLUMN_NAME, ', ') WITHIN GROUP (ORDER BY COLUMN_ID) || ' FROM MAXSCHEMA.WORKORDER WHERE WONUM = ''101319066''' FROM ALL_TAB_COLUMNS WHERE OWNER = 'MAXSCHEMA' AND TABLE_NAME = 'WORKORDER' AND COLUMN_NAME != 'FAILDATE';
执行这条语句会输出一个完整的查询语句,复制后直接执行就能得到排除FAILDATE的结果。如果后续表结构有变化,重新执行这条语句生成新的查询即可。
3. 用PL/SQL动态执行查询(适合交互式工具)
在PL/SQL Developer、SQL*Plus这类工具中,可以写一个PL/SQL块动态生成并执行查询,直接返回结果:
DECLARE v_sql_stmt VARCHAR2(4000); BEGIN SELECT 'SELECT ' || LISTAGG(COLUMN_NAME, ', ') WITHIN GROUP (ORDER BY COLUMN_ID) || ' FROM MAXSCHEMA.WORKORDER WHERE WONUM = ''101319066''' INTO v_sql_stmt FROM ALL_TAB_COLUMNS WHERE OWNER = 'MAXSCHEMA' AND TABLE_NAME = 'WORKORDER' AND COLUMN_NAME != 'FAILDATE'; EXECUTE IMMEDIATE v_sql_stmt; END; /
注意在SQL*Plus中需要先执行SET SERVEROUTPUT ON才能看到输出,部分工具(比如PL/SQL Developer)可以直接返回查询结果集。
内容的提问来源于stack exchange,提问作者Jim Higgins
相关产品推荐
相关产品推荐

