• Oracle的动态SQL


    例1:传递表名,和Where条件删除数据

    CREATE OR REPLACE PROCEDURE raise_emp_salary (column_value NUMBER, 
                                 emp_column VARCHAR2, amount NUMBER) IS
       v_column VARCHAR2(30);
       sql_stmt  VARCHAR2(200);
    BEGIN
    -- determine if a valid column name has been given as input
      SELECT COLUMN_NAME INTO v_column FROM USER_TAB_COLS 
        WHERE TABLE_NAME = 'EMPLOYEES' AND COLUMN_NAME = emp_column;
      sql_stmt := 'UPDATE employees SET salary = salary + :1 WHERE ' 
                   || v_column || ' = :2';
      EXECUTE IMMEDIATE sql_stmt USING amount, column_value;
      IF SQL%ROWCOUNT > 0 THEN
        DBMS_OUTPUT.PUT_LINE('Salaries have been updated for: ' || emp_column 
                            || ' = ' || column_value);
      END IF;
      EXCEPTION
      WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE ('Invalid Column: ' || emp_column);
    END raise_emp_salary;
    /
    
    DECLARE
       plsql_block       VARCHAR2(500);
    BEGIN
    -- note the semi-colons (;) inside the quotes '...'
      plsql_block := 'BEGIN raise_emp_salary(:cvalue, :cname, :amt); END;';
      EXECUTE IMMEDIATE plsql_block USING 110, 'DEPARTMENT_ID', 10;
      EXECUTE IMMEDIATE 'BEGIN raise_emp_salary(:cvalue, :cname, :amt); END;'
          USING 112, 'EMPLOYEE_ID', 10;
    END;
    /
    
    DECLARE
       sql_stmt          VARCHAR2(200);
       v_column          VARCHAR2(30) := 'DEPARTMENT_ID';
       dept_id           NUMBER(4) := 46;
       dept_name         VARCHAR2(30) := 'Special Projects';
       mgr_id            NUMBER(6) := 200;
       loc_id            NUMBER(4) := 1700;
    BEGIN
    -- note that there is no semi-colon (;) inside the quotes '...'
      EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
      sql_stmt := 'INSERT INTO departments VALUES (:1, :2, :3, :4)';
      EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, mgr_id, loc_id;
      EXECUTE IMMEDIATE 'DELETE FROM departments WHERE ' || v_column || ' = :num'
          USING dept_id;
      EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE';
      EXECUTE IMMEDIATE 'DROP TABLE bonus';
    END;
    /

    例2 动态的表名和Where语句

    CREATE TABLE employees_temp AS SELECT * FROM employees;
    
    CREATE OR REPLACE PROCEDURE delete_rows (
       table_name IN VARCHAR2,
       condition  IN VARCHAR2 DEFAULT NULL) AS
       where_clause  VARCHAR2(100) := ' WHERE ' || condition;
       v_table      VARCHAR2(30);
    BEGIN
    -- first make sure that the table actually exists; if not, raise an exception
      SELECT OBJECT_NAME INTO v_table FROM USER_OBJECTS
        WHERE OBJECT_NAME = UPPER(table_name) AND OBJECT_TYPE = 'TABLE';
       IF condition IS NULL THEN where_clause := NULL; END IF;
       EXECUTE IMMEDIATE 'DELETE FROM ' || v_table || where_clause;
      EXCEPTION
      WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE ('Invalid table: ' || table_name);
    END;
    /
    BEGIN
      delete_rows('employees_temp', 'employee_id = 111');
    END;
    /

    例3 替换IN和OUT参数

    DECLARE
       plsql_block VARCHAR2(500);
       new_deptid  NUMBER(4);
       new_dname   VARCHAR2(30) := 'Advertising';
       new_mgrid   NUMBER(6) := 200;
       new_locid   NUMBER(4) := 1700;
    BEGIN
       plsql_block := 'BEGIN create_dept(:a, :b, :c, :d); END;';
       EXECUTE IMMEDIATE plsql_block
          USING IN OUT new_deptid, new_dname, new_mgrid, new_locid;
    END;
    /

    例4 使用BULK COLLECT INTO的动态SQL

    DECLARE
       TYPE EmpCurTyp IS REF CURSOR;
       TYPE NumList IS TABLE OF NUMBER;
       TYPE NameList IS TABLE OF VARCHAR2(25);
       emp_cv EmpCurTyp;
       empids NumList;
       enames NameList;
       sals   NumList;
    BEGIN
       OPEN emp_cv FOR 'SELECT employee_id, last_name FROM employees';
       FETCH emp_cv BULK COLLECT INTO empids, enames;
       CLOSE emp_cv;
       EXECUTE IMMEDIATE 'SELECT salary FROM employees'
          BULK COLLECT INTO sals;
    END;
    /

    例5 使用RETURNING BULK COLLECT INTO的动态SQL

    DECLARE
       TYPE NameList IS TABLE OF VARCHAR2(15);
       enames    NameList;
       bonus_amt NUMBER := 50;
       sql_stmt  VARCHAR(200);
    BEGIN
       sql_stmt := 'UPDATE employees SET salary = salary + :1 
                    RETURNING last_name INTO :2';
       EXECUTE IMMEDIATE sql_stmt
          USING bonus_amt RETURNING BULK COLLECT INTO enames;
    END;
    /

    例6 FORALL中的动态SQL

    DECLARE
       TYPE NumList IS TABLE OF NUMBER;
       TYPE NameList IS TABLE OF VARCHAR2(15);
       empids NumList;
       enames NameList;
    BEGIN
       empids := NumList(101,102,103,104,105);
       FORALL i IN 1..5
          EXECUTE IMMEDIATE
            'UPDATE employees SET salary = salary * 1.04 WHERE employee_id = :1
             RETURNING last_name INTO :2'
             USING empids(i) RETURNING BULK COLLECT INTO enames;
    END;
    /

    例7 在动态SQL中重复使用Placeholder

    CREATE PROCEDURE calc_stats(w NUMBER, x NUMBER, y NUMBER, z NUMBER) IS
    BEGIN
      DBMS_OUTPUT.PUT_LINE(w + x + y + z);
    END;
    /
    DECLARE
       a NUMBER := 4;
       b NUMBER := 7;
       plsql_block VARCHAR2(100);
    BEGIN
       plsql_block := 'BEGIN calc_stats(:x, :x, :y, :x); END;';
       EXECUTE IMMEDIATE plsql_block USING a, b;
    END;
    /

    例8 对%ROWCOUNT的访问

    DECLARE
      TYPE cursor_ref IS REF CURSOR;
      c1 cursor_ref;
      TYPE emp_tab IS TABLE OF employees%ROWTYPE;
      rec_tab emp_tab;
      rows_fetched NUMBER;
    BEGIN
      OPEN c1 FOR 'SELECT * FROM employees';
      FETCH c1 BULK COLLECT INTO rec_tab;
      rows_fetched := c1%ROWCOUNT;
      DBMS_OUTPUT.PUT_LINE('Number of employees fetched: ' || TO_CHAR(rows_fetched));
    END;
    /

    例9 对数据集的动态Fetch

    DECLARE
       TYPE EmpCurTyp IS REF CURSOR;
       emp_cv   EmpCurTyp;
       emp_rec  employees%ROWTYPE;
       sql_stmt VARCHAR2(200);
       v_job   VARCHAR2(10) := 'ST_CLERK';
    BEGIN
       sql_stmt := 'SELECT * FROM employees WHERE job_id = :j';
       OPEN emp_cv FOR sql_stmt USING v_job;
       LOOP
         FETCH emp_cv INTO emp_rec;
         EXIT WHEN emp_cv%NOTFOUND;
         DBMS_OUTPUT.PUT_LINE('Name: ' || emp_rec.last_name || ' Job Id: ' ||
                               emp_rec.job_id);
       END LOOP;
       CLOSE emp_cv;
    END;
    /

  • 相关阅读:
    Python高效编程技巧
    Python使用Flask框架,结合Highchart,自定义图表样式主题
    Python使用Flask框架,结合Highchart,自定义基本上算是最全的导出菜单了
    Python使用Flask框架,结合Highchart,自定义导出菜单项目及顺序
    Python使用Flask框架,结合Highchart,搭配数据功能模块,加载 HTML 表格数据
    Python使用Flask框架,结合Highchart,搭配数据功能模块处理csv数据
    Python使用Flask框架,结合Highchart处理jsonl数据
    Python使用Flask框架,结合Highchart处理xml数据
    Python使用Flask框架,结合Highchart处理csv数据(引申-从文件获取数据--从数据库获取数据)
    使用Python的Flask框架,结合Highchart,动态渲染图表(Ajax 请求数据接口)
  • 原文地址:https://www.cnblogs.com/sekihin/p/3340627.html
  • Copyright © 2020-2023  润新知
    Creative Commons License 本作品采用 知识共享署名-非商业性使用 2.5 中国大陆许可协议进行许可。