GaussDB-执行动态查询语句

59 阅读3分钟

GaussDB-执行动态查询语句

介绍执行动态查询语句。GaussDB提供两种方式:使用EXECUTE IMMEDIATE、OPEN FOR实现动态查询。前者通过动态执行SELECT语句,后者结合了游标的使用。当需要将查询的结果保存在一个数据集用于提取时,可使用OPEN FOR实现动态查询。

EXECUTE IMMEDIATE

语法图请参见图1

图1 EXECUTE IMMEDIATE dynamic_select_clause::=

using_clause子句的语法图参见图2

图2 using_clause::=

对以上语法格式的解释如下:

  • define_variable,用于指定存放查询结果的变量。

  • USING IN bind_argument,用于指定存放传递给动态SQL值的变量,即在dynamic_select_string中存在占位符时使用。

  • USING OUT bind_argument,用于指定存放动态SQL返回值的变量。

    NOTICE:

    • 查询语句中,into和out不能同时存在;
    • 占位符命名以“:”开始,后面可跟数字、字符或字符串,与USING子句的bind_argument一一对应;
    • bind_argument只能是值、变量或表达式,不能是表名、列名、数据类型等数据库对象,即不支持使用bind_argument为动态SQL语句传递模式对象。如果存储过程需要通过声明参数传递数据库对象来构造动态SQL语句(常见于执行DDL语句时),建议采用连接运算符“||”拼接dynamic_select_clause;
    • 动态PL/SQL块允许出现重复的占位符,即相同占位符只能与USING子句的一个bind_argument按位置对应。当设置guc参数behavior_compat_options值为dynamic_sql_compat时,会按照占位符的顺序依次匹配USING子句bind_argument,重复的占位符不会再识别为同一个占位符。
    • IMMEDIATE关键字仅用作语法兼容,无实际意义。

示例

| ``` gaussdb=# DROP SCHEMA IF EXISTS hr CASCADE; gaussdb=# CREATE SCHEMA hr; gaussdb=# SET CURRENT_SCHEMA = hr; gaussdb=# CREATE TABLE staffs ( staff_id NUMBER, first_name VARCHAR2, salary NUMBER ); gaussdb=# INSERT INTO staffs VALUES (200, 'mike', 5800); gaussdb=# INSERT INTO staffs VALUES (201, 'lily', 3000); gaussdb=# INSERT INTO staffs VALUES (202, 'john', 4400); --从动态语句检索值(INTO 子句): gaussdb=# DECLARE staff_count VARCHAR2(20); BEGIN EXECUTE IMMEDIATE 'select count(*) from hr.staffs' INTO staff_count; dbe_output.print_line(staff_count); END; / 3 ANONYMOUS BLOCK EXECUTE --传递并检索值(INTO子句用在USING子句前): gaussdb=# CREATE OR REPLACE PROCEDURE dynamic_proc AS staff_id NUMBER(6) := 200; first_name VARCHAR2(20); salary NUMBER(8,2); BEGIN EXECUTE IMMEDIATE 'select first_name, salary from hr.staffs where staff_id = :1' INTO first_name, salary USING IN staff_id; dbe_output.print_line(first_name || ' ' || salary); END; / CREATE PROCEDURE --调用存储过程 gaussdb=# CALL dynamic_proc(); mike 5800.00 dynamic_proc -------------- (1 row) --删除存储过程 gaussdb=# DROP PROCEDURE dynamic_proc;

| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

#### OPEN FOR

动态查询语句还可以使用OPEN FOR打开动态游标来执行。

语法参见[图3](https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/devg-dist/gaussdb-12-0779.html#ZH-CN_TOPIC_0000001911586473__zh-cn_topic_0000001704538389_zh-cn_topic_0059778916_f3f108da94a694175ac707f4511b7f1a1)。

[]()[]()**图3** open_for::=  
![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e1d350ade46349758fea6eb6d1c19cb2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgamVycnl3YW5nMTk4Mw==:q75.awebp?rk3s=f64ab15b&x-expires=1771844999&x-signature=GPQmTXe6t5h5PRAfNs5vNDecARk%3D)

参数说明:

-   cursor_name:要打开的游标名。
-   dynamic_string:动态查询语句。
-   USING value:在dynamic_string中存在占位符时使用。

游标的使用请参考[游标](https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/devg-dist/gaussdb-12-0797.html#ZH-CN_TOPIC_0000001911665457)。

**示例**

| ```
gaussdb=# CREATE SCHEMA hr; gaussdb=# SET CURRENT_SCHEMA = hr; gaussdb=# CREATE TABLE staffs  (   section_id NUMBER,   first_name VARCHAR2,   phone_number VARCHAR2,    salary NUMBER   ); gaussdb=# INSERT INTO staffs VALUES (30, 'mike', '13567829252', 5800); gaussdb=# INSERT INTO staffs VALUES (40, 'john', '17896354637', 4000);  gaussdb=# DECLARE     name          VARCHAR2(20);     phone_number  VARCHAR2(20);     salary        NUMBER(8,2);     sqlstr        VARCHAR2(1024);      TYPE app_ref_cur_type IS REF CURSOR;  --定义游标类型     my_cur app_ref_cur_type;  --定义游标变量      BEGIN     sqlstr := 'select first_name,phone_number,salary from hr.staffs          where section_id = :1';     OPEN my_cur FOR sqlstr USING '30';  --打开游标, using是可选的     FETCH my_cur INTO name, phone_number, salary; --获取数据     WHILE my_cur%FOUND LOOP           dbe_output.print_line(name||'#'||phone_number||'#'||salary);           FETCH my_cur INTO name, phone_number, salary;     END LOOP;     CLOSE my_cur;   --关闭游标 END; / mike#13567829252#5800.00 mike#13567829252#5800.00 ANONYMOUS BLOCK EXECUTE 
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

更多详情请参考GaussDB 文档中心:<https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/productdesc/qlh_03_0001.html>