Skip to content

动态SQL

动态SQL是一种在运行时生成和运行SQL语句的编程方法。

PL/SQL提供了两种编写动态SQL的方法:原生动态SQL和DBMS_SQL包。关于后者的使用,可参阅相应文档:DBMS_SQL包

相比静态SQL,动态SQL通过损失一定的性能,换取更大的灵活性。动态SQL由于包含变化的部分,因此无法以普通语句的方式执行;而是在语句组装好后,以EXECUTE IMMEDIATE方式执行。

原生动态SQL编写的代码比使用DBMS_SQL包写出的等效代码更易读,并且运行速度也更快。但是用原生动态SQL代码必须在编译时知道输入和输出变量的数量和数据类型;如果在编译时还不能确定此类信息,则只能使用DBMS_SQL包。

示例

在用户下创建表并插入数据,再清空所有表数据,由于用户下的表是在运行时查询出来的,因此需要动态SQL在运行时得到最终的执行语句。

sql
-- 在用户下创建表
CREATE TABLE table1 (id NUMBER PRIMARY KEY, name VARCHAR2(100));
CREATE TABLE table2 (id NUMBER PRIMARY KEY, description VARCHAR2(100));

-- 插入数据
INSERT INTO table1 (id, name) VALUES (1, '记录1');
INSERT INTO table2 (id, description) VALUES (1, '描述1');

-- 查询表信息
SELECT*FROM TABLE1, TABLE2;

ID | NAME | ID | DESCRIPTION |
------------------------------------------------------------------------------
1| 记录1| 1| 描述1|

-- 使用动态SQL清空所有表
DECLARE
  v_sql VARCHAR2(200);
BEGIN
  -- 查询用户模式下的所有表名
  FOR t IN (SELECT table_name FROM user_tables) LOOP
    -- 构建动态SQL语句
    v_sql := 'TRUNCATE TABLE ' || t.table_name;

    -- 输出生成的SQL语句
    SEND_MSG(v_sql);

    -- 执行动态SQL语句
    EXECUTE IMMEDIATE v_sql;
  END LOOP;
END;
/

TRUNCATE TABLE TABLE1
TRUNCATE TABLE TABLE2

-- 查询表已被清空
SELECT*FROM TABLE1, TABLE2;

ID | NAME | ID | DESCRIPTION |
------------------------------------------------------------------------------

说明:

关于动态SQL的其他示例,可参阅EXECUTE语句