【问题标题】:Dynamic PL SQL in where condition for different operands不同操作数的 where 条件中的动态 PL SQL
【发布时间】:2023-03-28 22:58:01
【问题描述】:

我有三张桌子,即:

  1. Mains_Control
  2. Control_Mapping
  3. Control_Details

连同几个条件和列。但我正在对下面给出的表格列执行动态操作。

对于以下情况,我无法在 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 表具有以下列
    SWITCH     ACTION_CODE     RULE_MAP_1
    TYPE         ON            R1
    TYPE         OFF           R2
    METHOD      HOLD           R3
    METHOD     TERM_IN         R4
  1. Control_Mapping 表具有以下列
    RULE_MAP_1     RULE_MAP_2
    R1             M11
    R2             M22
    R3             M33
    R4             M44
  1. Control_Details 表包含以下列
    RULE_MAP_2     ATTRIB_COLUMNS     OPERAND     ATTRIB_VAL
    M11              SWTICH_MODE         =          THRUST
    M22           SWITCH_MODE_GEAR       =         SEC_GEAR
    M33             HOLD_RELEASE         <>          END

【问题讨论】:

  • 如何定义条件是$SWITCH AND ($ATTRIB_COLUMNS OR $ATTRIB_VAL)还是($SWITCH AND $ATTRIB_COLUMNS) OR $ATTRIB_VAL)
  • 很抱歉,这是业务状况。我编辑了这个问题。这就是业务逻辑。有时,它可以。 1. 查询 1 SELECT * FROM CUR_ALL_CONTENTS WHERE MAINS_CONTROL_SWITCH = "TYPE AND (SWITCH_MODE = "THRUST" OR SWITCH_MODE_GEAR = "SEC_GEAR") 或 2. 查询 2 SELECT * FROM CUR_ALL_CONTENTS WHERE MAINS_CONTROL_SWITCH = "METHOD AND (SWITCH_MODE = "THRUST" OR HOLD_RELEASE "结束")
  • 您的查询完全不清楚。为什么不WHERE MAINS_CONTROL_SWITCH = 'TYPE' AND (SWITCH_MODE = 'THRUST' OR HOLD_RELEASE &lt;&gt; "END")?你如何定义MAINS_CONTROL_SWITCH = 'TYPE'MAINS_CONTROL_SWITCH = 'METHOD'
  • MAINS_CONTROL_SWITCH 的值来自上游系统。它可以是基于业务逻辑的 TYPE 或 METHOD。因此,组合可以是任意数量。就像我在之前的评论中提到的那样。所以,我正在尝试使用动态 SQL 查询来满足要求。
  • @WernfriedDomscheit :我稍微调整了您的代码并添加了一些变量。我能够实现我的解决方案。非常感谢!

标签: sql oracle plsql dynamic-sql


【解决方案1】:

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

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,代码会更简单,但是使用绑定变量是正确的做法。

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    相关资源
    最近更新 更多