在PLSQL中,是否有可能选择除1或2之外的表中的所有字段,而不必指定所需的字段?
例如,employee表包含以下字段:
是否仍然可以编写类似的查询
select * from employee
Run Code Online (Sandbox Code Playgroud)
离开球场hobbies
而不必写这样的东西?
select id, firstname, lastname from employee
Run Code Online (Sandbox Code Playgroud)
Yah*_*hia 46
否 - 您要么获取所有字段(*
)或指定所需的字段.
Mic*_*son 39
如果你想避免编写器的抽筋,你可以使用SQL Developer并让它为你生成列列表:
select column_name||','
from all_tab_columns
where table_name = 'YourTableName'
Run Code Online (Sandbox Code Playgroud)
然后只取出你不想要的一两列.
你也可以使用
SELECT listagg(column_name, ',') within group (order by column_name) columns
FROM all_tab_columns
WHERE table_name = 'TABLE_NAME'
GROUP BY table_name;
Run Code Online (Sandbox Code Playgroud)
Mat*_*eak 21
你在Oracle 12c上运行吗?
如果是这样,请考虑这是否符合您的需求:
alter table mytable modify column undesired_col_name INVISIBLE;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,列undesired_col_name
将完全可用,但它将被排除在任何SELECT *
语句之类(例如%ROWTYPE
)之外,就好像它不存在一样.
Fel*_*ira 18
一个旧线程,但是,是的...有一种方法可以在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 () -- no values here...
)
where 1=1 -- and your filters here...
order by id
Run Code Online (Sandbox Code Playgroud)
为了理解PIVOT如何工作以及为什么它解决了这个问题,让我们为我们的employee
示例表做一个更好的例子:
select *
from employee
pivot
(
max(id) foo,
max(1) bar
for (hobbies)
IN ('2' as two, '3' as three)
)
Run Code Online (Sandbox Code Playgroud)
结果如下:
FIRSTNAME | LASTNAME | TWO_FOO | TWO_BAR | THREE_FOO | THREE_BAR c d null null 4 1 e f 5 1 null null a b 2 1 3 1
使用这个更容易理解的查询可以实现完全相同的输出:
select
firstname,
lastname,
max(case when hobbies = '2' then id end) two_foo,
max(case when hobbies = '2' then 1 end) two_bar,
max(case when hobbies = '3' then id end) three_foo,
max(case when hobbies = '3' then 1 end) three_bar
from employee
group by
firstname,
lastname
Run Code Online (Sandbox Code Playgroud)
因此,hobbies
永远不会选择列,就像id
在PIVOT子句中指定的列一样.所有其他列都已分组并选中.
好吧,返回第一个查询,它有两个原因:
1-你不会在分组过程中丢失任何行,因为id列是唯一的,没有为聚合指定列;
2-作为数组生成N*M个新列,其中N = IN子句的值的数量,M =指定的聚合数,因此没有过滤器,并且单个无害聚合将产生0*1 = 0个新列,并且删除PIVOT子句中指定的那些,这只是业余爱好.
回答1
这个问题的第一行说:"......无需指定你想要的字段".在所有其他答案中,建议的查询在SELECT子句中指定了所需的字段,实际上除了我的.
此外,问题标题中写着"......没有作家的抽筋".那么,识别作家痉挛的正确措施是什么?我最大的努力是预见到这个问题的一个好的SQL标准,并与我的答案进行比较.实际上,我认为这个"标准"可能类似SELECT*NOT IN([col1],[col2],...).
现在,我可以在两个查询中看到:
这意味着你需要在我的方法中多写一点,因为你需要一个假聚合和PIVOT子句...但它真的很少有几个字符......
Oracle 18c 多态表函数可以从表中选择所有内容并排除列列表:
select * from everything_but(employee, columns(hobbies));
ID FIRSTNAME LASTNAME
-- --------- --------
1 John Smith
Run Code Online (Sandbox Code Playgroud)
创建该函数需要以下包,该包是从 Tim Hall 的网站https://oracle-base.com/articles/18c/polymorphic-table-functions-18c复制的。请注意,该包不包含特定于该表的任何内容 - 此解决方案适用于任何 Oracle 表。
CREATE OR REPLACE PACKAGE poly_pkg AS
FUNCTION everything_but(tab IN TABLE,
col IN COLUMNS)
RETURN TABLE PIPELINED
ROW POLYMORPHIC USING poly_pkg;
FUNCTION describe (tab IN OUT DBMS_TF.table_t,
col IN dbms_tf.columns_t)
RETURN DBMS_TF.describe_t;
END poly_pkg;
/
CREATE OR REPLACE PACKAGE BODY poly_pkg AS
FUNCTION describe (tab IN OUT DBMS_TF.table_t,
col IN dbms_tf.columns_t)
RETURN DBMS_TF.describe_t
AS
BEGIN
-- Loop through all the table columns.
FOR i IN 1 .. tab.column.count() LOOP
-- Loop through all the columns listed in the second parameter.
FOR j IN 1 .. col.count() LOOP
-- Set pass_through to true for any columns not in the exclude list.
tab.column(i).pass_through := (tab.column(i).description.name != col(j));
-- Exit inner loop if you find a column that shouldn't be included.
EXIT WHEN NOT tab.column(i).pass_through;
END LOOP;
END LOOP;
RETURN NULL;
END;
END poly_pkg;
/
Run Code Online (Sandbox Code Playgroud)
我还创建了这个简单的包装函数来给它一个更好的名字。并创建了一个简单的示例表。
CREATE OR REPLACE FUNCTION everything_but(tab IN TABLE, col in COLUMNS)
RETURN TABLE PIPELINED
ROW POLYMORPHIC USING poly_pkg;
/
create table employee as
select 1 id, 'John' firstname, 'Smith' lastname, 'fishing' hobbies from dual;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
70347 次 |
最近记录: |