使用 SQL 或 PL/SQL 的来自多个 table 的列和 table 名称的动态查询
Dynamic query with columns and table names from multiple tables using SQL or PL/SQL
让我们假设(为简单起见)我有两个 tables:
Product
product_id
CreatedDate
LastEditedBy
EditedDate
Entity
entity_id
CreatedDate
LastEditedBy
EditedDate
两个 table 具有相同的列名,但只有 ID 列具有不同的名称。我想 运行 一个查询,这样当我 运行 它来自 SQL 加上我只是给它一个参数,它从 table 之一获取数据。在上面的例子中,我可以 运行 这样的查询
@archiveHistory.sql product
@archiveHistory.sql entity
这是我的尝试,但它总是无法识别其中一列,即如果我 运行 它与产品,它说 entity_id 不存在。如果我 运行 它与实体它说 product_id 不存在。
请注意,我在列选择和 table 名称选择中都使用了传入的参数。
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 语句中的列列表都来自同一个 table,它会起作用。
问题
我需要做什么才能让查询忽略不相关的列,即忽略 product_id 如果参数是实体
我考虑过使用匿名 PL/SQL 块(即 Begin End),但我不确定如何在不使用 dbms_output.put_line 的情况下显示输出。
对于这种特殊情况,我认为以下仅 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' = ...
谓词,从而防止执行不需要的联合子查询。
如果这不是一个选项(因为您的实际用例要复杂得多),Stack Overflow 上已经有很多关于从 PL/SQL 执行动态 SQL 的答案:
- Executing a dynamic sql statement into a SYS_REFCURSOR
- Cursor For Loop with dynamic SQL-Statement
- Binding Parameters to Oracle Dynamic SQL
您可以使用动态 SQL 将数据插入临时文件 table,然后只需 SELECT * FROM temp_table
让我们假设(为简单起见)我有两个 tables:
Product
product_id
CreatedDate
LastEditedBy
EditedDate
Entity
entity_id
CreatedDate
LastEditedBy
EditedDate
两个 table 具有相同的列名,但只有 ID 列具有不同的名称。我想 运行 一个查询,这样当我 运行 它来自 SQL 加上我只是给它一个参数,它从 table 之一获取数据。在上面的例子中,我可以 运行 这样的查询
@archiveHistory.sql product
@archiveHistory.sql entity
这是我的尝试,但它总是无法识别其中一列,即如果我 运行 它与产品,它说 entity_id 不存在。如果我 运行 它与实体它说 product_id 不存在。
请注意,我在列选择和 table 名称选择中都使用了传入的参数。
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 语句中的列列表都来自同一个 table,它会起作用。
问题
我需要做什么才能让查询忽略不相关的列,即忽略 product_id 如果参数是实体
我考虑过使用匿名 PL/SQL 块(即 Begin End),但我不确定如何在不使用 dbms_output.put_line 的情况下显示输出。
对于这种特殊情况,我认为以下仅 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' = ...
谓词,从而防止执行不需要的联合子查询。
如果这不是一个选项(因为您的实际用例要复杂得多),Stack Overflow 上已经有很多关于从 PL/SQL 执行动态 SQL 的答案:
- Executing a dynamic sql statement into a SYS_REFCURSOR
- Cursor For Loop with dynamic SQL-Statement
- Binding Parameters to Oracle Dynamic SQL
您可以使用动态 SQL 将数据插入临时文件 table,然后只需 SELECT * FROM temp_table