不同操作数的 where 条件下的动态 PL SQL

Dynamic PL SQL in where condition for different operands

我有三个 table,即:

  1. Mains_Control
  2. Control_Mapping
  3. Control_Details

以及几个条件和列。但是我正在对下面给出的 tables 列执行动态操作。

我无法在 PL-SQL 程序中为以下条件编写动态 SQL 块。任何人都可以在这种特殊情况下帮助我。

SELECT * 
FROM CUR_ALL_CONTENTS
WHERE MAINS_CONTROL SWITCH = $SWITCH 
AND ($ATTRIB_COLUMNS = $ATTRIB_VAL 
  OR $ATTRIB_COLUMNS = $ATTRIB_VAL)

以上业务情况是这样的

SELECT * 
FROM CUR_ALL_CONTENTS 
WHERE MAINS_CONTROL_SWITCH = 'TYPE' 
AND (SWITCH_MODE = 'THRUST' OR SWITCH_MODE_GEAR = 'SEC_GEAR')

此处SWITCH属性值可以改变,ATTRIB_COLUMNS和ATTRIB_VAL可以改变。

  1. Mains_Control table 有以下列
    SWITCH     ACTION_CODE     RULE_MAP_1
    TYPE         ON            R1
    TYPE         OFF           R2
    METHOD      HOLD           R3
    METHOD     TERM_IN         R4
  1. Control_Mapping table 有以下列
    RULE_MAP_1     RULE_MAP_2
    R1             M11
    R2             M22
    R3             M33
    R4             M44
  1. Control_Details table 有以下列
    RULE_MAP_2     ATTRIB_COLUMNS     OPERAND     ATTRIB_VAL
    M11              SWTICH_MODE         =          THRUST
    M22           SWITCH_MODE_GEAR       =         SEC_GEAR
    M33             HOLD_RELEASE         <>          END

我仍然不清楚您如何确定应使用哪个条件以及何时使用。让我们用硬编码规则集给出这个例子:

DECLARE
    sqlstr VARCHAR2(30000);
    cur INTEGER;
    res INTEGER;
    refCur SYS_REFCURSOR;

    val Mains_Control.SWITCH%TYPE;

    CURSOR Conditions IS
    SELECT *
    FROM RULE_MAP_2 IN ('M11', 'M22');


BEGIN
    
    cur := DBMS_SQL.OPEN_CURSOR;
    
    sqlstr := 'SELECT * '||CHR(13);
    sqlstr := sqlstr || 'FROM CUR_ALL_CONTENTS '||CHR(13);
    sqlstr := sqlstr || 'WHERE MAINS_CONTROL_SWITCH = :switch AND (';
    FOR aCond IN Conditions LOOP
        sqlstr := sqlstr || aCond.ATTRIB_COLUMNS ||aCond.OPERAND||' :'||RULE_MAP_2 ||' OR '
    END LOOP;
    sqlstr := REGEXP_REPLACE(sqlstr, ' OR ', ')');
    DBMS_OUTPUT.PUT_LINE(sqlStr); --> verify generated statement
    
    DBMS_SQL.PARSE(cur, sqlStr, DBMS_SQL.NATIVE);
    
    SELECT SWITCH
    INTO val
    FROM Mains_Control
    WHERE RULE_MAP_1 = 'R1';
    DBMS_SQL.BIND_VARIABLE(cur, ':switch', sw);
    
    FOR aCond IN Conditions LOOP
        DBMS_SQL.BIND_VARIABLE(cur, ':'||aCond.RULE_MAP_2, aCond.ATTRIB_VAL);
    END LOOP;
    res := DBMS_SQL.EXECUTE(cur);   
    refCur := DBMS_SQL.TO_REFCURSOR(cur);
    
    FETCH refCur BULK COLLECT INTO ...;
    
END;

如果没有 DBMS_SQL.BIND_VARIABLE,代码会更简单,但是使用绑定变量是正确的做法。