华为云云数据库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返回值的变量。
查询语句中,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,重复的占位符不会再识别为同一个占位符。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
--从动态语句检索值(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; / --传递并检索值(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; / --调用存储过程 gaussdb=# CALL dynamic_proc(); --删除存储过程 gaussdb=# DROP PROCEDURE dynamic_proc; |
OPEN FOR
动态查询语句还可以使用OPEN FOR打开动态游标来执行。
语法参见图3。
图3 open_for::=
参数说明:
cursor_name:要打开的游标名。
dynamic_string:动态查询语句。
USING value:在dynamic_string中存在占位符时使用。
游标的使用请参考游标。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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; / |
父主题: 动态语句
同意关联代理商云淘科技,购买华为云产品更优惠(QQ 78315851)
内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家