返回首页

gbase数据、南大通用产品文档:GBase8s延迟执行 SQL PREPARE 语句

更新日期:2024年09月11日

可以通过启用 deferred-PREPARE 功能来延迟 SQLPrepare 语句的执行。
此功能适用于应用程序执行一系列的 SQLPrepare 和 SQLExecute 语句的动态 SQL 语句。
它通过在应用程序对该语句调用 SQLExecute 之前不向数据库服务器发送 SQLPrepare语
句的方式来优化到数据库服务器的往返消息的数量。
当启用 deferred-PREPARE 后,应用程序执行以下行为:
 执行 SQLPrepare 不会将语句置于准备好的状态。
 在执行语句之前,SQLPrepare 语句中的语法错误是未知的,因为该 SQL 语句在执
行之前不会发送到数据库服务器。如果打开 open-fetch-close 优化功能,则直到第一
次访存之前错误不会返回到客户端,因为 open-fetch-close 优化了 OPEN/FETCH,
所以在第一次访存时发送 OPEN。
 如果应用程序在调用 SQLPrepare 之后,SQLExecute 之前调用 SQLColAttributes 、
SQLDescribeCol、SQLNumResultCols 和 SQLNumParams,则始终返回 HY010(函
数序列错误)。
 如果源描述符句柄在 SQLPrepare 之后,但在应用程序执行 SQLExecute之前调用,
则 SQLCopyDesc 返回 HY010。
 如果描述符句柄是一个 IRD,
并且应用程序在 SQLPrepare 之后 SQLExecute之前调
用,则 SQLGetDescField 和 SQLGetDescRec 返回 HY010。
可以使用以下方式启用 ODBC 应用程序的 deferred-PREPARE 功能:
 使用 SQLSetConnectAttr 设置 SQL_INFX_ATTR_DEFERRED_PREPARE 属性。

GBase 8s ODBC Driver 程序员指南
南大通用数据技术股份有限公司
- 191 -
 当使用 SQLSetConnectAttr启用该属性时,所有为此连接新分配的语句都会继承该属
性值。
更改该属性的唯一方法是设置每一条语句并将它重新设置为语句的属性。
连接
属性缺省为 DISABLED 。
 使用 SQLSetStmtAttr 设置 SQL_INFX_ATTR_AUTO_FREE 属性。
当使用 SQLSetConnectAttr 进行设置 SQL_INFX_ATTR_DEFERRED_PREPARE 属性时,
可以在 C2 和 C5 之间(包括两者)的任何连接状态中进行设置
SQL_INFX_ATTR_DEFERRED_PREPARE 属性。
而只有当语句处于 S1 (分配)
状态时,
才能使用 SQLSetStmtAttr 设置此属性。可以通过使用 SQLGetConnectAttr 或
SQLSetStmtAttr 检索 SQL_INFX_ATTR_DEFERRED_PREPARE 属性的值。

记录变量支持为每个域单独赋值,有些情况下支持将一个记录变量赋值给另外一个记
录变量。记录变量间的赋值记录变量必须具有相同的记录类型。
CREATE OR REPLACE PROCEDURE P_5_34 AS
TYPE name_rec IS RECORD (
first VARCHAR(100) DEFAULT 'John',
last VARCHAR(100) DEFAULT 'Doe'
);
name1 name_rec;
name2 name_rec;
BEGIN
name1.first := 'Jane'; name1.last := 'Smith';
DBMS_OUTPUT.PUT_LINE('name1: ' || name1.first || ' ' || name1.last);
name2 := name1; --相同记录类型的变量是可以相互赋值的
DBMS_OUTPUT.PUT_LINE('name2: ' || name2.first || ' ' || name2.last);
END;

--Result:
--name1: Jane Smith
--name2: Jane Smith
整行或行的一部分赋值给记录变量
l
SELECT INTO
语法
SELECT select_list INTO record_variable_name FROM table_or_view_name;
对于select_list中的每列,记录变量必须有相对应的类型相兼容的域。select_list 的列
必须和记录中的域具有相同的顺序。
CREATE OR REPLACE PROCEDURE P_5_35 AS
TYPE RecordTyp IS RECORD (

GBase 8s PL/SQL手册
南大通用数据技术股份有限公司
- 90 -

last VARCHAR(100),
id NUMBER(6)
);
rec1 RecordTyp;
BEGIN
SELECT last_name, employee_id INTO rec1
FROM employees
WHERE job_id = 'AD_PRES';
DBMS_OUTPUT.PUT_LINE ('Employee #' || rec1.id || ' = ' || rec1.last);
END;

--Result:
--Employee #100 = King
l
FETCH INTO
语法
FETCH cursor INTO record_variable_name;
一个游标关联一个查询,对每个查询的列,都得在记录变量里有对应的互兼容类型的
域。游标必须是一个显式游标变量或者一个强游标变量。
l
赋值NULL
将NULL赋值给记录变量,其实就是把NULL赋值给他的每一个域。这个赋值是递归
的,也就是说,如果一个字段是记录变量,那么他的域也被赋值为NULL。
CREATE OR REPLACE PROCEDURE P_5_36 as
TYPE EmpRecTyp IS RECORD (
emp_id NUMBER(6),
salary NUMBER(6)
);
highest_paid_emp EmpRecTyp;
next_highest_paid_emp EmpRecTyp;
CURSOR desc_salary IS
SELECT employee_id, salary
FROM employees
ORDER BY salary DESC;
BEGIN
OPEN desc_salary;
FOR i IN 1..1 LOOP
FETCH desc_salary INTO highest_paid_emp;
END LOOP;
CLOSE desc_salary;

OPEN desc_salary;

GBase 8s PL/SQL手册
南大通用数据技术股份有限公司
- 91 -

FOR i IN 1..2 LOOP
FETCH desc_salary INTO next_highest_paid_emp;
END LOOP;
CLOSE desc_salary;

DBMS_OUTPUT.PUT_LINE('Highest Paid: #' || highest_paid_emp.emp_id || ', $' ||
highest_paid_emp.salary);
DBMS_OUTPUT.PUT_LINE('Next Highest Paid: #' || next_highest_paid_emp.emp_id || ', $' ||
next_highest_paid_emp.salary);
END;

--Result:
--Highest Paid: #100, $24000
--Next Highest Paid: #101, $17000

功能说明
使用CALL 语句调用已经创建的存储过程。使用SELECT 语句调用函数。
语法格式
CALL [database_name.]proc_name([parameter_1[,…,parameter_n]]);
SET @Variable_name = func_name([parameter_1[,…,parameter_n]]);
SELECT @Variable_name;
表5- 170 参数说明
参数名称


proc_name
要调用的存储过程名称。
parameter
调用参数。如果存储过程有参数,则必须按照存储过程的定
义中的顺序和类型为参数赋值,同时,对于OUT 和INOUT
参数,必须指明OUT 和INOUT 关键字。
func_name
要调用的函数的名称。
Variable_name
变量名,可以将函数的执行结果赋予一个变量。
说明

针对无参数存储过程,
<存储过程名称>后面是否添加括号,
执行结果一致。

GBase 8a MPP Cluster 使用SELECT 语句查看调用函数的执行结果。
示例
示例1:调用存储过程示例。
gbase> USE test;
Query OK, 0 rows affected
gbase> DELIMITER //

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1343
gbase> DROP PROCEDURE proc_count //
Query OK, 0 rows affected
gbase> CREATE PROCEDURE proc_count (OUT param1 INT,IN param2
varchar(10))
BEGIN
SELECT COUNT(*) INTO param1 FROM ssbm.customer
WHERE c_nation= param2;
END //
Query OK, 0 rows affected
gbase> CALL proc_count(@count1, 'JORDAN') //
Query OK, 0 rows affected
gbase> DELIMITER ;
gbase> SELECT @count1 ;
+---------+
| @count1 |
+---------+
|
1182 |
+---------+
1 row in set
示例2:调用函数示例。
gbase> USE test;
Query OK, 0 rows affected
gbase> DELIMITER //
gbase> DROP FUNCTION hello //
Query OK, 0 rows affected
gbase> CREATE FUNCTION hello (s CHAR(20)) RETURNS
VARCHAR(50)
RETURN CONCAT('Hello, ',s,'!') //
Query OK, 0 rows affected
gbase> DELIMITER ;
gbase> SET @result = hello('world');
Query OK, 0 rows affected
gbase> SELECT @result;
+------------------------------+
| @result
|
+------------------------------+

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1344
| Hello, world
! |
+------------------------------+
1 row in set