【问题标题】:How to select columns on the basis of column names in OracleOracle中如何根据列名选择列
【发布时间】:2021-09-08 18:46:05
【问题描述】:

我尝试了以下方法,但不起作用。

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>

【问题讨论】:

  • 你需要动态SQL,涉及到execute immediate。不过,我怀疑问题出在您的数据模型上,而数据模型可能应该已修复。
  • 你能举个例子吗?关于数据模型,我不是这个数据的所有者。我只是在消费它。

标签: sql oracle oracle11g


【解决方案1】:

在此示例中,我正在编写一个 select 语句,该语句基于名称满足特定条件的表(作为参数传递给函数)中的列列表。由于它是 Scott 的 emp 表并且其列没有任何后缀,因此我选择名称包含字母 E 的列。

基于该列列表(与listagg 聚合),l_str 变量包含一个完整 select 语句,而该语句又是一个来源为 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>

【讨论】:

  • 这种方式函数应该用AUTHID CURRENT_USER声明,因为DEFINERis the default。但好的方法是在应用程序代码中生成语句。
  • 感谢您的评论,@astentx。我发布的代码远非完美,它只是建议如何完成。例如,如果传递小写表名,如果没有列满足条件,它将失败,...如果 OP 选择使用它,则 things 应该改进,所以我建议他们也会考虑您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-25
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多