Oracle中如何根据列名select列
How to select columns on the basis of column names in Oracle
我尝试了以下方法,但不起作用。
select (
select COLUMN_NAME from ALL_TAB_COLUMNS
WHERE COLUMN_NAME LIKE '%_<SOME_SUFFIX>'
AND OWNER = '<SCHEMA>' AND TABLE_NAME = '<TABLE_NAME>'
)
FROM <SCHEMA>.<TABLE_NAME>
在这个例子中,我正在编写一个 select
语句,该语句基于名称满足特定条件的 table(作为参数传递给函数)中的列列表。因为它是 Scott 的 emp
table 并且它的列没有任何后缀,所以我选择名称包含字母 E.
的列
基于该列列表(与 listagg
聚合),l_str
变量包含一个 full select
语句,它是 - 在turn - 一个 source for refcursor.
SQL> CREATE OR REPLACE FUNCTION f_test (par_table_name IN VARCHAR2)
2 RETURN SYS_REFCURSOR
3 IS
4 l_cols VARCHAR2 (100);
5 l_str VARCHAR2 (200);
6 rc SYS_REFCURSOR;
7 BEGIN
8 -- list of column names that satisfy some condition; for example, have some suffix or, as
9 -- in my example, have a letter "E" in their name
10 SELECT LISTAGG (column_name, ', ') WITHIN GROUP (ORDER BY column_name)
11 INTO l_cols
12 FROM user_tab_columns
13 WHERE table_name = DBMS_ASSERT.sql_object_name (par_table_name)
14 AND INSTR (column_name, 'E') > 0;
15
16 l_str :=
17 'select '
18 || l_cols
19 || ' from '
20 || DBMS_ASSERT.sql_object_name (par_table_name);
21
22 OPEN rc FOR l_str;
23
24 RETURN rc;
25 END;
26 /
Function created.
测试:
SQL> select f_test('EMP') from dual;
F_TEST('EMP')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO EMPNO ENAME HIREDATE
---------- ---------- ---------- ----------
20 7369 SMITH 17/12/1980
30 7499 ALLEN 20/02/1981
30 7521 WARD 22/02/1981
20 7566 JONES 02/04/1981
30 7654 MARTIN 28/09/1981
30 7698 BLAKE 01/05/1981
10 7782 CLARK 09/06/1981
20 7788 SCOTT 09/12/1982
10 7839 KING 17/11/1981
30 7844 TURNER 08/09/1981
20 7876 ADAMS 12/01/1983
30 7900 JAMES 03/12/1981
20 7902 FORD 03/12/1981
10 7934 MILLER 23/01/1982
14 rows selected.
SQL> select f_test('DEPT') from dual;
F_TEST('DEPT')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO DNAME
---------- --------------
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
SQL>
我尝试了以下方法,但不起作用。
select (
select COLUMN_NAME from ALL_TAB_COLUMNS
WHERE COLUMN_NAME LIKE '%_<SOME_SUFFIX>'
AND OWNER = '<SCHEMA>' AND TABLE_NAME = '<TABLE_NAME>'
)
FROM <SCHEMA>.<TABLE_NAME>
在这个例子中,我正在编写一个 select
语句,该语句基于名称满足特定条件的 table(作为参数传递给函数)中的列列表。因为它是 Scott 的 emp
table 并且它的列没有任何后缀,所以我选择名称包含字母 E.
基于该列列表(与 listagg
聚合),l_str
变量包含一个 full select
语句,它是 - 在turn - 一个 source for refcursor.
SQL> CREATE OR REPLACE FUNCTION f_test (par_table_name IN VARCHAR2)
2 RETURN SYS_REFCURSOR
3 IS
4 l_cols VARCHAR2 (100);
5 l_str VARCHAR2 (200);
6 rc SYS_REFCURSOR;
7 BEGIN
8 -- list of column names that satisfy some condition; for example, have some suffix or, as
9 -- in my example, have a letter "E" in their name
10 SELECT LISTAGG (column_name, ', ') WITHIN GROUP (ORDER BY column_name)
11 INTO l_cols
12 FROM user_tab_columns
13 WHERE table_name = DBMS_ASSERT.sql_object_name (par_table_name)
14 AND INSTR (column_name, 'E') > 0;
15
16 l_str :=
17 'select '
18 || l_cols
19 || ' from '
20 || DBMS_ASSERT.sql_object_name (par_table_name);
21
22 OPEN rc FOR l_str;
23
24 RETURN rc;
25 END;
26 /
Function created.
测试:
SQL> select f_test('EMP') from dual;
F_TEST('EMP')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO EMPNO ENAME HIREDATE
---------- ---------- ---------- ----------
20 7369 SMITH 17/12/1980
30 7499 ALLEN 20/02/1981
30 7521 WARD 22/02/1981
20 7566 JONES 02/04/1981
30 7654 MARTIN 28/09/1981
30 7698 BLAKE 01/05/1981
10 7782 CLARK 09/06/1981
20 7788 SCOTT 09/12/1982
10 7839 KING 17/11/1981
30 7844 TURNER 08/09/1981
20 7876 ADAMS 12/01/1983
30 7900 JAMES 03/12/1981
20 7902 FORD 03/12/1981
10 7934 MILLER 23/01/1982
14 rows selected.
SQL> select f_test('DEPT') from dual;
F_TEST('DEPT')
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
DEPTNO DNAME
---------- --------------
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
SQL>