第四⼗三章SQL命令FETCH
⽂章⽬录
第四⼗三章 SQL命令 FETCH
第四⼗三章 SQL命令 FETCH
重新定位游标,并从中检索数据。
⼤纲
FETCH cursor-name [INTO host-variable-list ]
参数
cursor-name - 当前打开的游标的名称。
游标名称是在DECLARE命令中指定的。
游标名称区分⼤⼩写。
INTO host-variable-list - 可选—将取操作列中的数据放⼊局部变量中。
host-variable-list指定⼀个主机变量或⼀个逗号分隔的主机变量列表,它们是包含与游标关联的数据的⽬标。
INTO句是可选的。
如果没有指定,FETCH语句只定位游标。
描述
在嵌⼊式SQL应⽤程序中,FETCH语句从游标检索数据。
所需的操作顺序是:DECLARE、OPEN、FETCH、CLOSE。
在未打开的游标上尝试FETCH会导致SQLCODE -102错误。
作为SQL语句,这只在嵌⼊式SQL中得到⽀持。
通过ODBC使⽤ODBC API⽀持等价的操作。
INTO⼦句可以指定为DECLARE语句的⼦句,也可以指定为FETCH语句的⼦句,或者两者都指定。
INTO⼦句允许将fetch列中的数据放到本地主机变量中。
列表中的每个主机变量,从左到右,都与游标结果集中的相应列相关联。
每个变量的数据类型必须匹配或⽀持对应结果集列的数据类型的隐式转换。
变量的数量必须与游标选择列表中的列数匹配。
当游标前进到数据的末尾时,FETCH操作就完成了。
这将设置SQLCODE=100(没有更多数据)。
它还将%ROWCOUNT变量设置为获取的⾏数。
注意:只有当SQLCODE=0时,INTO⼦句宿主变量返回的值才是可靠的。
如果SQLCODE=100(没有更多数据),则不应该使⽤主机变量值。
游标名称不是特定于名称空间的。
泰迪熊ted更改当前名称空间对声明游标的使⽤没有影响。
唯⼀需要考虑的名称空间是FETCH必须出现在包含要查询的表的名称空间中。
%ROWID
当FETCH检索可更新游标的⾏时,它将%ROWID设置为所获取⾏的ROWID值。
哈利波特电子书下载可更新游标是指顶部FROM⼦句只包含⼀个元素(表名或可更新视图名)的游标。
为检索到的每⼀⾏设置%ROWID受以下条件的限制:
DECLARE cursorname CURSOR和OPEN cursorname语句不初始化%ROWID;
%ROWID值与之前的值不变。
第⼀个成功的FETCH设置%ROWID。
每个后续的FETCH检索⾏都会将%ROWID重置为当前的ROWID。
FETCH如果检索可更新游标的⾏,则设置%ROWID。
如果游标不可更新,%ROWID将保持不变。
如果没有匹配查询选择条件的⾏,FETCH不会更改之前的%ROWID值。
在CLOSE或FETCH发出SQLCODE 100 (No Data, or No More Data)时,%ROWID包含检索到的最后⼀⾏的ROWID。
带有DISTINCT关键字或GROUP BY⼦句的基于游标的SELECT不会设置%ROWID。
%ROWID值与之前的值(如果有的话)保持不变。
基于游标的SELECT只执⾏聚合操作,不设置%ROWID。
%ROWID值与之前的值(如果有的话)保持不变。
没有声明游标的嵌⼊式SQL SELECT不会设置%ROWID。
在完成⼀个简单的SELECT语句后,%ROWID值是不变的。
FETCH for UPDATE or DELETE
可以使⽤FETCH来检索要进⾏更新或删除的⾏。
人民币500UPDATE或DELETE必须指定WHERE CURRENT OF⼦句。
DECLARE应该指定FOR UPDATE⼦句。
下⾯的⽰例显⽰了⼀个基于游标的删除操作,它删除所有选中的⾏:
ClassMethod FETCH()
{sqw
s $NAMESPACE="Samples"
&sql(
DECLARE MyCursor CURSOR FOR SELECT %ID,Status
FROM Sample.Quality WHERE Status='Bad' FOR UPDATE
)
&sql(
OPEN MyCursor
)
if SQLCODE<0{
w "SQL Open游标错误:",SQLCODE," ",%msg
q
}
n %ROWCOUNT,%ROWID
for{
&sql(
FETCH MyCursor
)
q:SQLCODE'=0
&sql(
DELETE FROM Sample.Quality WHERE CURRENT OF MyCursor
)
}
w !,"更新的⾏数=",%ROWCOUNT
&sql(
CLOSE MyCursor
)
if SQLCODE<0{
w "SQL关闭游标错误:",SQLCODE," ",%msg
q
}
}
⽰例
下⾯的嵌⼊式SQL⽰例显⽰了⼀个⽆参数的FOR循环调⽤FETCH,从名为EmpCursor的游标检索数据。INTO⼦句在DECLARE语句中指定:
ClassMethod FETCH1()
{
&sql(
DECLARE EmpCursor CURSOR FOR
SELECT Name, Home_State
INTO :name,:state FROM Sample.Employee
WHERE Home_State %STARTSWITH 'M'
)
&sql(
OPEN EmpCursor
)
if SQLCODE<0{
w "SQL Open游标错误:",SQLCODE," ",%msg
q
}
n %ROWCOUNT,%ROWID
for{
&sql(
FETCH EmpCursor
)
q:SQLCODE'=0
w "count: ",%ROWCOUNT," RowID: ",%ROWID,!
w " Name=",name," State=",state,!
}
w !,"Final Fetch SQLCODE: ",SQLCODE
&sql(
CLOSE EmpCursor
)
if SQLCODE<0{
w "SQL关闭游标错误:",SQLCODE," ",%msg
q
}
}
下⾯的嵌⼊式SQL⽰例显⽰了⼀个⽆参数的FOR循环调⽤FETCH,从名为EmpCursor的游标检索数据。INTO⼦句被指定为FETCH语句的⼀部分:
DECLARE C1 CURSOR FOR
SELECT Name,Home_State INTO :name,:state FROM Sample.Person WHERE Home_State %STARTSWITH 'M'
)
&sql(OPEN C1)
if SQLCODE<0{
w "SQL Open游标错误:",SQLCODE," ",%msg
q
}
&sql(FETCH C1)
while(SQLCODE =0){
退欧
w "count: ",%ROWCOUNT," RowID: ",%ROWID,!
w " Name=",name," State=",state,!
&sql(FETCH C1)
}
w !,"Final Fetch SQLCODE: ",SQLCODE
&sql(CLOSE C1)
if SQLCODE<0{
征服英语w "SQL关闭游标错误:",SQLCODE," ",%msg
q
}
笔记本电脑硬盘坏了怎么办
}
下⾯的嵌⼊式SQL⽰例显⽰FETCH检索聚合函数值。
%ROWID没有设置:
ClassMethod FETCH3()
{
&sql(
DECLARE PersonCursor CURSOR FOR
SELECT COUNT(*),AVG(Age) FROM Sample.Person
)
&sql(OPEN PersonCursor)
if SQLCODE<0{
w "SQL Open游标错误:",SQLCODE," ",%msg
q
}
n %ROWCOUNT
for{
&sql(
FETCH PersonCursor INTO :cnt,:avg
)
q:SQLCODE'=0
w %ROWCOUNT," Num People=",cnt," Average Age=",avg,!
}
w !,"Final Fetch SQLCODE: ",SQLCODE
&sql(CLOSE PersonCursor)
if SQLCODE<0{
w "SQL关闭游标错误:",SQLCODE," ",%msg
q
}
}
下⾯的嵌⼊式SQL⽰例显⽰FETCH检索DISTINCT值。
%ROWID没有设置:
DECLARE EmpCursor CURSOR FOR
SELECT DISTINCT Home_State FROM Sample.Employee
WHERE Home_State %STARTSWITH 'M'
ORDER BY Home_State
)
&sql(OPEN EmpCursor)
if SQLCODE<0{
w "SQL Open游标错误:",SQLCODE," ",%msg
q
}
n %ROWCOUNT
for{
&sql(
FETCH EmpCursor INTO :state
)
q:SQLCODE'=0
w %ROWCOUNT," State=",state,!
}
w !,"Final Fetch SQLCODE: ",SQLCODE
&sql(CLOSE EmpCursor)
if SQLCODE<0{
w "SQL关闭游标错误:",SQLCODE," ",%msg
q
}
}
下⾯的嵌⼊式SQL⽰例显⽰了游标跨名称空间持久存在。
该游标在%SYS中声明,在USER中打开和获取,在SAMPLES中关闭。
注意,OPEN必须在包含要查询的表的名称空间中执⾏,FETCH必须能够访问输出主机变量,这些变量是特定于名称空间的:
ClassMethod FETCH5()
{
&sql(USE DATABASE %SYS)
w $ZNSPACE,!
&sql(DECLARE NSCursor CURSOR FOR SELECT Name INTO :name FROM Sample.Employee)
&sql(USE DATABASE "USER")
w $ZNSPACE,!
&sql(OPEN NSCursor)
if SQLCODE<0{
w "SQL Open游标错误:",SQLCODE," ",%msg
q
}
n SQLCODE,%ROWCOUNT,%ROWID
under siegefor{
&sql(FETCH NSCursor)
q:SQLCODE
喝咖啡睡不着怎么办
w "Name=",name,!
}
&sql(USE DATABASE SAMPLES)呈报
w $ZNSPACE,!
&sql(CLOSE NSCursor)
if SQLCODE<0{
w "SQL关闭游标错误:",SQLCODE," ",%msg
q
}
}