【问题标题】:PLSQL: edit cursor at runtimePLSQL:在运行时编辑光标
【发布时间】:2014-01-22 16:15:53
【问题描述】:

我有点困惑

在这样的函数/过程中是否可能?

CURSOR CR IS
SELECT
FROM
WHERE Y = X

稍后在正文中,将 X 值更改为 Z 或其他值,然后重新打开游标以获取 Y = Z 的行?

【问题讨论】:

    标签: plsql cursor


    【解决方案1】:

    有几种方法可以在不使用动态 SQL 的情况下做到这一点。一种选择是使用参数化游标:

    DECLARE
      nSome_value  NUMBER := 666;
    
      CURSOR CR(parmSome_value NUMBER) IS
        SELECT *
          FROM SOME_TABLE
          WHERE SOME_COLUMN = parmSome_value;
    BEGIN
      nSome_value := 123; -- change value of nSome_value
    
      OPEN CR(nSome_value);  -- pass nSome_value in as the value of the cursor parameter
    
      -- Fetch from the cursor, do whatever
    
      CLOSE CR;
    END;
    

    它仍然是静态 SQL,但是通过将参数传递给游标,可以增加游标的可重用性。

    另一种选择是使用游标 FOR 循环,在循环的 SQL 中引用变量:

    DECLARE
      nSome_value  NUMBER := 666;
    BEGIN
      nSome_value := 123; -- change value of nSome_value
    
      FOR aRow IN (SELECT *
                     FROM SOME_TABLE
                     WHERE SOME_COLUMN = nSome_value)
      BEGIN
        -- Do something useful with the rows returned by the cursor
      END LOOP;
    END;
    

    请注意,在这些情况下,您不会更改 SQL - 您只是更改查询中使用的变量或参数的值。这些方法的一个优点是,与动态生成的 SQL 不同,它们不易受到 SQL 注入攻击。

    分享和享受。

    【讨论】:

    • @ro.nin 另一个主要优点是PL/SQL编译器可以检查SQL。
    【解决方案2】:

    是的,试试这样的(快速输入,因此语法可能不准确)

    sql   VARCHAR2(255);
    cur   REF CURSOR;
    val   varchar2(100);
    
    val := X;
    sql :=  'SELECT .. FROM .. WHERE Y = :val';
    
    open cur for
        sql
        USING val;
    
    close cur;
    ....
    
    val := Z;
    
    open cur for
        sql
        USING val;
    

    【讨论】:

    • 谢谢,原来是sql动态
    • @ro.nin 是的,这行得通,但最好不要使用动态 sql,除非你真的必须这样做。在这种情况下,更好的选择是使用 Bob Jarvis 所示的参数化光标。
    【解决方案3】:

    这也可以通过使用类似函数的子程序而不是使用光标来完成

    将缩短代码:

    创建或替换函数 getashish(dept varchar2) return emp3 as

    emp5 emp3 := emp3();

    str varchar2(300);

    开始

    str := 'selectemp1(e.last_name,l.city,e.salary) 从员工 e 加入部门 d

    on e.department_id = d.department_id 加入位置 l on d.location_id=l.location_id where

    d.department_name = :dept';

    立即执行 str 批量收集到 emp5 使用部门;

    返回 emp5; 结束;

    在这里你必须创建一个对象,包括你想要的返回类型,然后创建该对象的表:

    创建或替换类型 emp1 作为对象 (lname varchar2(10),city varchar2(10),sal number(10));

    创建或替换 键入 emp3 作为 emp1 的表;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-19
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      相关资源
      最近更新 更多