返回首页

gbase数据、南大通用产品文档:GBase8a

更新日期:2024年09月11日

GetFloat 方法 (String)
根据给定的列名称,获取指定列的单精度浮点数值类型。

语法
[Visual Basic]
Public Function GetFloat ( _

column As String _

GBase 8a 程序员手册ADO.NET 篇


- 228 -

南大通用数据技术股份有限公司
) As Single
[C#]
public float GetFloat(

string column
)

参数
1) column :列名称

功能描述
SELECT 用于从表或视图中取出数据。
SELECT 语句就像叠加在数据库表上的过滤器,利用SQL 关键字从数据表中过滤出用
户需要的数据。
注意事项
必须对每个在SELECT 命令中使用的字段有SELECT 权限。
使用FOR UPDATE,FOR NO KEY UPDATE,FOR SHARE 或FOR KEY SHARE 还要
求UPDATE 权限。
语法格式

查询数据
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [/*+ plan_hint */] [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
{ * | {expression [ [ AS ] output_name ]} [, ...] }
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ [ START WITH condition ] CONNECT BY [NOCYCLE] condition [ ORDER SIBLINGS BY
expression ] ]
[ GROUP BY grouping_element [, ...] ]
[ HAVING condition [, ...] ]
[ WINDOW {window_name AS ( window_definition )} [, ...] ]
[ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] select ]
[ ORDER BY {expression [ [ ASC | DESC | USING operator ] |
nlssort_expression_clause ] [ NULLS { FIRST | LAST } ]} [, ...] ]
[ LIMIT { [offset,] count | ALL } ]
[ OFFSET start [ ROW | ROWS ] ]
[ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
[ {FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ]
[ NOWAIT | WAIT N ]} [...] ];

condition 和expression 中可以使用targetlist 中表达式的别名。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1229

只能同一层引用。

只能引用targetlist 中的别名。

只能是后面的表达式引用前面的表达式。

不能包含volatile 函数。

不能包含Window function 函数。

不支持在join on 条件中引用别名。

targetlist 中有多个要应用的别名则报错。
其中子查询with_query 为:
with_query_name [ ( column_name [, ...] ) ]
AS [ [ NOT ] MATERIALIZED ] ( {select | values | insert | update | delete} )
其中指定查询源from_item 为:
{[ ONLY ] table_name [ * ] [ partition_clause ] [ [ AS ] alias [ ( column_alias
[, ...] ) ] ]
[ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ]
[TIMECAPSULE {TIMESTAMP|CSN} expression]
|( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
|with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
|function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] |
column_definition [, ...] ) ]
|function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
|from_item [ NATURAL ] join_type from_item [ ON join_condition | USING
( join_column [, ...] ) ]}
其中group 子句为:
( )
| expression
| ( expression [, ...] )
| ROLLUP ( { expression | ( expression [, ...] ) } [, ...] )
| CUBE ( { expression | ( expression [, ...] ) } [, ...] )
| GROUPING SETS ( grouping_element [, ...] )
其中指定分区partition_clause 为:
PARTITION { ( partition_name ) | FOR (
partition_value [, ...] ) }

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1230
SUBPARTITION { ( subpartition_name ) | FOR (
subpartition_value [, ...] )}

指定分区只适合普通表。
其中设置排序方式nlssort_expression_clause 为:
NLSSORT ( column_name, ' NLS_SORT = { SCHINESE_PINYIN_M | generic_m_ci } ' )
其中,第二个参数可选generic_m_ci,仅支持纯英文不区分大小写排序。

简化版查询语法,功能相当于select * from table_name。
TABLE { ONLY {(table_name)| table_name} | table_name [ * ]};
参数说明

WITH [ RECURSIVE ] with_query [, …]
用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。
如果声明了RECURSIVE,那么允许SELECT 子查询通过名称引用它自己。
其中with_query 的详细格式为:with_query_name [ ( column_name [, …] ) ] AS( {select |
values | insert | update | delete} )
with_query_name 指定子查询生成的结果集名称,在查询中可使用该名称访问子查询的
结果集。
column_name 指定子查询结果集中显示的列名。
每个子查询可以是SELECT、VALUES、INSERT、UPDATE 或DELETE 语句。

plan_hint 子句
以/*+ */的形式在SELECT 关键字后,
用于对SELECT 对应的语句块生成的计划进行hint
调优,详细用法请参见章节使用Plan Hint 进行调优。每条语句中只有第一个/*+ plan_hint */
注释块会作为hint 生效,里面可以写多条hint。

ALL
声明返回所有符合条件的行,是默认行为,可以省略该关键字。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1231

DISTINCT [ ON ( expression [, …] ) ]
从SELECT 的结果集中删除所有重复的行,使结果集中的每行都是唯一的。
ON ( expression [, …] ) 只保留那些在给出的表达式上运算出相同结果的行集合中的第
一行。

DISTINCT ON 表达式是使用与ORDER BY 相同的规则进行解释的。除非使用了
ORDER BY 来保证需要的行首先出现,否则,
“第一行” 是不可预测的。

SELECT 列表
指定查询表中列名,可以是部分列或者是全部(使用通配符*表示)。
通过使用子句AS output_name 可以为输出字段取个别名,这个别名通常用于输出字段
的显示。支持关键字name、value 和type 作为列别名。
列名可以用下面几种形式表达:
手动输入列名,多个列之间用英文逗号(,)分隔。
可以是FROM 子句里面计算出来的字段。

FROM 子句
为SELECT 声明一个或者多个源表。
FROM 子句涉及的元素如下所示。

table_name
表名或视图名,名称前可加上模式名,如:schema_name.table_name。

alias
给表或复杂的表引用起一个临时的表别名,以便被其余的查询引用。
别名用于缩写或者在自连接中消除歧义。
如果提供了别名,
它就会完全隐藏表的实际名
称。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1232

TABLESAMPLE sampling_method ( argument [, …] ) [ REPEATABLE ( seed ) ]
_table_name_之后的TABLESAMPLE 子句表示应该用指定的_sampling_method_来检索
表中行的子集。
可选的REPEATABLE 子句指定一个用于产生采样方法中随机数的_种子_数。
种子值可
以是任何非空常量值。如果查询时表没有被更改,指定相同种子和_argument_值的两个查询
将会选择该表相同的采样。但是不同的种子值通常将会产生不同的采样。如果没有给出
REPEATABLE,则会基于一个系统产生的种子为每一个查询选择一个新的随机采样。

TIMECAPSULE { TIMESTAMP | CSN } expression
查询指定CSN 点或者指定时间点表的内容。
目前不支持闪回查询的表:系统表、列存表、内存表、DFS 表、全局临时表、本地临
时表、UNLOGGED 表、分区表、视图、序列表、Hbkt 表、共享表、继承表、带有PARTIAL
CLUSTER KEY 约束的表。

TIMECAPSULE TIMESTAMP
关键字,闪回查询的标识,根据date 日期,闪回查找指定时间点的结果集。date 日期
必须是一个过去有效的时间戳。

TIMECAPSULE CSN
关键字,闪回查询的标识,根据表的CSN 闪回查询指定CSN 点的结果集。其中CSN
可从gs_txn_snapshot 记录的snpcsn 号查得。
说明:

闪回查询不能跨越影响表结构或物理存储的语句,
否则会报错。
即闪回点和当前点
之间,如果执行过修改表结构或影响物理存储的语句(DDL、DCL、VACUUM
FULL)
,则闪回失败,报错:ERROR: The table definition of T1 has been changed。
闪回点过旧时,
因闪回版本被回收等导致无法获取旧版本会导致闪回失败,
报错:
Restore
point too old。可通过将version_retention_age 和vacuum_defer_cleanup_age 设置成同值,配

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1233
置闪回功能旧版本保留期限,取值范围是0~1000000,值为0 表示VACUUM 不会延迟清除
无效的行存记录。
通过时间方式指定闪回点,闪回数据和实际时间点最多偏差为3 秒。

column_alias
列别名。

PARTITION
查询分区表的某个分区的数据。

partition_name
分区名。

partition_value
指定的分区键值。
在创建分区表时,
如果指定了多个分区键,
可以通过PARTITION FOR
子句指定的这一组分区键的值,唯一确定一个分区。

subquery
FROM 子句中可以出现子查询,创建一个临时表保存子查询的输出。

with_query_name
WITH 子句同样可以作为FROM 子句的源,
可以通过WITH 查询的名称对其进行引用。

function_name
函数名称。函数调用也可以出现在FROM 子句中。

join_type
有5 种类型,如下所示。

[ INNER ] JOIN
一个JOIN 子句组合两个FROM 项。
可使用圆括弧以决定嵌套的顺序。
如果没有圆括弧,
JOIN 从左向右嵌套。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1234
在任何情况下,JOIN 都比逗号分隔的FROM 项绑定得更紧。

LEFT [ OUTER ] JOIN
返回笛卡尔积中所有符合连接条件的行,
再加上左表中通过连接条件没有匹配到右表行
的那些行。这样,
左边的行将扩展为生成表的全长,方法是在那些右表对应的字段位置填上
NULL。请注意,只在计算匹配的时候,才使用JOIN 子句的条件,外层的条件是在计算完
毕之后施加的。

RIGHT [ OUTER ] JOIN
返回所有内连接的结果行,加上每个不匹配的右边行(左边用NULL 扩展)。
这只是一个符号上的方便,因为总是可以把它转换成一个LEFT OUTER JOIN,只要把
左边和右边的输入互换位置即可。

FULL [ OUTER ] JOIN
返回所有内连接的结果行,加上每个不匹配的左边行(右边用NULL 扩展),再加上
每个不匹配的右边行(左边用NULL 扩展)。

CROSS JOIN
CROSS JOIN 等效于INNER JOIN ON(TRUE),即没有被条件删除的行。这种连接
类型只是符号上的方便,因为它们与简单的FROM 和WHERE 的效果相同。

必须为INNER 和OUTER 连接类型声明一个连接条件,即NATURAL ON、
join_condition、USING (join_column [,…]) 之一。但是它们不能出现在CROSS
JOIN 中。
其中CROSS JOIN 和INNER JOIN 生成一个简单的笛卡尔积,和在FROM 的顶层列出
两个项的结果相同。

ON join_condition
连接条件,用于限定连接中的哪些行是匹配的。如:ON left_table.a = right_table.a。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1235

USING(join_column[,…])
ON left_table.a = right_table.a AND left_table.b = right_table.b … 的简写。要求对应的列
必须同名。

NATURAL
NATURAL 是具有相同名称的两个表的所有列的USING 列表的简写。

from item
用于连接的查询源对象的名称。

WHERE 子句
WHERE 子句构成一个行选择表达式,
用来缩小SELECT 查询的范围。
condition 是返回
值为布尔型的任意表达式,任何不满足该条件的行都不会被检索。
WHERE 子句中可以通过指定“(+)”
操作符的方法将表的连接关系转换为外连接。
但是
不建议用户使用这种用法,因为这并不是SQL 的标准语法,在做平台迁移的时候可能面临
语法兼容性的问题。同时,使用“(+)”有很多限制:
1.
“(+)”只能出现在where 子句中。
2.
如果from 子句中已经有指定表连接关系,那么不能再在where 子句中使用“(+)”。
3.
“(+)”只能作用在表或者视图的列上,不能作用在表达式上。
4.
如果表A 和表B 有多个连接条件,
那么必须在所有的连接条件中指定
“(+)”

否则
“(+)”
将不会生效,表连接会转化成内连接,并且不给出任何提示信息。
5.
“(+)”作用的连接条件中的表不能跨查询或者子查询。如果“(+)”作用的表,不在当
前查询或者子查询的from 子句中,则会报错。如果“(+)”作用的对端的表不存在,则
不报错,同时连接关系会转化为内连接。
6.
“(+)”作用的表达式不能直接通过“OR”连接。
7.
如果“(+)”作用的列是和一个常量的比较关系,那么这个表达式会成为join 条件的一
部分。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1236
8.
同一个表不能对应多个外表。
9.
“(+)”只能出现“比较表达式”,“NOT 表达式”,“ANY 表达式”,“ALL 表达
式”,
“IN 表达式”,
“NULLIF 表达式”,
“IS DISTINCT FROM 表达式”,
“IS OF
表达式”。“(+)”不能出现在其他类型表达式中,并且这些表达式中不允许出现通过
“AND”和“OR”连接的表达式。
10. “(+)”只能转化为左外连接或者右外连接,不能转化为全连接,即不能在一个表达式
的两个表上同时指定“(+)”。

对于WHERE 子句的LIKE 操作符,当LIKE 中要查询特殊字符“%”

“_”

“\”
的时候需要使用反斜杠“\”来进行转义。

START WITH 子句
START WITH 子句通常与CONNECT BY 子句同时出现,数据进行层次递归遍历查询,
START WITH 代表递归的初始条件。若省略该子句,单独使用CONNECT BY 子句,则表
示以表中的所有行作为初始集合。

CONNECT BY 子句
CONNECT BY 代表递归连接条件,CONNECT BY 条件中可以对列指定PRIOR 关键字
代表以这列为递归键进行递归。当前约束只能对表中的列指定PRIOR,不支持对表达式、
类型转换指定PRIOR 关键字。若在递归连接条件前加NOCYCLE,则表示遇到循环记录时
停止递归。(注:含START WITH .. CONNECT BY 子句的SELECT 语句不支持使用FOR
SHARE/UPDATE 锁)。

GROUP BY 子句
将查询结果按某一列或多列的值分组,值相等的为一组。

CUBE ( { expression | ( expression [, …] ) } [, …] )
CUBE 是自动对group by 子句中列出的字段进行分组汇总,
结果集将包含维度列中各值
的所有可能组合,
以及与这些维度值组合相匹配的基础行中的聚合值。
它会为每个分组返回

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1237
一行汇总信息,用户可以使用CUBE 来产生交叉表值。比如,在CUBE 子句中给出三个表
达式(n = 3),运算结果为2n = 23 = 8 组。以n 个表达式的值分组的行称为常规行,其余
的行称为超级聚集行。

GROUPING SETS ( grouping_element [, …] )
GROUPING SETS 子句是GROUP BY 子句的进一步扩展,它可以使用户指定多个
GROUP BY 选项。这样做可以通过裁剪用户不需要的数据组来提高效率。当用户指定了
所需的数据组时,数据库不需要执行完整CUBE 或ROLLUP 生成的聚合集合。

如果SELECT 列表的表达式中引用了那些没有分组的字段,则会报错,除非使用
了聚集函数,因为对于未分组的字段,可能返回多个数值。

HAVING 子句
与GROUP BY 子句配合用来选择特殊的组。
HAVING 子句将组的一些属性与一个常数
值比较,只有满足HAVING 子句中的逻辑表达式的组才会被提取出来。

WINDOW 子句
一般形式为WINDOW window_name AS ( window_definition ) [,…],
window_name 是
可以被随后的窗口定义所引用的名称,window_definition 可以是以下的形式:
[ existing\_window\_name \]
[ PARTITION BY expression \[, ...\] \]
[ ORDER BY expression \[ ASC | DESC | USING operator \] \[ NULLS \{ FIRST | LAST
\} \] \[, ...\] \]
[ frame\_clause \]
frame_clause 为窗函数定义一个窗口框架window frame,窗函数(并非所有)依赖于框
架,window frame 是当前查询行的一组相关行。frame_clause 可以是以下的形式:
[ RANGE | ROWS \] frame\_start

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1238
[ RANGE | ROWS \] BETWEEN frame\_start AND frame\_end
frame\_start 和frame\_end 可以是:
UNBOUNDED PRECEDING
value PRECEDING
CURRENT ROW
value FOLLOWING
UNBOUNDED FOLLOWING

对列存表的查询目前只支持row_number 窗口函数,不支持frame_clause。

UNION 子句
UNION 计算多个SELECT 语句返回行集合的并集。
UNION 子句有如下约束条件:
除非声明了ALL 子句,否则缺省的UNION 结果不包含重复的行。
同一个SELECT 语句中的多个UNION 操作符是从左向右计算的,
除非用圆括弧进行了
标识。
FOR UPDATE,FOR NO KEY UPDATE,FOR SHARE 和FOR KEY SHARE 不能在
UNION 的结果或输入中声明。
一般表达式:
select_statement UNION [ALL] select_statement
select_statement 可以是任何没有ORDER BY、LIMIT、FOR UPDATE,FOR NO KEY
UPDATE,FOR SHARE 或FOR KEY SHARE 子句的SELECT 语句。
如果用圆括弧包围,ORDER BY 和LIMIT 可以附着在子表达式里。

INTERSECT 子句
INTERSECT 计算多个SELECT 语句返回行集合的交集,不含重复的记录。
INTERSECT 子句有如下约束条件:

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1239
同一个SELECT 语句中的多个INTERSECT 操作符是从左向右计算的,
除非用圆括弧进
行了标识。
当对多个SELECT 语句的执行结果进行UNION 和INTERSECT 操作的时候,
会优先处
理INTERSECT。
一般形式:
select_statement INTERSECT select_statement
select_statement 可以是任何没有FOR UPDATE,
FOR NO KEY UPDATE,
FOR SHARE
或FOR KEY SHARE 子句的SELECT 语句。

EXCEPT 子句
EXCEPT 子句有如下的通用形式:
select_statement EXCEPT [ ALL ] select_statement
select_statement 是任何没有FOR UPDATE,FOR NO KEY UPDATE,FOR SHARE 或
FOR KEY SHARE 子句的SELECT 表达式。
EXCEPT 操作符计算存在于左边SELECT 语句的输出而不存在于右边SELECT 语句输
出的行。
EXCEPT 的结果不包含任何重复的行,除非声明了ALL 选项。使用ALL 时,一个在左
边表中有m 个重复而在右边表中有n 个重复的行将在结果中出现max(m-n,0) 次。
除非用圆括弧指明顺序,否则同一个SELECT 语句中的多个EXCEPT 操作符是从左向
右计算的。EXCEPT 和UNION 的绑定级别相同。
目前,不能给EXCEPT 的结果或者任何EXCEPT 的输入声明FOR UPDATE,FOR NO
KEY UPDATE,FOR SHARE 和FOR KEY SHARE 子句。

MINUS 子句
与EXCEPT 子句具有相同的功能和用法。

ORDER BY 子句

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1240
对SELECT 语句检索得到的数据进行升序或降序排序。对于ORDER BY 表达式中包含
多列的情况:
首先根据最左边的列进行排序,如果这一列的值相同,则根据下一个表达式进行比较,
依此类推。
如果对于所有声明的表达式都相同,则按随机顺序返回。
在与DISTINCT 关键字一起使用的情况下,
ORDER BY 中排序的列必须包括在SELECT
语句所检索的结果集的列中。
在与GROUP BY 子句一起使用的情况下,
ORDER BY 中排序的列必须包括在SELECT
语句所检索的结果集的列中。
在与GROUP BY 子句一起使用的情况下,
ORDER BY 中排序的列必须包括在SELECT
语句所检索的结果集的列中。

如果要支持中文拼音排序,需要在初始化数据库时指定编码格式为UTF-8、
GB18030 或GBK。命令如下:
initdb –E UTF8 –D ../data –locale=zh_CN.UTF-8、initdb -E GB18030 -D ../data
-locale=zh_CN.GB18030 或initdb –E GBK –D ../data –locale=zh_CN.GBK。

LIMIT 子句
LIMIT 子句由两个独立的子句组成:
LIMIT { count | ALL }
OFFSET start count 声明返回的最大行数,而start 声明开始返回行之前忽略的行数。如
果两个都指定了,会在开始计算count 个返回行之前先跳过start 行。

OFFSET 子句
SQL:2008 开始提出一种不同的语法:
OFFSET start { ROW | ROWS }
start 声明开始返回行之前忽略的行数。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1241

FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY
如果不指定count,
默认值为1,
FETCH 子句限定返回查询结果从第一行开始的总行数。

锁定子句
FOR UPDATE 子句将对SELECT 检索出来的行进行加锁。这样避免它们在当前事务结
束前被其他事务修改或者删除,
即其他企图UPDATE、DELETE、SELECT FOR UPDATE、
SELECT FOR NO KEY UPDATE, SELECT FOR SHARE 或SELECT FOR KEY SHARE 这
些行的事务将被阻塞,直到当前事务结束。任何在一行上的DELETE 命令也会获得FOR
UPDATE 锁模式,在非主键列上修改值的UPDATE 也会获得该锁模式。反过来,SELECT
FOR UPDATE 将等待已经在相同行上运行以上这些命令的并发事务,并且接着锁定并且返
回被更新的行(或者没有行,因为行可能已被删除)。
FOR NO KEY UPDATE 行为与FOR UPDATE 类似,
不过获得的锁较弱:
这种锁将不会
阻塞尝试在相同行上获得锁的SELECT FOR KEY SHARE 命令。任何不获取FOR UPDATE
锁的UPDATE 也会获得这种锁模式。
FOR SHARE 的行为类似,只是它在每个检索出来的行上要求一个共享锁,而不是一个
排他锁。一个共享锁阻塞其它事务执行UPDATE、DELETE、SELECT FOR UPDATE 或者
SELECT FOR NO KEY UPDATE,不阻塞SELECT FOR SHARE 或者SELECT FOR KEY
SHARE。
FOR KEY SHARE 行为与FOR SHARE 类似,不过锁较弱:SELECT FOR UPDATE 会
被阻塞,但是SELECT FOR NO KEY UPDATE 不会被阻塞。一个键共享锁会阻塞其他事务
执行修改键值的DELETE 或者UPDATE,但不会阻塞其他UPDATE,也不会阻止SELECT
FOR NO KEY UPDATE、SELECT FOR SHARE 或者SELECT FOR KEY SHARE。
为了避免操作等待其他事务提交,可使用NOWAIT 选项,如果被选择的行不能立即被
锁住,将会立即汇报一个错误,而不是等待。
如果在锁定子句中明确指定了表名称,则只有这些指定的表被锁定,其他在SELECT
中使用的表将不会被锁定。否则,将锁定该命令中所有使用的表。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1242
如果锁定子句应用于一个视图或者子查询,
它同样将锁定所有该视图或子查询中使用到
的表。
多个锁定子句可以用于为不同的表指定不同的锁定模式。
如果一个表中同时出现(或隐含同时出现)在多个子句中,则按照最强的锁处理。类似
的,如果影响一个表的任意子句中出现了NOWAIT,该表将按照NOWAIT 处理。

对列存表的查询不支持for update/share。

NLS_SORT
指定某字段按照特殊方式排序。
目前仅支持中文拼音格式排序和不区分大小写排序。

果要支持此排序方式,
在创建数据库时需要指定编码格式为
“UTF8”


GB18030”

“GBK”

如果指定为其他编码,例如SQL_ASCII,则可能报错或者排序无效。
取值范围:
SCHINESE_PINYIN_M,按照中文拼音排序。
generic_m_ci,不区分大小写排序(可选,仅支持纯英文不区分大小写排序)。

PARTITION 子句
查询某个分区表中相应分区的数据。
示例
--先通过子查询得到一张临时表temp_t,然后查询表temp_t 中的所有数据。
gbase=#WITH temp_t(name,isdba) AS (SELECT usename,usesuper FROM pg_user) SELECT
* FROM temp_t;
--查询tpcds.reason 表的所有r_reason_sk 记录,且去除重复。
gbase=#SELECT DISTINCT(r_reason_sk) FROM tpcds.reason;
--LIMIT 子句示例:获取表中一条记录。
gbase=#SELECT * FROM tpcds.reason LIMIT 1;
--查询所有记录,且按字母升序排列。
gbase=#SELECT r_reason_desc FROM tpcds.reason ORDER BY r_reason_desc;
--通过表别名,从pg_user 和pg_user_status 这两张表中获取数据。

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1243
gbase=#SELECT a.usename,b.locktime FROM pg_user a,pg_user_status b WHERE
a.usesysid=b.roloid;
--FULL JOIN 子句示例:将pg_user 和pg_user_status 这两张表的数据进行全连接显示,
即数据的合集。
gbase=#SELECT a.usename,b.locktime,a.usesuper FROM pg_user a FULL JOIN
pg_user_status b on a.usesysid=b.roloid;
--GROUP BY 子句示例:根据查询条件过滤,并对结果进行分组。
gbase=#SELECT r_reason_id, AVG(r_reason_sk) FROM tpcds.reason GROUP BY
r_reason_id HAVING AVG(r_reason_sk) > 25;
--GROUP BY CUBE 子句示例:根据查询条件过滤,并对结果进行分组汇总。
gbase=#SELECT r_reason_id,AVG(r_reason_sk) FROM tpcds.reason GROUP BY
CUBE(r_reason_id,r_reason_sk);
--GROUP BY GROUPING SETS 子句示例:根据查询条件过滤,并对结果进行分组汇总。
gbase=#SELECT r_reason_id,AVG(r_reason_sk) FROM tpcds.reason GROUP BY GROUPING
SETS((r_reason_id,r_reason_sk),r_reason_sk);
--UNION 子句示例:将表tpcds.reason 里r_reason_desc 字段中的内容以W 开头和以N
开头的进行合并。
gbase=#SELECT r_reason_sk, tpcds.reason.r_reason_desc
FROM tpcds.reason
WHERE tpcds.reason.r_reason_desc LIKE 'W%'
UNION
SELECT r_reason_sk, tpcds.reason.r_reason_desc
FROM tpcds.reason
WHERE tpcds.reason.r_reason_desc LIKE 'N%';
--NLS_SORT 子句示例:中文拼音排序。
gbase=#SELECT * FROM tpcds.reason ORDER BY NLSSORT( r_reason_desc, 'NLS_SORT =
SCHINESE_PINYIN_M');
--不区分大小写排序(可选,仅支持纯英文不区分大小写排序):
gbase=#SELECT * FROM tpcds.reason ORDER BY NLSSORT( r_reason_desc, 'NLS_SORT =
generic_m_ci');
--创建分区表tpcds.reason_p
gbase=#CREATE TABLE tpcds.reason_p
(
r_reason_sk integer,
r_reason_id character(16),
r_reason_desc character(100)
)
PARTITION BY RANGE (r_reason_sk)
(
partition P_05_BEFORE values less than (05),

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1244
partition P_15 values less than (15),
partition P_25 values less than (25),
partition P_35 values less than (35),
partition P_45_AFTER values less than (MAXVALUE)
)
;
--插入数据。
gbase=#INSERT INTO tpcds.reason_p values(3,'AAAAAAAABAAAAAAA','reason
1'),(10,'AAAAAAAABAAAAAAA','reason 2'),(4,'AAAAAAAABAAAAAAA','reason
3'),(10,'AAAAAAAABAAAAAAA','reason 4'),(10,'AAAAAAAABAAAAAAA','reason
5'),(20,'AAAAAAAACAAAAAAA','reason 6'),(30,'AAAAAAAACAAAAAAA','reason 7');
--PARTITION 子句示例:从tpcds.reason_p 的表分区P_05_BEFORE 中获取数据。
gbase=# SELECT * FROM tpcds.reason_p PARTITION (P_05_BEFORE);
r_reason_sk |
r_reason_id
|
r_reason_desc
-------------+------------------+------------------------------------
4 | AAAAAAAABAAAAAAA | reason 3
3 | AAAAAAAABAAAAAAA | reason 1
(2 rows)
--GROUP BY 子句示例:按r_reason_id 分组统计tpcds.reason_p 表中的记录数。
gbase=#SELECT COUNT(*),r_reason_id FROM tpcds.reason_p GROUP BY r_reason_id;
count |
r_reason_id
-------+------------------
2 | AAAAAAAACAAAAAAA
5 | AAAAAAAABAAAAAAA
(2 rows)
--GROUP BY CUBE 子句示例:根据查询条件过滤,并对查询结果分组汇总。
gbase=#SELECT * FROM tpcds.reason GROUP BY
CUBE
(r_reason_id,r_reason_sk,r_reason_desc);
--GROUP BY GROUPING SETS 子句示例:根据查询条件过滤,并对查询结果分组汇总。
gbase=#SELECT * FROM tpcds.reason GROUP BY
GROUPING SETS
((r_reason_id,r_reason_sk),r_reason_desc);
--HAVING 子句示例:按r_reason_id 分组统计tpcds.reason_p 表中的记录,并只显示
r_reason_id 个数大于2 的信息。
gbase=#SELECT COUNT(*) c,r_reason_id FROM tpcds.reason_p GROUP BY r_reason_id
HAVING c>2;
c |
r_reason_id

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1245
---+------------------
5 | AAAAAAAABAAAAAAA
(1 row)
--IN 子句示例:按r_reason_id 分组统计tpcds.reason_p 表中的r_reason_id 个数,并
只显示r_reason_id 值为AAAAAAAABAAAAAAA 或AAAAAAAADAAAAAAA 的个数。
gbase=#SELECT COUNT(*),r_reason_id FROM tpcds.reason_p GROUP BY r_reason_id
HAVING r_reason_id IN('AAAAAAAABAAAAAAA','AAAAAAAADAAAAAAA');
count |
r_reason_id
-------+------------------
5 | AAAAAAAABAAAAAAA
(1 row)
--INTERSECT 子句示例:查询r_reason_id 等于AAAAAAAABAAAAAAA,并且r_reason_sk
小于5 的信息。
gbase=#SELECT * FROM tpcds.reason_p WHERE r_reason_id='AAAAAAAABAAAAAAA'
INTERSECT SELECT * FROM tpcds.reason_p WHERE r_reason_sk<5;
r_reason_sk |
r_reason_id
|
r_reason_desc
-------------+------------------+------------------------------------
4 | AAAAAAAABAAAAAAA | reason 3
3 | AAAAAAAABAAAAAAA | reason 1
(2 rows)
--EXCEPT 子句示例:查询r_reason_id 等于AAAAAAAABAAAAAAA,并且去除r_reason_sk
小于4 的信息。
gbase=#SELECT * FROM tpcds.reason_p WHERE r_reason_id='AAAAAAAABAAAAAAA' EXCEPT
SELECT * FROM tpcds.reason_p WHERE r_reason_sk<4;
r_reason_sk |
r_reason_id
|
r_reason_desc
-------------+------------------+------------------------------------
10 | AAAAAAAABAAAAAAA | reason 2
10 | AAAAAAAABAAAAAAA | reason 5
10 | AAAAAAAABAAAAAAA | reason 4
4 | AAAAAAAABAAAAAAA | reason 3
(4 rows)
--通过在where 子句中指定"(+)"来实现左连接。
gbase=#select t1.sr_item_sk ,t2.c_customer_id from store_returns t1, customer t2
where t1.sr_customer_sk
= t2.c_customer_sk(+)
order by 1 desc limit 1;
sr_item_sk | c_customer_id
------------+---------------

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1246
18000 |
(1 row)
--通过在where 子句中指定"(+)"来实现右连接。
gbase=#select t1.sr_item_sk ,t2.c_customer_id from store_returns t1, customer t2
where t1.sr_customer_sk(+)
= t2.c_customer_sk
order by 1 desc limit 1;
sr_item_sk |
c_customer_id
------------+------------------
| AAAAAAAAJNGEBAAA
(1 row)
--通过在where 子句中指定"(+)"来实现左连接,并且增加连接条件。
gbase=#select t1.sr_item_sk ,t2.c_customer_id from store_returns t1, customer t2
where t1.sr_customer_sk
= t2.c_customer_sk(+) and t2.c_customer_sk(+) < 1 order
by 1
limit 1;
sr_item_sk | c_customer_id
------------+---------------
1 |
(1 row)
--不支持在where 子句中指定"(+)"的同时使用内层嵌套AND/OR 的表达式。
gbase=#select t1.sr_item_sk ,t2.c_customer_id from store_returns t1, customer t2
where not(t1.sr_customer_sk
= t2.c_customer_sk(+) and t2.c_customer_sk(+) < 1);
ERROR:
Operator "(+)" can not be used in nesting expression.
LINE 1: ...tomer_id from store_returns t1, customer t2 where not(t1.sr_...
^
--where 子句在不支持表达式宏指定"(+)"会报错。
gbase=#select t1.sr_item_sk ,t2.c_customer_id from store_returns t1, customer t2
where (t1.sr_customer_sk
= t2.c_customer_sk(+))::bool;
ERROR:
Operator "(+)" can only be used in common expression.
--where 子句在表达式的两边都指定"(+)"会报错。
gbase=#select t1.sr_item_sk ,t2.c_customer_id from store_returns t1, customer t2
where t1.sr_customer_sk(+)
= t2.c_customer_sk(+);
ERROR:
Operator "(+)" can't be specified on more than one relation in one join
condition
HINT:
"t1", "t2"...are specified Operator "(+)" in one condition.
--删除表。
gbase=#DROP TABLE tpcds.reason_p;

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1247
--闪回查询示例
--创建表tpcds.time_table
gbase=# create table tpcds.time_table(idx integer, snaptime timestamp, snapcsn
bigint, timeDesc character(100));
--向表tpcds.time_table 中插入记录
gbase=# INSERT INTO tpcds.time_table select 1, now(),int8in(xidout(next_csn)),
'time1' from gs_get_next_xid_csn();
gbase=# INSERT INTO tpcds.time_table select 2, now(),int8in(xidout(next_csn)),
'time2' from gs_get_next_xid_csn();
gbase=# INSERT INTO tpcds.time_table select 3, now(),int8in(xidout(next_csn)),
'time3' from gs_get_next_xid_csn();
gbase=# INSERT INTO tpcds.time_table select 4, now(),int8in(xidout(next_csn)),
'time4' from gs_get_next_xid_csn();
gbase=# select * from tpcds.time_table;
idx |
snaptime
| snapcsn |
timedesc
-----+----------------------------+---------+--------------------------------
----------------------------------------------------------------------
1 | 2021-04-25 17:50:05.360326 |
107322 | time1
2 | 2021-04-25 17:50:10.886848 |
107324 | time2
3 | 2021-04-25 17:50:16.12921
|
107327 | time3
4 | 2021-04-25 17:50:22.311176 |
107330 | time4
(4 rows)
gbase=# delete tpcds.time_table;
DELETE 4
gbase=# SELECT * FROM tpcds.time_table TIMECAPSULE TIMESTAMP
to_timestamp('2021-04-25 17:50:22.311176','YYYY-MM-DD HH24:MI:SS.FF');
idx |
snaptime
| snapcsn |
timedesc
-----+----------------------------+---------+--------------------------------
----------------------------------------------------------------------
1 | 2021-04-25 17:50:05.360326 |
107322 | time1
2 | 2021-04-25 17:50:10.886848 |
107324 | time2
3 | 2021-04-25 17:50:16.12921
|
107327 | time3
(3 rows)
gbase=# SELECT * FROM tpcds.time_table TIMECAPSULE CSN 107330;
idx |
snaptime
| snapcsn |
timedesc

GBase 8c SQL 参考手册
南大通用数据技术股份有限公司
1248
-----+----------------------------+---------+--------------------------------
----------------------------------------------------------------------
1 | 2021-04-25 17:50:05.360326 |
107322 | time1
2 | 2021-04-25 17:50:10.886848 |
107324 | time2
3 | 2021-04-25 17:50:16.12921
|
107327 | time3
(3 rows)

使用 FETCH 语句来将游标移到活动的集合中的新行,并从内存检索该行值。
请随同 GBase 8s ESQL/C 并随同 SPL 使用此语句。
语法

元素
描述
限制
语法
cursor_id
要检索行的游标
必须打开
标识符
cursor_id_var
存储 cursor_id 的主
变量
必须为字符数据类

特定于语


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 620
元素
描述
限制
语法
cursor_var
游标变量的名称
必须已打开
标识符
data_structure
作为主变量的结构
必须存储访存的值 特定于语

descriptor
系统描述符区域
必须已分配
引用字符

descriptor_var
存储 descriptor 的
主变量
必须已分配
特定于语

indicator_var
返回码的主变量,如
果 output_var 可为
NULL 值
请参阅 使用指示
符变量。
特定于语

output_var
访存的值的主变量
必须存储来自行的

特定于语

position_num
相对于当前行的位置
值 0 访存当前行 精确数值
position_num_var
主变量(=
position_num)
值 0 访存当前行 特定于语

row_position
活动的集合中的序数
位置
必须为大于 1 的
整数
精确数值
row_position_var
主变量(= row_
position)
必须为 1 或更大 特定于语

sqlda_pointer
指向 sqlda 结构的指

不可以 $ 开头,
也不可以 : 开头
请参阅
ESQL/C。
用法
除非另有注明,后续章节都描述在 GBase 8s ESQL/C 例程中如何使用 FETCH 语
句。要获取更多关于在 SPL 例程中 FETCH 语句的更严格语法和语义的信息,
请参阅 从 SPL 例程中的动态游标访存。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 621
数据库服务器如何创建、存储和访存活动的行集合的成员,取决于是否将游标声
明为顺序游标,或声明为滚动游标。FETCH 语句可在 SPL 例程中引用的所有游
标都是顺序游标。
在 X/Open 模式下,如果指定游标方向值(诸如 NEXT 或 RELATIVE),则发
出警告消息,指出语句不符合 X/Open 标准。
使用顺序游标的 FETCH
顺序游标仅可从活动的集合按顺序访存下一行。唯一可用的选项为缺省选项
NEXT。每次打开表时顺序游标仅可通读表一次。下列 GBase 8s ESQL/C 示例说
明使用顺序游标的 FETCH 语句:
EXEC SQL FETCH seq_curs INTO :fname, :lname;
EXEC SQL FETCH NEXT seq_curs INTO :fname, :lname;
在程序打开顺序游标时,数据库服务器处理对第一行数据的定位或构造点的查
询。数据库服务器的目标是尽可能少地占用资源。
由于顺序游标仅可检索下一行,因此数据库服务器可频繁地创建活动的集合,一
次一行。
对于每一 FETCH 操作,数据库服务器返回当前行的内容,并定位到下一行。如
果数据库服务器必须创建整个活动的集合来确定哪一行为下一行,则这种一次一
行的策略不可行。(可能是 SELECT 语句包括 ORDER 子句的那种情况)。
使用滚动游标的 FETCH
这些 GBase 8s ESQL/C 示例说明使用滚动游标的 FETCH 语句:
EXEC SQL fetch previous q_curs into :orders;
EXEC SQL fetch last q_curs into :orders;
EXEC SQL fetch relative -10 q_curs into :orders;
printf("Which row? ");
scanf("
EXEC SQL fetch absolute :row_num q_curs into :orders;
滚动游标可访存活动的集合中的任意行,或者通过指定绝对行位置,或者通过指
定相对偏移量。使用下列游标位置选项来指定您想要检索的特定行。
关键字 作用

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 622
NEXT 检索活动的集合中的下一行
PREVIOUS 检索活动的集合中的前一行
PRIOR 检索活动的集合中的前一行(与 PREVIOUS 同义。)
FIRST 检索活动的集合中的第一行
LAST 检索活动的集合中的最后一行
CURRENT 检索活动的集合中的当前行(与前面的 FETCH 语句从滚动游标
返回的行相同)
RELATIVE 检索相对于活动的集合中当前游标位置的第 n 行,其中
position_num(或 position_num_var) 提供 n。负值指示当前游
标位置之前的第 n 行。如果 position_num = 0,则访存当前
行。
ABSOLUTE 检索活动的集合中的第 n 行,其中 row_position_var (或
row_position)= n。绝对行位置从 1 开始计数。
提示: 请不要将行位置值与 rowid 值相混淆。rowid 值是基于在其表中的位
置,并在重建表之前保持有效。行位置值(ABSOLUTE 关键字检索到的值)是该行
在游标的活动的集合中的相对位置;下一次打开游标时,可能选择不同的行。
数据库服务器如何实现滚动游标
由于数据库服务器不可预测程序下一次会请求哪一行,因此数据库服务器必须保
留活动的集合中的所有行,直到该滚动游标关闭为止。在滚动游标打开时,数据
库服务器实现活动的集合作为临时表,虽然它不可能立即植入此表。
第一次访存行时,数据库服务器将它复制到临时表内并将它返回到程序。
在第二次访存行时,可以从临时表进行。这种方案使用最少的资源,以防程序在
访存所有行之前放弃查询。从不被访存的那些行通常不从数据库复制,或被保存
在临时表中。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 623
指定值在内存中的返回位置
来自查询的选择列表或者执行用户定义的函数的每一值必须被返回到内存位置
内。您可以下列方式之一指定这些目的地:

使用 SELECT 语句的 INTO 子句。

使用 EXECUTE 函数(或 EXECUTE PROCEDURE)语句的 INTO 子
句。

使用 FETCH 语句的 INTO 子句。

使用系统描述符区域。

使用 sqlda 结构。
使用 INTO 子句
如果您将 SELECT 或 EXECUTE FUNCTION(或 EXECUTE PROCEDURE)语
句与函数游标相关联,则该语句可包含 INTO 子句来指定变量来接收返回的值。
仅当写 SELECT、EXECUTE FUNCTION 或 EXECUTE PROCEDURE 语句作为
游标声明的一部分时,才可使用这种方法;请参阅 DECLARE 语句。在这种情况
下,FETCH 语句不可包含 INTO 子句。
下列示例使用 SELECT 语句的 INTO 子句来指定 GBase 8s ESQL/C 中的程序变
量:
EXEC SQL declare ord_date cursor for
select order_num, order_date, po_num
into :o_num, :o_date, :o_po;
EXEC SQL open ord_date;
EXEC SQL fetch next ord_date;
如果您准备 SELECT 语句,则 SELECT 不可包括 INTO 子句,因此必须使用
FETCH 语句的 INTO 子句。
在您动态地创建 SELECT 语句时,不可使用 INTO 子句,因为您不可在准备好
的语句中命名主变量。
如果您确定投影列表中值的数量和数据类型,则可使用 FETCH 语句中的 INTO
子句。然而,如果用户输入生成了查询,则可能无法确定被选择的值的数量和数
据类型。在这种情况下,您必须或者使用系统描述符,或者使用指向 sqlda 结构
的指针。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 624
使用指示符变量
如果返回的数据可能为空,则请使用指示符变量。
indicator_var 参数是可选的,但如果可能存在 output_var 的值为
NULL 的情况,则使用指示符变量。
如果您指定不带 INDICATOR 关键字的指示符变量,则不可在
output_var 与 indicator_var 之间加空格。
要获取更多关于在 indicator_var 之前加前缀的规则的信息,请参阅 GBase 8s
ESQL/C 程序员手册。
主变量不可为 DATETIME 或 INTERVAL 数据类型。
在需要 FETCH 的 INTO 子句时
在 SELECT 或 EXECUTE FUNCTION(或 EXECUTE PROCEDURE)省略
INTO 子句时,在访存行时必须指定数据目标。
例如,要动态地执行 SELECT 或 EXECUTE FUNCTION(或 EXECUTE
PROCEDURE)语句,SELECT 或 EXECUTE FUNCTION(或 EXECUTE
PROCEDURE)不可在 PREPARE 语句中包括其 INTO 子句。因此,FETCH 语
句必须包括 INTO 子句来将数据检索到一组变量内。这种方法让您在不同的内存
位置中存储不同的行。
仅可使用 FETCH 语句中的 INTO 子句来访存到程序数组元素内。如果您使用程序
数组,则必须罗列数据名称和在 data_structure 中数据的特定元素。在您声明
游标时,请不要在 SQL 语句内引用数据元素。
提示: 如果您确定在 Projection 子句的选择列表中值的数量和数据类型,则可
使用 FETCH 语句中的 INTO 子句。
在下列 GBase 8s ESQL/C 示例中,一系列完整的行被访存到程序数组内。每一
FETCH 语句的 INTO 子句指定数组元素和数据名称:
EXEC SQL BEGIN DECLARE SECTION;
char wanted_state[2];
short int row_count = 0;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 625
struct customer_t{
{
int c_no;
char fname[15];
char lname[15];
} cust_rec[100];
EXEC SQL END DECLARE SECTION;

main()
{
EXEC SQL connect to'stores_demo';
printf("Enter 2-letter state code: ");
scanf ("%s", wanted_state);
EXEC SQL declare cust cursor for
select * from customer where state = :wanted_state;
EXEC SQL open cust;
EXEC SQL fetch cust into :cust_rec[row_count];
while (SQLCODE == 0)
{
printf("\n%s %s", cust_rec[row_count].fname,
cust_rec[row_count].lname);
row_count++;
EXEC SQL fetch cust into :cust_rec[row_count];
}
printf ("\n");
EXEC SQL close cust;
EXEC SQL free cust;
}
使用系统描述符区域(X/Open)
当您不知道在运行时 SELECT 或 EXECUTE FUNCTION(或 EXECUTE
PROCEDURE)语句返回的返回值的数量或其数据类型时,可使用系统描述符区
域来存储输出值。系统描述符区域描述一个或多个返回值的数据类型和内存位
置,并符合 X/Open 标准。
关键字 USING SQL DESCRIPTOR 将系统描述符区域的名称引入您访存行的内容
或用户定义的函数的返回值内。然后您可使用 GET DESCRIPTOR 语句来将
FETCH 语句返回的值从系统描述符区域传送到主变量内。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 626
下列示例展示有效的 FETCH…USING SQL DESCRIPTOR 语句:
EXEC SQL allocate descriptor 'desc';
...
EXEC SQL declare selcurs cursor for
select * from customer where state = 'CA';
EXEC SQL describe selcurs using sql descriptor 'desc';
EXEC SQL open selcurs;
while (1)
{
EXEC SQL fetch selcurs using sql descriptor 'desc';
您还可使用 sqlda 结构来动态地提供参数。
使用 sqlda 结构
在您不知道 SELECT 或 EXECUTE FUNCTION(或 EXECUTE PROCEDURE)
语句返回的值的数量或其数据类型时,可使用指向 sqlda 结构的指针来存储输出
值。
此结构包含为一个选择的值指定数据类型和内存位置的数据描述符。关键字
USING DESCRIPTOR 引入指向 sqlda 结构的指针。
提示: 如果您知道在选择列表中所有值的数量和数据类型,则可使用 FETCH 语
句中的 INTO 子句。要获取更多信息,请参阅 在需要 FETCH 的 INTO 子句时。
要指定 sqlda 结构作为参数位置:
1. 声明 sqlda 指针变量。
2. 使用 DESCRIBE 语句来填充 sqlda 结构。
3. 分配内存来保留数据值。
4. 使用 FETCH 的 USING DESCRIPTOR 子句来指定 sqlda 结构作为您访
存返回值的目标位置。
下列示例展示 FETCH USING DESCRIPTOR 语句:
struct sqlda *sqlda_ptr;
...
EXEC SQL declare selcurs2 cursor for

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 627
select * from customer where state = 'CA';
EXEC SQL describe selcurs2 into sqlda_ptr;
...
EXEC SQL open selcurs2;
while (1)
{
EXEC SQL fetch selcurs2 using descriptor sqlda_ptr;
...
sqld 值指定 sqlda 结构的 sqlvar 结构的出现个数中描述的输出值的数量。此数
量必须对应于从准备好的语句返回的值的数量。
为更新而访存行
FETCH 语句通常不锁定已访存的行。这样,您的程序收到该访存的行之后,另一
进程可立即修改(更新或删除)它。在下列情况下,锁定访存的行:

在您将隔离级别设置为 Repeatable Read 时,以读锁锁定访存的每一行,
直到当前会话结束为止。其他程序还可读锁定的行。

在您将隔离级别设置为 Cursor Stability 时,锁定当前行。

在符合 ANSI 的数据库中,Repeatable Read 为缺省的隔离级别;您可将
它设置为其他值。

当您通过更新游标(声明 FOR UPDATE 的游标)访存时,以可提升锁
锁定访存的每一行。其他程序可读取锁定的行,但其他程序不可放置可提
升锁或写锁;因此,如果另一用户试图使用 UPDATE 或 DELETE 语句
的 WHERE CURRENT OF 子句修改该行,则它保持不变。
当您修改行时,锁升级为写锁并保持直到游标关闭或事务结束为止。如果您不修
改行,则数据库服务器的行为取决于已设置的隔离级别。一旦访存另一行,数据
库服务器即释放未更改的行的锁,除非您正在使用 Repeatable Read 隔离。(请参
阅 SET ISOLATION 语句。)
重要: 在没有使用 Repeatable Read 隔离或 Repeatable Read 隔离不可用时,您
可在附加的行上保持锁定。当您的程序正在读其他行时,以未更改的数据更新该
行来保持对它的锁定。您必须在应用的上下文中评估此技术对性能的影响,且必
须了解增加死锁的可能。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 628
在您使用显式事务时,请确保在单个事务内既访存也修改行;即,FETCH 和后续
的 UPDATE 或 DELETE 语句都必须在 BEGIN WORK 语句与下一个 COMMIT
WORK 语句之间。
从集合游标访存
集合游标允许您访问 GBase 8s ESQL/C 集合变量的个别元素。要声明集合游标,
请使用 DECLARE 语句,并将集合派生表段包括在与游标关联的 SELECT 语句
中。在您以 OPEN 语句打开集合游标之后,该游标允许您来访问集合变量的元
素。
要从集合游标每次访存一个元素,请使用 FETCH 语句和 INTO 子句。FETCH
语句标识以集合变量关联的集合游标。INTO 子句标识保留从集合游标访存的元
素值的主变量。INTO 子句中的主变量的数据类型必须与集合的元素类型相配。
假设您有一名为 children 的表,具有下列结构:
CREATE TABLE children
(
age SMALLINT,
name VARCHAR(30),
fav_colors SET(VARCHAR(20) NOT NULL),
)
下列 GBase 8s ESQL/C 代码段展示如何从 child_colors 集合变量访存元素:
EXEC SQL BEGIN DECLARE SECTION;
client collection child_colors;
varchar one_favorite[21];
char child_name[31] = "marybeth";
EXEC SQL END DECLARE SECTION;
EXEC SQL allocate collection :child_colors;
/* Get structure of fav_colors column for untyped
* child_colors collection variable */
EXEC SQL select fav_colors into :child_colors
from children
where name = :child_name;
/* Declare select cursor for child_colors collection
* variable */
EXEC SQL declare colors_curs cursor for

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 629
select * from table(:child_colors);
EXEC SQL open colors_curs;
do
{
EXEC SQL fetch colors_curs into :one_favorite;
...
} while (SQLCODE == 0)
EXEC SQL close colors_curs;
EXEC SQL free colors_curs;
EXEC SQL deallocate collection :child_colors;
在访存集合元素之后,您可以 UPDATA 或 DELETE 语句修改该元素。要获取
更多信息,请参阅本文档中的 UPDATE 和 DELETE 语句。您还可以 INSERT
语句将新元素插入到集合变量内。要获取更多信息,请参阅 INSERT 语句。
检查 FETCH 的结果
您可使用 SQLSTATE 变量来检查每一 FETCH 语句的结果。数据库服务器在每
一 SQL 语句之后设置 SQLSTATE 变量。如果成功地返回一行,则
SQLSTATE 变量包含值 00000。如果未找到行,则数据库服务器设置
SQLSTATE 代码为 02000,表明 未找到数据,且当前行不变。下列条件将
SQLSTATE 代码设置为 02000,表明 未找到数据:

活动的集合未包含行。

在游标指向活动的集合中的最后一行或越过该行时,发出 FETCH NEXT
语句。

在游标指向活动的集合中的第一行时,发出 FETCH PRIOR 或 FETCH
PREVIOUS 语句。

在活动的集合中不存在第 n 行时,发出 FETCH RELATIVE n 语句。

在活动的集合中不存在第 n 行时,发出 FETCH ABSOLUTE n 语句。
数据库服务器从系统诊断区域的 RETURNED_SQLSTATE 域复制 SQLSTATE
代码。 GBase 8s 的客户机/服务器通信协议,诸如 SQLI 和 DRDA®,支持
SQLSTATE 代码值。要获取这些代码的列表,并获取关于如何获得消息文本的
消息,请参阅 使用 SQLSTATE 错误状态代码。您可使用 GET DIAGNOSTICS
语句来直接地检验 RETURNED_SQLSTATE 域。系统诊断区域还可包含附加的
错误信息。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 630
您还可使用 SQL 通信区域(sqlca)的 SQLCODE 变量来确定相同的结果。
在 SPL 例程中的使用 FETCH
使用 SPL 例程中的 FETCH 语句来检索指定的动态游标活动的集合的下一行,
检索到一个在同一 SPL 例程中声明的 SPL 变量的有序列表内。
语法
SPL 例程中 FETCH 语句的语法是在 GBase 8s ESQL/C 例程中 FETCH 支持的
语法的子集。

元素
描述
限制
语法
cursor_id
动态游标的名称
必须是打开的且已经在
同一 SPL 例程中声明
标识符
output_var
存储来自该行的访存
的值的 SPL 变量
必须在调用上下文中已
经本地地或全局地声
明,且必须为与访存的
列值相兼容的数据类型
标识符
cursor_var
游标变量的名称
必须已经定义并打开
标识符
恰如在 ESQL/C 例程中那样,输出变量的列表必须与列值的数量、顺序和数据类
型相一致,这些列值是 SQL 语句关联的由特定的游标返回的那些行。
所有 SPL 游标都是顺序游标。您的 UDR 必须包括检测游标的活动的集合到头
的逻辑,因为在 SPL 中 NOTFOUND 条件不会自动地产生例外。
内建的 SQLCODE 函数,仅可从 SPL 例程调用的函数,可返回 FETCH 操作
的状态代码。
对引用顺序选择游标或功能游标的 FETCH 语句的其他 ESQL/C 限制,也适用于
SPL 中的 FETCH 操作。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 631
SPL 例程中的 FETCH 语句不支持下列 ESQL/C 特性:

位置规范或位置关键字(需要滚动游标)

随同描述符或随同 sqlda 指针的 USING 子句。
在 SPL 语言中,不需要指示符变量。如果 FETCH 操作收到 NULL 值,则将收到
访存的值的 SPL 变量设置为 NULL。
FETCH 语句仅可引用 DECLARE 语句定义的动态游标和 DEFINE 语句定义的
游标变量。cursor_id 不可指定 SPL 的 FOREACH 语句声明的直接游标的名
称。