zoukankan      html  css  js  c++  java
  • Oracle 11g Release 1 (11.1) PL/SQL_了解静态和动态 SQL

    http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/static.htm#BABGEDAE

    http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm#CACDDACH

    本文内容

    • 静态 SQL
    • 动态 SQL

    静态 SQL

    静态 SQL 是属于 PL/SQL 语言的 SQL。也就是:

    • 除了解释执行计划的,数据操作语句(Data Manipulation Language,DML)
    • 事务控制(Transaction Control Language,TCL)语句
    • SQL 函数
    • SQL 伪列
    • SQL 运算符

    静态 SQL 符合目前 ANSI/ISO SQL 标准。

    示例 1:演示用 PL/SQL 操作数据

    若操作数据库的数据,则无需任何特别的符号,你可以直接在 PL/SQL 程序里包含 DML 操作,如 INSERTUPDATEDELETE 语句。你也可以直接在 PL/SQL 程序里包含 COMMIT 语句。

    CREATE TABLE employees_temp
      AS SELECT employee_id, first_name, last_name 
      FROM employees;
    DECLARE
      emp_id          employees_temp.employee_id%TYPE;
      emp_first_name  employees_temp.first_name%TYPE;
      emp_last_name   employees_temp.last_name%TYPE;
    BEGIN
       INSERT INTO employees_temp VALUES(299, 'Bob', 'Henry');
       UPDATE employees_temp
         SET first_name = 'Robert' WHERE employee_id = 299;
       DELETE FROM employees_temp WHERE employee_id = 299 
         RETURNING first_name, last_name
           INTO emp_first_name, emp_last_name;
       COMMIT;
       DBMS_OUTPUT.PUT_LINE( emp_first_name  || ' ' || emp_last_name);
    END;
    /

    示例 2:演示在 PL/SQL 调用 SQL 函数——COUNT 函数

    DECLARE
      job_count NUMBER;
      emp_count NUMBER;
    BEGIN
      SELECT COUNT(DISTINCT job_id)
        INTO job_count
          FROM employees;
     
      SELECT COUNT(*)
        INTO emp_count
          FROM employees;
    END;
    /

    示例 3:演示使用伪列——ROWNUM

    CREATE TABLE employees_temp AS SELECT * FROM employees;
    DECLARE
       CURSOR c1 IS SELECT employee_id, salary FROM employees_temp
          WHERE salary > 2000 AND ROWNUM <= 10;  -- 10 arbitrary rows
       CURSOR c2 IS SELECT * FROM
         (SELECT employee_id, salary FROM employees_temp
           WHERE salary > 2000 ORDER BY salary DESC)
         WHERE ROWNUM < 5;  -- first 5 rows, in sorted order
    BEGIN
    -- Each row gets assigned a different number
      UPDATE employees_temp SET employee_id = ROWNUM;
    END;
    /

    动态 SQL

    动态 SQL 是用编程的方式在运行时创建并执行 SQL 语句。这在编写通用或灵活的程序,像 ad hoc 查询系统,或在编写必须执行 DLL 语句的程序,或是在编译期间不确定整个 SQL 文本、数量,以及输入输出变量的数据类型时,很有用。

    PL/SQL 提供两种方式编写动态 SQL:

    • 本地动态 SQL(Native dynamic SQL),创建并执行动态 SQL 语句是 PL/SQL 语言的特点
    • DBMS_SQL 包是创建、执行和描述动态 SQL 语言的 API

    Native dynamic SQL 代码比其等价的使用 DBMS_SQL package 代码更容易读写,执行也快。特别是,当它通过编译器优化后。然而,若编写 Native dynamic SQL 代码,你必须在编译期间知道输入和输出变量的数据类型和数量。否则,只能使用 DBMS_SQL package

    当你同时需要 Native dynamic SQLDBMS_SQL package 时,你可以通过 DBMS_SQL.TO_REFCURSOR 函数和 DBMS_SQL.TO_CURSOR_NUMBER 函数在它们之间进行切换。

    何时使用静态 SQL 或动态 SQL

    在 PL/SQL,下面情况需要动态 SQL:

    • 编译期间无法确定 SQL 文本。例如,SELECT 语句包含一个事先不确定的标识符,如表名,或是 WHERE 子句中的一部分在编译期间不确定。
    • 静态 SQL不支持的。也就是不能用静态 SQL 创建的任何 SQL。

    若不需要动态 SQL,则使用静态 SQL 的好处如下:

    • 成功的编译会验证静态 SQL 引用可靠的数据库对象,以及访问这些对象的必需权限。
    • 成功的编译会创建模式对象依赖。

    示例 4:演示从动态 PL/SQL 块调用一个子程序

    -- Subprogram that dynamic PL/SQL block invokes:
    CREATE PROCEDURE create_dept ( deptid IN OUT NUMBER,
                                   dname  IN VARCHAR2,
                                   mgrid  IN NUMBER,
                                   locid  IN NUMBER
                                 ) AS
    BEGIN
    deptid := departments_seq.NEXTVAL;
      INSERT INTO departments VALUES (deptid, dname, mgrid, locid);
    END;
    /
    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
     -- Dynamic PL/SQL block invokes subprogram:
      plsql_block := 'BEGIN create_dept(:a, :b, :c, :d); END;';
     
     /* Specify bind arguments in USING clause.
        Specify mode for first parameter.
        Modes of other parameters are correct by default. */
      EXECUTE IMMEDIATE plsql_block
        USING IN OUT new_deptid, new_dname, new_mgrid, new_locid;
    END;
    /

  • 相关阅读:
    domain logic approaches
    远程连接mysql提示:1251-client does not support authentication protocol requested by server
    Navicat远程连接mysql时,报错误“Can't connect to MySQL server on 'ip'(10038)”的解决方法
    XShell连接不了(ubunt14.04)虚拟机Could not connect to ‘192.168.1.105’ (port 22): Connection failed
    Ubuntu20.04 安装和卸载MySQL8
    linux系统(Ubuntu)之合上笔记本盖但不断网
    Ubuntu20.04 FTP服务器的搭建
    Ubuntu20.04安装SqlServer2019教程-简洁版
    Linux更改主机名的三种方法
    ubuntu grub引导win10
  • 原文地址:https://www.cnblogs.com/liuning8023/p/2506987.html
Copyright © 2011-2022 走看看