使用SQL或PL / SQL从多个表中使用列和表名进行动态查询

时间:2015-04-18 11:16:47

标签: sql oracle plsql oracle11g

让我们假设(为简单起见)我有两个表:

Product
 product_id
 CreatedDate
 LastEditedBy
 EditedDate

Entity
 entity_id
 CreatedDate
 LastEditedBy
 EditedDate

两个表都具有相同的列名,但只有ID列具有不同的名称。我想运行一个查询,这样当我从SQL运行它时,我只需给它一个参数,它从其中一个表中获取数据。在上面的例子中,我可以运行像这样的查询

@archiveHistory.sql product
@archiveHistory.sql entity

这是我的尝试,但它总是无法识别其中一个列,即如果我用产品运行它,它说entity_id不存在。如果我用实体运行它说product_id不存在。

请注意,我在列选择和表名选择中使用传入的参数。

define identifier = '&1'

Select * from (
 Select case lower('&identifier')
  when product then product_id 
  when entity then entity_id
  end ID, CreatedDate, LastEditedBy, EditedDate
 From &identifier
)

我认为如果CASE语句中的列列表都来自同一个表,它将起作用。

问题

  • 我需要做什么,以便查询忽略不相关的列,如果参数是实体则忽略product_id

  • 我考虑过使用匿名PL / SQL块(即Begin End),但我不确定如何在不使用dbms_output.put_line的情况下显示输出。

1 个答案:

答案 0 :(得分:2)

对于这种特殊情况,我认为以下仅限SQL的解决方案可能效果最好:

SELECT product_id AS the_field
     , CreatedDate, LastEditedBy, EditedDate
FROM   Product
WHERE  LOWER('&identifier') = 'product'
UNION ALL
SELECT entity_id AS the_field
     , CreatedDate, LastEditedBy, EditedDate
FROM   Entity
WHERE  LOWER('&identifier') = 'entity'

查询规划器将预先评估您的'&identifier' = ...谓词,这可以防止执行不需要的union子查询。

如果这不是一个选项(因为你的实际用例要复杂得多),那么Stack Overflow上有很多关于从PL / SQL执行动态SQL的答案:

您可以使用动态SQL将数据插入临时表,然后只需SELECT * FROM temp_table