我有table_lookup
。这是主表,其中包含所有查找代码,如
LOOKUP_TYPE LOOKUP_CODE MEANING ENABLED_FLAG
EMP_CAT 3 Hourly with fixed hours per week Y
EMP_CAT 4 Hourly Y
EMP_CAT CAS Casual Y
EMP_CAT FR Full-time regular Y
EMP_CAT FR_01 Full-time Y
ABSENCE_CATEGORY DLHM Leave Y
ABSENCE_CATEGORY DLHNM Leave on the death of a husband Y
ABSENCE_CATEGORY DLR Leave on the death of a relative Y
ABSENCE_CATEGORY GB_ADO Adoption Y
ABSENCE_CATEGORY GB_PAT_ADO Paternity adoption Y
NATIONALITY PY Paraguayan Y
NATIONALITY QA Qatari Y
NATIONALITY RO Romanian Y
NATIONALITY RS Serbian
此表在不同的表中引用,如
table_assignment
emp no. name Employee category active/inactive
1 divya 3 A
2 abc FR A
3 XYZ 4 I
4 aMY 100 A
表table_nationality
Emp no. nationality
1 QA
2 RS
4 RO
即lookup_code
f已在table_Assignment
中的employee_category
table_nationality
列和国籍列中翻译。
我有一个类似的查询:
select emp_no.,
name,
employee_category
from table_assignment lookup_assignmen,
table_lookup lookup_stg
where lookup_stg.lookup_type = 'EMP_CAT'
AND LOOKUP_STG.LOOKUP_CODE = lookup_assignmen.employee_category;
类似table_nationality
之类的内容:
select emp_no.,
nationality
from TABLE_NATIONALITY lookup_NATIONALITY,
table_lookup lookup_stg
where lookup_stg.lookup_type = 'NATIONALITY'
AND LOOKUP_STG.LOOKUP_CODE = lookup_NATIONALITY.employee_category;
现在我想要一个动态查询来检测例如table_assignment
是否存在table_lookup
中没有的任何员工类别。
例如:在table_assignment
中,员工类别列中提供的值为100 table_lookup
中没有。
应在查询中检索此类值,但查询应该是动态的,以便它应检索table_Assignment
,table_nationality
或任何其他内容中的所有无效查找值
表。我可以在查询中输入lookup_type
和表名,并且应该检索无效值。
如何将静态查询更改为动态?
答案 0 :(得分:2)
你可以联合所有无效代码并避免使用动态sql。
select *
from (
select emp_no as entity_id, 'emp_cat' as lookup_type, eployee_category as invalid_lookup_code
from table_assignment e
left join table_lookup r
on e.employee_category = r.lookup_code
and r.lookup_type = 'emp_cat'
where r.lookup_type is null
union all
select emp_no as entity_id, 'nationality' as lookup_type, nationality as invalid_lookup_code
from table_nationality e
left join table_lookup r
on e.employee_category = r.lookup_code
and r.lookup_type = 'nationality'
where r.lookup_type is null
) as t
where t.lookup_type = 'nationality'
答案 1 :(得分:1)
您可以使用将Oracle Data Cartridge与ANY类型相结合的包在SQL中运行动态SQL。下面的代码使用了这个想法的my open source version。
即使使用预先构建的PL / SQL,这仍然是一项艰巨的任务,因为在查询中构建查询会让人感到困惑。并且不清楚表是如何映射在一起的,看起来没有外键或标准名称。我假设某处有一个映射表,或者可以创建一个映射表。对于演示,我创建了这个:
create table lookup_map(
table_name varchar2(30),
column_name varchar2(30),
lookup_type varchar2(100)
);
insert into lookup_map
select 'TABLE_ASSIGNMENT', 'EMPLOYEE_CATEGORY', 'EMP_CAT' from dual union all
select 'TABLE_NATIONALITY', 'NATIONALITY', 'NATIONALITY' from dual;
commit;
此代码将为每个表构建并运行动态查询,并UNION ALL
结果。
select * from table(method4.dynamic_query(
q'[
select replace(replace(replace(q'!
select '#TABLE_NAME#' table_name, emp_no, #COLUMN_NAME#
from #TABLE_NAME#
left join table_lookup
on #TABLE_NAME#.#COLUMN_NAME# = table_lookup.lookup_code
and table_lookup.lookup_type = '#LOOKUP_TYPE#'
where table_lookup.lookup_code is null
!',
'#TABLE_NAME#', table_name),
'#COLUMN_NAME#', column_name),
'#LOOKUP_TYPE#', lookup_type) v_sql
from lookup_map
]'
));
TABLE_NAME EMP_NO EMPLOYEE_CATEGORY
---------- ------ -----------------
TABLE_ASSIGNMENT 4 100
为了避免引号 - 地狱,最好使用替代引用机制(q')和REPLACE。引号在Stackoverflow语法高亮显示中看起来无与伦比,但它在Oracle IDE中应该看起来更好。
这对于这个确切的查询来说太过分了。但它为你提供了充足的成长空间。您可以更改查询并使其更加动态,无需任何其他PL / SQL代码。