我有一个包含 100 多个列的事务数据库。现在,如果我必须选择所有行,但只选择表中已更改的那些列(特定列有多个不同的值)。我怎样才能在ORACLE中做到这一点?
在我的查询中,我必须手动编写 100 行来检查特定列是否有超过 1 个不同计数。这很乏味。我这里需要一些专业知识以及我们是否有任何简单的方法。
SELECT id,
CASE WHEN COUNT(DISTINCT column1) > 1 THEN column1 END AS column1,
CASE WHEN COUNT(DISTINCT column2) > 1 THEN column2 END AS column2,
.
.
.
FROM your_table_name
GROUP BY id
我的理解是,一种选择是创建一个返回 refcursor 的函数,该函数由值已更改的列组成。为了找到它们,请收集表统计信息并检查
user_tab_columns
视图的 num_distinct
列。
示例数据:仅
phone
列已更改:
SQL> select * from test;
ID NAME PHONE
---------- ------ ------
1 Little 123456
1 Little 555666
函数必须是一个自治事务,因为 DDL(收集表统计信息)隐式提交。
SQL> create or replace function f_test (par_table_name in varchar2)
2 return sys_refcursor
3 is
4 pragma autonomous_transaction;
5 rc sys_refcursor;
6 l_str varchar2(10000);
7 begin
8 dbms_stats.gather_table_stats(user, par_table_name);
9
10 execute immediate
11 q'[select listagg(column_name, ',') within group (order by column_id)
12 from user_tab_columns
13 where table_name = ]' || chr(39) ||
14 dbms_assert.sql_object_name(par_table_name) || chr(39) ||
15 ' and num_distinct > 1'
16 into l_str;
17
18 if l_str is not null then
19 l_str := 'select ' || l_str || ' from ' || par_table_name;
20 open rc for l_str;
21 return rc;
22 else
23 raise_application_error(-20000, 'No changes in that table''s columns');
24 end if;
25 end;
26 /
Function created.
测试:
SQL> select f_test('TEST') from dual;
F_TEST('TEST')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
PHONE
------
123456
555666
SQL>