返回首页

gbase数据、南大通用产品文档:GBase8sPREPARE 语句

更新日期:2024年09月11日

使用 PREPARE 语句可在运行时解析、验证和生成一个或多个 SQL 语句的执行
计划。
语法

元素
描述
限制
语法
char_expression
计算得到单个
SQL 语句的文本
的表达式
必须为 SELECT、EXECUTE
FUNCTION 或 EXECUTE
PROCEDURE 语句
表达式

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 766
元素
描述
限制
语法
statement_id
为准备好的对象
在此声明的标识

在游标和准备好的对象的
名称之中(以及 SPL 中,
在变量之中)必须是唯一
的。
标识符
statement_id_var
存储
statement_id
的主变量
必须先前已声明为字符数
据类型
特定于
语言
statement_text
要准备的 SQL
语句的文本
请参阅 准备多个 SQL 语
句 和 语句文本。
引用字
符串.
statement_var
存储一个或多个
SQL 语句的主变

必须为字符数据类型。如
果 SQL 语句包含“集合派
生的表”段,则无效。
特定于
语言
用法
请在 ESQL/C 或 SPL 例程中使用此语句。
PREPARE 语句启用您的程序来在运行时收集一个(或对于 ESQL/C,多于一
个)SQL 语句的文本,来声明结果的准备好的对象的标识符,并使之可运行。以
三个步骤实现此 SQL 的动态形式:
1. PREPARE 语句接收语句文本为输入,或作为引用的字符串,或 ESQL/C
字符变量,或(在 SPL 中)作为字符表达式计算的值。语句文本可包含
问号(?)占位符来表示要到执行该语句时定义的值。
2. OPEN 语句(以及在 ESQL/C 例程中,EXECUTE 语句)可提供所需要
的输入值并一次或多次执行准备好的语句。
3. 稍后,可使用 FREE 语句释放那些分配给准备好的语句的资源。
要获取更多关于在准备好的语句中以运行时的值替换占位符的信息,请参阅章节
准备接收参数的语句。
当您创建准备好的对象时的整理顺序为当前,执行那个对象时的整理顺序也一
样,即使该会话的(或 DB_LOCALE 的)执行时整理是不同的。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 767
限制
在单个程序内准备好的对象的数目受可用内存的限制。这些包括在 PREPARE 语
句(statement_id 或 statement_id_var)中声明的语句标识符,以及声明了的游
标。要避免超限,请使用 FREE 语句来释放一些语句或游标。
在 SPL 例程中,准备好的对象可包括不超过一 SQL 语句的文本,那语句必须或
为 EXECUTE FUNCTION、EXECUTE PROCEDURE,或为 SELECT 语句,但
SELECT 语句不可包括 INTO variable、INTO TEMP 或 FOR UPDATE 子句。
在 SPL 例程中指定语句文本的表达式必须计算为 CHAR、LVARCHAR、
NCHAR、NVARCHAR 或 VARCHAR 数据类型。您必须显式地强制转型为这些
任何其他文本数据类型的表达式类型,诸如 UDT。
要了解在 ESQL/C 例程中对字符串中的 SQL 语句的限制,请参阅 在单一语句
准备中受限的语句 和 在多语句准备好的对象中的受限语句。
声明语句标识符
PREPARE 将语句文本发送到数据库服务器,数据库服务器分析该语句文本。如
果文本不含语法错误,则数据库服务器将其翻译为内部形式。为了以后执行,将
此翻译了的语句保存在 PREPARE 语句分配的数据结构中。该结构的名称是在
PREPARE 语句中赋给该语句标识符的值。后续的 SQL 语句可通过使用与在
PREPARE 语句中使用的相同的标识符来引用该结构。
后续的 FREE 语句释放分配给了该语句的数据库服务器资源。在您以 FREE 释
放这些资源之后,您不可在 DELCARE 语句或(在 ESQL/C 中)以 EXECUTE
语句使用该语句标识符,直到您再次准备该语句为止。
当例程退出时,自动地释放 SPL 例程为准备好的对象定义的数据库服务器资源。
语句标识符的作用域
ESQL/C 程序可由一个或多个源代码文件构成。缺省情况下,对程序而言,语句
标识符的引用的作用域是全局的。因此,在一个文件中准备的语句标识符可从另
一文件引用。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 768
在多文件程序中,如果您想要将语句标识符的引用的作用域限制到其被准备的文
件中, 则以 -local 命令行选项预先处理所有文件。
释放语句标识符
语句标识符一次仅可表示一个 SQL 语句或(在 ESQL/C 中)一个以分号分隔的
SQL 语句的列表。新的 PREPARE 语句可指定现有的语句标识符,如果您想要
将该标识符绑定到不同的 SQL 语句文本的话。
PREPARE 语句支持动态的语句标识符名称,允许您来准备语句标识符作为标识
符,或(在 ESQL/C 中)作为包含字符串的数据类型的主变量。下列的第一个示
例显示被指定作为主变量的语句标识符。第二个示例指定语句标识符作为字符
串。
stcopy ("query2", stmtid);
EXEC SQL prepare :stmtid from 'select * from customer';

EXEC SQL prepare query2 from 'select * from customer';
该变量必须为字符数据类型。在 C 中,它必须被声明为 char。
在 SPL 例程中,在本地作用域中自动地定义 PREPARE 语句声明的语句标识
符。请不要尝试将语句标识符声明为有本地的或全局的作用域。对于同一会话调
用的任何其他 SPL 例程,在一个 SPL 例程中定义的语句标识符都是不可见的。
SPL 语句标识符与 SPL 变量和游标名称分享同一命名空间。
语句文本
可在 PREPARE 语句中指定语句文本

作为引用的字符串

或作为存储在 ESQL/C 程序变量中的文本

或(在 SPL 例程中)作为字符表达式。
下列限制适用于语句文本:

文本仅可包含 SQL 语句。它不可包含来自主编程语言的语句或注释。

文本可包含前面有双连字号(--),或括在大括号({ })中或括在 C 风
格的斜杠和星号(/* */)定界符中的注释。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 769
这些符号引入或括起 SQL 注释。要获取更多关于 SQL 注释符号的信
息,请参阅 如何输入 SQL 注释。

文本可包含或单一的 SQL 语句,或(在 ESQL/C 例程中)一系列由分
号(;)分隔的语句。
要了解不可准备的 SQL 语句的列表,请参阅 在单一语句准备中受限的
语句。要了解更多关于如何准备多 SQL 语句的信息,请参阅 准备多个
SQL 语句。

文本不可包括嵌入的 SQL 语句前缀或结束符,诸如美元符号($)或词
语 EXEC SQL。

不像在准备好的文本中那样识别主语言变量。
因此,您不可准备包括 INTO 子句的 SELECT(或 EXECUTE
FUNCTION 或 EXECUTE PROCEDURE)语句,因为 INTO 子句需要
主语言变量。

您仅可使用的标识符是在数据库中定义的那些名称,诸如表和列的名称。
要获取更多关于如何在语句文本中使用标识符的信息,请参阅 以 SQL
标识符准备语句。

请使用问号(?)作为占位符来表示当语句执行时提供数据的位置,如在
此 GBase 8s ESQL/C 示例中:
EXEC SQL prepare new_cust from
'insert into customer(fname,lname) values(?,?)';
要获取更多关于如何使用问号作为占位符的信息,请参阅 准备接收参数的语句。
如果准备好的语句包含“集合派生的表”段或 GBase 8s ESQL/C 集合变量,则在您
可为该 PREPARE 语句组装文本方面有一些附加的限制。要获取关于动态的
SQL 的信息,请参阅 GBase 8s ESQL/C 程序员手册。SPL 例程不可使用动态的
SQL 语句来处理包含“集合派生的表”段的准备好的语句。
在 SPL 例程中的 PREPARE 语句的示例
GBase 8s SPL 语言支持单一语句的准备好的对象。
例如,下列 SQL 和 SPL 语句执行这些任务:
1.
创建 cities 表。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 770
2.
以四行数据填入 cities 表。
3.
创建定义准备好的语句和游标来查询 cities 的 order_city SPL 例程:
CREATE TABLE cities -- defines a table
(
id INT,
city_name CHAR(50)
);

INSERT INTO cities VALUES (1, 'Chicago');
INSERT INTO cities VALUES (2, 'New York');
INSERT INTO cities VALUES (3, 'San Francisco');
INSERT INTO cities VALUES (4, 'Atlanta');

UPDATE STATISTICS HIGH;

CREATE PROCEDURE order_city() -- defines a UDR
RETURNING INT, CHAR(50);
DEFINE c_num INT;
DEFINE c_name CHAR(50);
DEFINE c_query VARCHAR(250);
LET c_query =
"SELECT id, city_name FROM cities ORDER BY city_name;";

PREPARE c_stmt FROM c_query;
DECLARE c_cur CURSOR FOR c_stmt;

OPEN c_cur ;
while (1 = 1)
FETCH c_cur INTO c_num, c_name;
IF (SQLCODE != 100) THEN
RETURN c_num, c_name WITH RESUME;
ELSE
EXIT;
END IF
END WHILE

CLOSE c_cur;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 771
FREE c_cur;
FREE c_stmt;

END PROCEDURE;
下列 SQL 语句调用 order_city 例程:
EXECUTE PROCEDURE order_city();
如果从 dbaccess 实用程序调用 order_city 函数,则显示此输出:
(expression) (expression)
4 Atlanta
1 Chicago
2 New York
3 San Francisco
准备并执行用户定义的例程
准备用户定义的例程(UDR)的方式依赖于该 UDR 是用户定义的过程还是用户
定义的函数:

要准备用户定义的过程,请准备执行该过程的 EXECUTE PROCEDURE
语句。

要执行用户准备的过程,请使用 EXECUTE 语句。

要准备用户定义的函数,请准备执行该函数的 EXECUTE FUNCTION
(或 EXECUTE PROCEDURE)语句。
您不可在 PREPARE 语句中包括 EXECUTE FUNCTION(或 EXECUTE
PROCEDURE)的 INTO 子句。
如何执行准备好的用户定义的函数,依赖于它是仅返回一组值还是多组值。对于
仅返回一组值的用户定义的函数,请使用 EXECUTE 语句。
要执行返回多于一组返回值的用户定义的函数,您必须将该 EXECUTE
FUNCTION(或 EXECUTE PROCEDURE)语句与一游标相关联。
在单一语句准备中受限的语句
通常,您可准备任何数据操作语言(DML)语句。
在 GBase 8s 中,您可准备任何单一的 SQL 语句,除下列语句之外:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 772

ALLOCATE COLLECTION

ALLOCATE DESCRIPTOR

ALLOCATE ROW

CLOSE

CONNECT

CREATE FUNCTION FROM

CREATE PROCEDURE FROM

CREATE ROUTINE FROM

DEALLOCATE COLLECTION

DEALLOCATE DESCRIPTOR

DEALLOCATE ROW

DECLARE

DESCRIBE

DISCONNECT

EXECUTE

EXECUTE IMMEDIATE

FETCH

FLUSH

FREE

GET DESCRIPTOR

GET DIAGNOSTICS

INFO

LOAD

OPEN

OUTPUT

PREPARE

PUT

SET AUTOFREE

SET CONNECTION

SET DEFERRED_PREPARE

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 773

SET DESCRIPTOR

UNLOAD

WHENEVER
您可准备 SELECT 语句。如果 SELECT 包括 INTO TEMP 子句,则 ESQL/C
程序可执行随同 EXECUTE 语句的准备好的语句。如果它不包括 INTO TEMP
子句,则该语句返回数据行。请使用 DECLARE、OPEN 和 FETCH 游标语句来
存取行。
在 ESQL/C 中,准备好的 SELECT 语句可包括 FOR 子句。随同 DECLARE 语句使
用此子句来创建一更新游标。下一示例展示在 GBase 8s ESQL/C 中带有 FOR
UPDATE 子句的 SELECT 语句:
sprintf(up_query, "%s %s %s",
"select * from customer ",
"where customer_num between ? and ? ",
"for update");
EXEC SQL prepare up_sel from :up_query;
EXEC SQL declare up_curs cursor for up_sel;
EXEC SQL open up_curs using :low_cust,:high_cust;
在参数已知时准备语句
在一些准备好的语句中,在准备语句时所有必需的信息都已知。下列在 GBase 8s
ESQL/C 中的示例展示从常量数据准备了的两个语句:
sprintf(redo_st, "%s %s",
"drop table workt1; ",
"create table workt1 (wtk serial, wtv float)" );
EXEC SQL prepare redotab from :redo_st;
准备接收参数的语句
在一些语句中,在准备语句时参数还未知,因为每次执行该语句时可插入不同的
值。在这些语句中,在当执行语句时必须提供参数的地方,您可使用问号(?)占
位符。
下列 GBase 8s ESQL/C 示例中的 PREPARE 语句展示问号(?)占位符的一些使
用:
EXEC SQL prepare s3 from

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 774
'select * from customer where state matches ?';
EXEC SQL prepare in1 from 'insert into manufact values (?,?,?)';
sprintf(up_query, "%s %s",
"update customer set zipcode = ?"
"where current of zip_cursor");
EXEC SQL prepare update2 from :up_query;
EXEC SQL prepare exfunc from
'execute function func1 (?, ?)';
对于表达式,但不对于 SQL 标识符,您可使用占位符来延缓计算值,直到运行
时为止,除了在 以 SQL 标识符准备语句 中注明之外。
下列 GBase 8s ESQL/C 代码片段的示例从名为 demoquery 的变量准备语句。变
量中的文本包括一问号(?)占位符。该准备好的语句与一游标相关联,且当打开
该游标时,OPEN 语句的 USING 子句为该占位符提供值:
EXEC SQL BEGIN DECLARE SECTION;
char queryvalue [6];
char demoquery [80];
EXEC SQL END DECLARE SECTION;

EXEC SQL connect to 'stores_demo';
sprintf(demoquery, "%s %s",
"select fname, lname from customer ",
"where lname > ? ");
EXEC SQL prepare quid from :demoquery;
EXEC SQL declare democursor cursor for quid;
stcopy("C", queryvalue);
EXEC SQL open democursor using :queryvalue;
在与游标以及 EXECUTE 语句(所有其他的准备好的语句)关联的两个 OPEN
语句中,USING 子句都可用。
您可使用问号(?)占位符来表示 GBase 8s ESQL/C 或 SPL 集合变量的名称。
以 SQL 标识符准备语句
通常,当准备语句时,您必须在语句文本中显式地指定 SQL 标识符。在少数特
殊情况下,您可为 SQL 标识符使用问号(?)占位符:

对于 DATABASE 语句中的数据库名称。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 775

对于 CREATE DATABASE 语句的 IN dbspace 子句中的 dbspace 名
称。

对于使用游标名称的语句中的游标名称。
从用户输入获取 SQL 标识符
如果准备好的语句需要标识符,但在您编写准备好的语句时该标识符未知,则您
可构造从用户输入接收 SQL 标识符的语句。
下列 GBase 8s ESQL/C 示例提示用户输入表的名称,并在 SELECT 语句中使用
该名称。由于此名称在运行时之前未知,因此该表列的数目和数据类型也未知。
因此,程序不可提前分配主变量来接收每一行的数据。取而代之的是,此程序片
断描述语句到一 sqlda 描述符内并以该描述符访存每一行。该访存将每一行放入
程序动态地提供的内存位置内。
如果程序检索活动集合中的所有行,则 FETCH 将置于被访存的每一行的循环中。
如果 FETCH 语句检索超过一个数据值(列),则在 FETCH 之后存在另一循环,
对每一数据值执行一些活动:
#include
EXEC SQL include sqlda;
EXEC SQL include sqltypes;
char *malloc( );

main()
{
struct sqlda *demodesc;
char tablename[19];
int i;
EXEC SQL BEGIN DECLARE SECTION;
char demoselect[200];
EXEC SQL END DECLARE SECTION;

/* 该程序选择给定的 tablename 的所有列。
交互地提供该 tablename。 */

EXEC SQL connect to 'stores_demo';
printf( "This program does a select * on a table\n" );
printf( "Enter table name: " );

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 776
scanf( "%s", tablename );
sprintf(demoselect, "select * from %s", tablename );

EXEC SQL prepare iid from :demoselect;
EXEC SQL describe iid into demodesc;

/* 打印描述返回的内容 */

for ( i = 0; i < demodesc->sqld; i++ )
prsqlda (demodesc->sqlvar + i);
/* 指定数据指针。 */

for ( i = 0; i < demodesc->sqld; i++ )
{
switch (demodesc->sqlvar[i].sqltype & SQLTYPE)
{
case SQLCHAR:
demodesc->sqlvar[i].sqltype = CCHARTYPE;
/* 为空结束符制造空间 */
demodesc->sqlvar[i].sqllen++;
demodesc->sqlvar[i].sqldata =
malloc( demodesc->sqlvar[i].sqllen );
break;

case SQLSMINT: /* 失败 */
case SQLINT: /* 失败 */
case SQLSERIAL:
demodesc->sqlvar[i].sqltype = CINTTYPE;
demodesc->sqlvar[i].sqldata =
malloc( sizeof( int ) );
break;
/* 对每一类型亦然。 */
}
}

/* 为选择声明和打开游标。 */
EXEC SQL declare d_curs cursor for iid;
EXEC SQL open d_curs;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 777

/* 每次将被选择的行访存到 demodesc 内。 */
for( ; ; )
{
printf( "\n" );
EXEC SQL fetch d_curs using descriptor demodesc;
if ( sqlca.sqlcode != 0 )
break;
for ( i = 0; i < demodesc->sqld; i++ )
{
switch (demodesc->sqlvar[i].sqltype)
{
case CCHARTYPE:
printf( "%s: \"%s\n", demodesc->sqlvar[i].sqlname,
demodesc->sqlvar[i].sqldata );
break;
case CINTTYPE:
printf( "%s: %d\n", demodesc->sqlvar[i].sqlname,
*((int *) demodesc->sqlvar[i].sqldata) );
break;
/* 对每一类型亦然…… */
}
}
}
EXEC SQL close d_curs;
EXEC SQL free d_curs;
/* 释放数据内存。 */

for ( i = 0; i < demodesc->sqld; i++ )
free( demodesc->sqlvar[i].sqldata );
free( demodesc );

printf ("Program Over.\n");
}

prsqlda(sp)
struct sqlvar_struct *sp;


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 778
{
printf ("type = %d\n", sp->sqltype);
printf ("len = %d\n", sp->sqllen);
printf ("data = %lx\n", sp->sqldata);
printf ("ind = %lx\n", sp->sqlind);
printf ("name = %s\n", sp->sqlname);
}
准备多个 SQL 语句
在 ESQL/C 中,您可执行几个 SQL 语句作为一个活动,如果您将它们包括在同
一 PREPARE 语句中。将多语句文本作为一个单元处理;不是顺序地处理这些活
动。因此,多语句文本不可包括那些依赖于该文本中先前的语句中发生的活动的
语句。例如,您不可创建表并将值插入到同一准备好的语句块中的那个表内。
如果多语句准备中的一个语句返回错误,则停止执行这个准备好的语句。数据库
服务器不执行任何余下的语句。在多数情况下,编译的产品返回关于错误的错误
状态信息,但不指出文本中的哪一语句导致错误。您可使用 sqlca 中的
sqlca.sqlerrd[4] 字段来发现错误的偏移量。
在多语句准备中,如果在下列语句中从 WHERE 子句未返回行,则数据库服务器返
回 SQLNOTFOUND (100):

UPDATE … WHERE …

SELECT INTO TEMP … WHERE …

INSERT INTO … WHERE …

DELETE FROM … WHERE …
在下一示例中,四个 SQL 语句被准备到称为 query 的单一 GBase 8s ESQL/C
字符串内。以分号分隔单独的语句。
单个 PREPARE 语句可准备该四个语句执行,且单个 EXECUTE 语句可执行与 qid
语句标识符相关联的语句:
sprintf (query, "%s %s %s %s %s %s %s",
"update account set balance = balance + ? ",
"where acct_number = ?;",
"update teller set balance = balance + ? ",
"where teller_number = ?;",
"update branch set balance = balance + ? ",

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 779
"where branch_number = ?;",
"insert into history values (?, ?);";
EXEC SQL prepare qid from :query;

EXEC SQL begin work;
EXEC SQL execute qid using
:delta, :acct_number, :delta, :teller_number,
:delta, :branch_number, :timestamp, :values;
EXEC SQL commit work;
此处需要分号(;)作为在 query 持有的文本中每一 SQL 语句之间的 SQL 语句
结束符号。
在多语句准备好的对象中的受限语句
除了在 在单一语句准备中受限的语句 中罗列的作为例外的语句,您不可在多语
句的准备好的对象的文本中使用下列语句:

CLOSE DATABASE

CREATE DATABASE

DATABASE

DROP DATABASE

RENAME DATABASE

SELECT(随同一个例外)
在多语句准备中,下列语句的类型也是无效的:

在执行多语句序列期间可导致当前数据库关闭的语句

包括对 TEXT 或 BYTE 主变量引用的语句
通常,您在多语句准备中不可使用 SELECT 语句。唯一在多语句准备中被允许的
SELECT 语句的形式为带有 INTO 临时表子句的 SELECT 语句。
为了效率而使用准备好的语句
要提高执行效率,您可在循环中使用 PREPARE 语句和 EXECUTE 语句,来消
除冗余解析和优化所引起的开销。例如,每次循环运行时,都解析位于 WHILE
循环内的 UPDATE 语句。如果您在该循环之外准备 UPDATE 语句,则仅解析

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 780
该语句一次,消除开销并提高了语句执行的速度。下列示例展示如何准备一
GBase 8s ESQL/C 语句来提高性能:
EXEC SQL BEGIN DECLARE SECTION;
char disc_up[80];
int cust_num;
EXEC SQL END DECLARE SECTION;
main()
{
sprintf(disc_up, "%s %s","update customer ",
"set discount = 0.1 where customer_num = ?");
EXEC SQL prepare up1 from :disc_up;
while (1)
{
printf("Enter customer number (or 0 to quit): ");
scanf("%d", cust_num);
if (cust_num == 0)
break;
EXEC SQL execute up1 using :cust_num;
}
}
如同 SQL 语句高速缓存一样,准备好的语句可降低重新优化同一查询计划的频
度,从而节约在一些上下文中的资源。准备好的语句和语句高速缓存 部分讨论综
合地使用准备好的 DML 语句、游标和 SQL 语句高速缓存或提升查询性能的替
代技术。
对在准备好的对象中引用的表的 DDL 操作
各种 DDL 语句可删除、重命名或更改准备好的对象引用的表的模式,但后续的
执行该准备好的对象的尝试可能失败并报错误 -710,或可能导致预料不到的结
果。
然而,当为直接地引用表的准备好的对象和例程启用自动的重新编译时,ALTER
TABLE、CREATE INDEX 或 DROP INDEX 操作已更改了这些表,如果添加或
删除索引,则这些限制不是必然适用的。这是 GBase 8s 的缺省行为。在更改表
的模式之后,使用 SET ENVIRONMENT IFX_AUTO_REPREPARE 语句来启用或
禁用自动的重新编译,且即使当启用自动的重新编译时,数据库服务器发出错误

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 781
-710 的地方的上下文。要获得更多关于这方面的信息,请参阅
IFX_AUTO_REPREPARE 环境选项。
然而,当 AUTO_REPREPARE 配置参数和 IFX_AUTO_REPREPARE 会话环境
变量设置为禁用自动的重新编译时,将索引添加到准备好的语句间接地应用的
表,可类似地导致准备好的语句无效。如果游标引用无效的准备好的语句,则即
使 OPEN 语句包括 WITH REOPTIMIZATION 关键字,后续的 OPEN 语句也失
败。在禁用自动的重新编译时,如果在间接地引用的表上添加索引,则您必须再
次准备该语句并再次声明游标。如果游标是基于不再有效的准备好的语句,则您
不可简单地重新打开游标。
相关的语句
相关的语句:CLOSE 子句、DECLARE 语句、DESCRIBE 语句、EXECUTE 语
句、FREE 语句、OPEN 语句、SET AUTOFREE 语句 和 SET
DEFERRED_PREPARE 语句
要获取关于与 PREPARE 语句相关的基本概念的信息,请参阅 GBase 8s SQL 教
程指南。
要获取更多与 PREPARE 语句相关的高级概念的信息,请参阅 GBase 8s ESQL/C
程序员手册。

功能
该参数为布尔型变量,用于指定是否启用HDFS 单点登录功能。
参数取值含义说明

默认值为1 或ON,表示启用HDFS 单点登录。
表6- 86 参数值范围说明表
默认值
最小值
最大值
1
0
1

GBase 8a MPP Cluster 产品手册
6 附录
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1593

要确定需要多少磁盘空间,请遵循以下步骤:
1. 计算需要多少根数据库空间。
2. 估计要分配给所有数据库服务器数据库的总磁盘空间量,包括用于开销和增长的
空间。
以下主题说明了这些步骤。
根数据库空间的大小
可以计算根数据库空间的大小,此空间存储了描述数据库服务器的信息。
要计算根数据库空间的大小,请考虑下列存储结构:

物理日志(最小 200 KB)

逻辑日志文件(最小 200 KB)

临时表

数据

系统数据库(sysmaster、sysutils、syscdr、sysuuid)以及系统目录(大小随版本
的不同而变化)

保留页 (~24 KB)

表空间 tblspace(最小 100 到 200 KB)

额外空间

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 177 -
此估计值是初始化数据库服务器之前根数据库空间的大小。根数据库空间的大小取决于您
是计划在根数据库空间还是在其他数据库空间中存储物理日志、逻辑日志和临时表。根数
据库空间必须足够大以便在磁盘初始化期间进行最小大小配置。
建议: 使用小日志大小(例如,三个 1000 KB 的日志文件或总日志大小为 3000 KB)设置系统。在设
置完成后,请创建新的数据库空间、移动逻辑日志文件并调整其大小、删除根数据库空间中的原始日
志。然后将物理日志移至另一个数据库空间。此过程可最大限度降低日志在根数据库空间中的影响,原
因是:

移动这些日志后,根数据库空间中不会有大量空间保留不用。

日志不会与根数据库空间在相同磁盘上争用空间和 I/O。
有关如何移动日志的详细信息,请参阅将逻辑日志文件移至另一个数据库空间和更改物理
日志的位置和大小。
如果在服务器已初始化后,需要将根数据库空间设置得更大,可以向根数据库空间添加新
块。此外,可以通过使用自动空间管理来扩展根数据库空间中的块。
物理日志和逻辑日志
存储在 ONCONFIG 参数 PHYSFILE 中的值定义了在最初创建数据库服务器时物理日志
的大小。在使用 oninit -i 命令初始化磁盘空间并使数据库服务器进入联机方式后,请使用
onparams 实用程序更改物理日志的位置和大小。有关估算物理日志的建议包含在物理日
志的大小和位置中。
要计算逻辑日志文件的大小,请将 ONCONFIG 参数 LOGSIZE 的值乘以逻辑日志文件
数。有关估算逻辑日志的建议,请参阅估计日志文件的大小和数量。
临时表
分析最终用户应用程序以估计数据库服务器可能要求临时表具备的磁盘空间量。尝试估计
这些语句中有多少将会并发运行。已返还的行和列所占据的空间将提供估计所需的空间量
的良好基础。
数据库服务器在热复原期间创建的最大的临时表与逻辑日志的大小相等。您可以通过增加
所有逻辑日志文件的大小来计算逻辑日志的大小。
您还必须分析最终用户应用程序以估计数据库服务器可能需要用于显式临时表的磁盘空间
量。
关键数据
限制: 不要将数据库和表存储在根数据库空间中。为包含关键数据(如物理日志和逻辑日志)的根数据
库空间和其他数据库空间建立镜像。估计需要为存储在根数据库空间中的表分配的磁盘空间量(如果
有)。
额外空间
允许系统数据库的根数据库空间中的额外空间增长以便获得扩展保留页和充足的可用空
间。扩展保留页数取决于数据库服务器中的主要块、镜像块、逻辑日志文件和存储空间的
数目。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 178 -

数据库所需空间量
数据库服务器数据存储需要的附加磁盘空间量取决于用户的需求,以及开销和增长。用户
运行的每个应用程序都有不同的存储需要。 以下列表提出了一些您可以用来计算要分配
的磁盘空间(根数据库空间除外)量的步骤:

决定必须存储多少数据库和表。计算每个数据库和表所需的空间量。

计算每个表的增长率并为每个表指定一些磁盘空间量以适应增长。

决定希望监视哪些数据库和表。