你可以select一切,但1或2场,没有作家的抽筋?
是否有可能在PLSQL中select除1或2以外的表中的所有字段,而不必指定所需的字段?
例如,员工表具有以下字段:
- ID
- 名字
- 姓
- 爱好
是否仍然有可能编写类似于的查询
select * from employee
而不必去写这样的东西而留下田野hobbies
呢?
select id, firstname, lastname from employee
不 – 您可以获取所有字段( *
)或指定您想要的字段 。
如果你想避免作者的痉挛,你可以使用SQL Developer并让它为你生成列列表:
select column_name||',' from all_tab_columns where table_name = 'YourTableName'
然后拿出你不想要的一两列。
你也可以使用
SELECT WM_CONCAT(column_name) FROM all_tab_columns WHERE table_name = 'table_name' GROUP BY table_name;
一个古老的线程,但是,是的…有一种方法可以在Oracle中完成:
with employee(id, firstname, lastname, hobbies) as ( select 1, 'a', 'b', '1' from dual union select 2, 'a', 'b', '2' from dual union select 3, 'a', 'b', '3' from dual union select 4, 'c', 'd', '3' from dual union select 5, 'e', 'f', '2' from dual ) select * from employee pivot ( max(1) fake for (hobbies) -- put the undesired columns here IN () ) where 1=1 -- and anything more... order by id
它做什么 – PIVOT – 将通过除PIVOT子句中声明的所有列的所有行分组。 在IN子句中指定的每个filter的FOR子句之前,已声明的列将被由聚合定义的新列replace。
一个更好的例子是下面的查询:
select * from employee pivot ( max(id) foo, max(1) bar for (hobbies) IN ('2' as two, '3' as three) )
结果是:
FIRSTNAME | LASTNAME | TWO_FOO | TWO_BAR | THREE_FOO | THREE_BAR cd null null 4 1 ef 5 1 null null ab 2 1 3 1
除id和业余爱好之外的所有列将被分组,所以它将按姓和名分组,这将导致三个组('c','d')| ('e','f')| ('a','b')。 接下来,将创build四列… IN子句中的每个filter都有两个聚合列(因为有两个MAX子句指定),聚合应用于结果组中。
那么,返回到第一个查询,它有两个原因工作:
1-分组过程中不会丢失任何行,因为id列是唯一的,没有为聚合指定列;
2-作为主轴生成N * M个新列,其中N =“filter数目”和M =“聚合数目”,没有filter,并且单个“无害”聚集意味着1 * 0 = 0个新列删除PIVOT条款中指定的所有列,这只是业余爱好 。
回答评论1
这个问题的第一行说: “…而不必指定你想要的领域” 。 在所有其他的正面答案中,提议的查询在SELECT子句中指定了所需的字段,实际上除了我的。
另外,问题标题中说“没有作家的抽筋” 。 那么,识别作者抽筋的正确方法是什么呢? 我最好的努力将是预测这个问题的一个好的SQL标准,并与我的答案进行比较。 其实,我认为这个“标准”可能是像SELECT * NOT IN([col1],[col2],…)) 。
现在,我可以在两个查询中看到:
- 不需要的列的列表;
- 一个IN子句;
- 三个字符的子句 – FOR和NOT ;
这意味着你需要在我的方法中写更多的东西,因为你需要一个虚假的聚合(你不必像我这样给它一个别名,只需写MAX(1) )和PIVOT子句…这也太如果我花了两秒钟的时间来写这些关键字,而且我也没有问题要记住如何编写这个查询 – 这很容易记住可能的“标准”。 我真的不能在这里看到一个作家的抽筋。
你在Oracle 12c上运行吗?
如果是这样,请考虑这是否符合您的需求:
alter table mytable modify column undesired_col_name INVISIBLE;
在这种情况下,列undesired_col_name
将是完全可用的,但它将被排除在任何SELECT *
语句之类(例如%ROWTYPE
),就好像它不存在一样。
query_generator
是一个PL / SQL函数,它返回一个表(第一个参数)的selectstring ,但不包括某些列(第二个参数)。
putil.join
和putil.join
来自PL / SQL Commons 。
stringlist
是一个简单的string列表: create type StringList as table of varchar2(32767);
而putil.join
只是一个普通的连接函数。
create or replace function quote_list(p_list in stringlist) return stringlist as v_list stringlist := stringlist(); begin v_list.extend(p_list.last); for i in p_list.first .. p_list.last loop v_list(i) := '''' || p_list(i) || ''''; end loop; return v_list; end; / show errors create or replace function query_generator( p_table in varchar2, p_exclude in stringlist ) return varchar2 as v_table constant varchar2(31) := upper(p_table); v_exclude constant varchar2(32676) := upper(putil.join(quote_list(p_exclude), ',')); v_stmt_str constant varchar2(32676) := 'select column_name from all_tab_columns where table_name = ''' || v_table || ''' and column_name not in (' || v_exclude || ') order by column_id'; type stmt_cur_t is ref cursor; v_stmt_cur stmt_cur_t; v_column_name varchar2(31); v_query varchar2(32676) := 'select '; begin open v_stmt_cur for v_stmt_str; loop fetch v_stmt_cur into v_column_name; exit when v_stmt_cur%notfound; v_query := v_query || lower(v_column_name) || ', '; end loop; close v_stmt_cur; select rtrim(v_query, ', ') into v_query from dual; v_query := v_query || ' from ' || p_table || ';'; return v_query; end; / show errors
用法示例:
exec dbms_output.put_line(query_generator('all_tables', stringlist('segment_created', 'result_cache')))
OP正在寻找的东西是这样的:
SELECT * MINUS hobbies from...
为了避免大量input(并且获得所有列名称正确),最好的办法是打开表格描述并剪切并粘贴所有列名称,并删除不需要的名称,用逗号分隔剩余的列名称和把它们放在一两条单线上。
它很容易,快速,准确,您不会混淆下一个需要处理代码的人。
WITH O AS ( SELECT 'SELECT ' || rtrim('NULL AS "Dummy",' || LISTAGG('"'||column_name || '"', ',' ) within group (ORDER BY COLUMN_NAME),',')|| ' FROM "'||TABLE_NAME||'"' AS SQL, TABLE_NAME FROM USER_TAB_COLUMNS GROUP BY (TABLE_NAME) ) SELECT DBMS_XMLGEN.GETXMLTYPE ((SELECT REPLACE(SQL,',COLUMNNAME','') FROM O WHERE TABLE_NAME = 'TABLENAME')) FROM DUAL
创build视图:
创build视图view_name作为selectID,first_name,last_name从雇员其中('','','')
注意: – 这就像数据库中的虚拟表,但它可以影响实际表中的值。
这里有另一个选项来获得允许你指定分隔符的字段列表:
select listagg(column_name, ', ') WITHIN GROUP (ORDER BY rownum) from all_tab_columns where table_name='table'
这里是解决scheme…我需要除密码以外的所有列
(select table_name ||','from user_tab_columns where table_name ='USERS'and column_name <>'PASSWORD')