【问题标题】:Need assistance with IF ELSE condition in OracleOracle 中的 IF ELSE 条件需要帮助
【发布时间】:2021-02-08 15:37:10
【问题描述】:

我有一个表列表,我需要根据列名传递这些表。 例如,如果我的表有 CLASSID,它将进入块 2,如果表有 OBJID,它将进入块 1,如果表有 KOPPKT,它将进入块 3,但是如果任何表同时具有 CLASSID 和 OBJID,它应该进入块2 不是块 1
同样,如果任何表有 KOPPKT 和 OBJID,它应该去块 1 而不是块 3。在这里我面临将表发送到正确块的问题。
我试图实现但没有得到所需输出的代码。

desc TABLE1;
Name    Null     Type       
------- -------- ---------- 
CLASSID NOT NULL NUMBER(10) 
KOPPKT  NOT NULL NUMBER(10)
ID      NOT NULL NUMBER(10)

desc TABLE2;
Name    Null     Type       
------- -------- ---------- 
CLASSID NOT NULL NUMBER(10) 
OBJID   NOT NULL NUMBER(10) 

desc TABLE3;
Name    Null     Type       
------- -------- ---------- 
KOPPKT  NOT NULL NUMBER(10) 
OBJID   NOT NULL NUMBER(10) 

这里 Table1 和 table2 应该去块 2,因为它有 CLASSID,table3 应该去块 1,因为它有 OBJID

set serveroutput on
declare
v_exporttable VARCHAR2(100):='TABLE1';
v_name varchar2(100);
begin
FOR rec IN
  (
  select  distinct column_name from all_tab_cols
  where table_name = v_exporttable
  ) loop
  if (rec.column_name ='OBJID') then
   DBMS_OUTPUT.PUT_LINE('Table has OBJID'); /*  block 1 */
  elsif (rec.column_name ='CLASSID') then
   DBMS_OUTPUT.PUT_LINE('Table has Classid'); /*  block 2 */
  elsif (rec.column_name = 'KOPPKT') then
   DBMS_OUTPUT.PUT_LINE('Table has KOPPKT'); /*  block 3 */
  end if;
end loop;
end;
/

传递 Table1 我得到的第一个输出。这意味着它同时通过块 2 和块 3。但我只想通过块 2

PL/SQL procedure successfully completed.

Table has Classid
Table has KOPPKT

同样,如果我通过表 2,我就会得到这个。这意味着它同时通过块 1 和块 2。但我只想通过块 2

PL/SQL procedure successfully completed.

Table has OBJID
Table has CLASSID 

同样,如果我通过了表 3,我就会得到这个。这意味着它同时通过块 1 和块 3。但我只想通过块 2

PL/SQL procedure successfully completed.

Table has OBJID
Table has KOPPKT

我已经尝试过以下情况,但仍然无法正常工作

(rec.column_name ='OBJID' and rec.column_name <>'CLASSID')

【问题讨论】:

    标签: sql oracle plsql oracle11g oracle-sqldeveloper


    【解决方案1】:

    使用LISTAGG 查找表中所有感兴趣的列,然后检查CASE 语句中的各个组合。在CLASSID 之前设置条件CLASSID 和一些东西:

    with tab_cols as (
      select table_name,
        listagg(column_name, '|') within group(order by 1) as cols
      from all_tab_cols
      where table_name in (<your list>)
        and column_name in ('CLASSID', 'OBJID', 'KOPPKT')
      group by table_name
    )
    select table_name,
      case
        when instr(cols, 'CLASSID') > 0 then 2
        when instr(cols, 'OBJID') > 0 then 1
        when instr(cols, 'KOPPKT') > 0 then 3
      end as block_number
    from tab_cols
    

    【讨论】:

    • 我想这个答案最适合我。我已将此更改为我的 pl sql 块,它给出了准确的输出。非常感谢
    • @goldenbutter 希望您可以使用 PL/SQL 代码处理基本结果,因此我发布了您需要的干净数据源
    • 嗨,你能告诉我如何在 instr 中搜索精确的单词匹配,例如,如果我的列名是 ID,我需要将它发送到 block1,但在 CLASSID 列中我也得到 ID并发送该块 2。
    • @goldenbutter 您可以使用 regexp_instr('|' || cols || '|', '\|' || || '\|') 作为分隔符“管道”(' |') 喜欢我的回答
    【解决方案2】:

    SQL 语句中的条件聚合可用于将所需的块名称确定为本地字符串变量:

    SQL> SET SERVEROUTPUT ON 
    SQL> DECLARE
      v_name        VARCHAR2(10);
      v_exporttable VARCHAR2(100);
    BEGIN
      SELECT CASE WHEN SUM(CASE WHEN column_name IN ( 'CLASSID', 'OBJID' )
                  THEN 1 
                  ELSE 0 
              END) = 2 
                  THEN 
                       'Block 2' 
                  ELSE CASE WHEN SUM(CASE WHEN column_name IN ( 'KOPPKT', 'OBJID' )
                            THEN 1
                            ELSE 0
                             END) = 2
                            THEN 
                              'Block 1' 
                            ELSE 
                              'Block 3'
                        END         
                   END 
        INTO v_name           
        FROM user_tab_cols
       WHERE table_name = v_exporttable;
    
      DBMS_OUTPUT.PUT_LINE('Returning Block Name is '||v_name);
    END;
    /
    

    Demo

    更新:根据您告诉 Table1 出错的最后一条评论......它应该进入第 2 块,您可以将代码重新排列为

    DECLARE
      v_name        VARCHAR2(10);
      v_exporttable VARCHAR2(100);
    BEGIN
      SELECT CASE WHEN SUM(CASE WHEN column_name = 'CLASSID'
                  THEN 1 
                  ELSE 0 
                   END) > 0 
                  THEN 
                       'Block 2' 
                  ELSE CASE WHEN SUM(CASE WHEN column_name IN ( 'KOPPKT', 'OBJID' )
                            THEN 1
                            ELSE 0
                             END) = 2
                            THEN 
                              'Block 1' 
                            ELSE 
                              'Block 3'
                        END         
                   END 
        INTO v_name             
        FROM user_tab_cols
       WHERE table_name = v_exporttable;
    
      DBMS_OUTPUT.PUT_LINE('Returning Block Name is '||v_name);
    END;
    /
    

    Demo2

    【讨论】:

    • 嗨,谢谢。我已经测试过了。根据您的示例,Table1 也应该像 Table2 一样进入块 2,因为两者都有 classid 但它进入块 3。
    • 嗨@goldenbutter。但在任何情况下,表格都不会产生Block3。此外,您告诉 如果表有 KOPPKT,它将进入块 3 ,并且没有提到任何表是否同时具有 KOPPKT 和 CLASSID 的情况,它引用了 TABLE1。
    • 我写过这个“同样,如果任何表有 KOPPKT 和 OBJID,它应该去块 1 而不是块 3”:-) 无论如何,Table1 出错了......它应该去block 2
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多