使用动态表名称查询 Oracle 数据库

Posted

技术标签:

【中文标题】使用动态表名称查询 Oracle 数据库【英文标题】:Querying an Oracle Database with Dynamic Table names 【发布时间】:2019-02-05 16:11:17 【问题描述】:

我遇到了一些糟糕的数据库设计,我必须查询按日期命名的表。

当表名使用相关日期进行硬编码时,以下查询有效。

SELECT
  ajob.ORDER_ID
     , ajob.JOB_NAME
     , abim.SERVICE_ID
     , shist.SERVICE_NAME
  FROM
    obscuredschema.A190129001_AJOB               ajob --hardcoded YYMMDD table name
    INNER JOIN obscuredschema.A190129001_ABIMSVC abim --hardcoded YYMMDD table name
               ON (ajob.ORDER_ID = abim.ORDER_ID)
    INNER JOIN obscuredschema.SERVICE_HIST       shist
               ON (abim.SERVICE_ID = shist.SERVICE_KEY)
WHERE shist.SERVICE_NAME LIKE '%BIM'
  AND shist.BIM_AUTH_ID > 0
;

注意两个硬编码的表名(连同别名)

如何使用动态表名执行相同的查询?(有两个)

动态日期代码:TO_CHAR(trunc(sysdate - 7), 'YYMMDD')

如果第一个表名是一个字符串,我会这样构建它: 'A'||TO_CHAR(trunc(sysdate - 7), 'YYMMDD')||'001_AJOB'

如果第二个表名是一个字符串,我会这样构建它: 'A'||TO_CHAR(trunc(sysdate - 7), 'YYMMDD')||'001_ABIMSVC'

【问题讨论】:

您需要使用动态 SQL 来执行此操作。 . .想想execute immediate @GordonLinoff 我是动态 SQL、PL/SQL 的新手,可以立即执行。可悲的是,我不明白/无法弄清楚如何在 Oracle 上实施“问汤姆”的答案。 :( 【参考方案1】:

我认为你不能用动态表名编写一个普通的 SQL 查询。

您可以编写一个使用execute immediate 并返回游标或其他东西的PL/SQL 过程; somebody asked about that just yesterday。如果您只是想编写此查询以与某些数据进行交互,那可能是您最好的选择。

此外,您可以通过将 PL/SQL 过程转换为 pipelined function 来修改它,然后您可以使用 TABLE() 从 SQL 查询中调用它。

如果是我,我会考虑创建一个同义词(或仅从动态命名表中选择的标准视图),并安排一个作业以在每次创建新表时重新创建它。这可能比处理流水线函数更简单。

【讨论】:

堆栈礼仪问题。我无法让它工作,但幸运的是我找到了一种可以将问题转移到 Python 的方法。我要删除我的问题吗? 有些人会这样做。我觉得把问题留在那里不会有什么坏处,其他人可能有同样的问题。

以上是关于使用动态表名称查询 Oracle 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何用oracle动态查询一张表里面的某些列?

Oracle - 使用动态查询插入表

Oracle - 匿名过程循环遍历多个表(动态) - 查询返回多行

如何在 oracle pl/sql 查询中动态获取字段名称?

具有动态表名的 Oracle Select 查询

ORACLE:动态数据的 PIVOT 表