用于在SQL

时间:2016-02-23 11:56:36

标签: sql oracle

我有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_Assignmenttable_nationality或任何其他内容中的所有无效查找值 表。我可以在查询中输入lookup_type和表名,并且应该检索无效值。

如何将静态查询更改为动态?

2 个答案:

答案 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代码。