IBM 大型机环境中的许多客户端/服务器应用程序都涉及伪会话 CICS 事务。
如果您在伪会话模式下使用 CICS
当服务器返回给客户端时,服务器不可能持有游标。因此可滚动的游标
在这种环境下用处不大。因此,回答您的基本问题:此处不能使用任何可滚动光标。
这里的“技巧”是在服务器中创建一个可重新启动的 SQL 谓词。然后它将以正确的顺序从任何给定的行中提取行
陈述点。当客户端调用您的服务器时,它必须将所有定位信息传递给您的服务器。
通常,在客户端第一次调用时,所有定位值都会设置为使光标
位置本身必须从第一行开始。然后服务器拉入一个“页面”的数据
并将其返回给客户端。在下一页转发请求中,客户端将这些定位值设置为
它显示的最后一行并调用服务器以获得下一个“页面”数据。
在您的情况下,我假设页面前进光标看起来像这样,所有
以 RESTART... 为前缀的变量是客户端必须提供给服务器以启动游标的变量
在正确的位置。
DECLARE CURSOR Page-forward FOR
SELECT Receive_Date, Customer_id, Account_Nbr, Security_Dep_Id
FROM Table_Name
WHERE ( (Receive_Date < :RESTART-RCV-DT)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id > :RESTART-CUSTOMER-ID)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id = :RESTART-CUSTOMER-ID AND
Account_Nbr > :RESTART-ACCT-NBR)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id = :RESTART-CUSTOMER-ID AND
Account_Nbr = :RESTART-ACCT-NBR AND
Security_Dep_Id > :RESTART-SEC-DEP-ID))
ORDER BY 1 DESC, 2 ASC , 3 ASC, 4 ASC
对于初始调用,客户端将传递类似“9999-12-31”的内容作为 RESTART-RCV-DT,零
对于 RESTART-CUSTOMER-ID、RESTART-ACCT-NBR 和 SEC-DEP-ID(假设这些都是数字)。如果你看
游标谓词仔细您可以验证在这些值之前不能有任何行 - 因此这
将返回第一页数据。如果客户端在此之后需要向前翻页,它必须告诉服务器启动
在它收到的最后一行之后的下一行。为此,它将填充 RESTART... 变量
页面最后一行的值
显示。此过程将驱动光标一次向前选择一页。
当翻页时,过程是相反的(您需要第二个光标来支持这一点,客户端需要告诉您翻页的方向:前进或后退)。客户端
将需要使用从服务器收到的第一行填充 RESTART 变量。诀窍
对于上一页请求的服务器是返回数据
以相反的顺序发送给客户。您可能必须填充传回的数据页面
以相反的顺序发送给客户端(即将检索到的第一行放入共享的分页区域的最后一行
客户端和服务器)。页面向后光标看起来像:
DECLARE CURSOR Page-backward FOR
SELECT Receive_Date, Customer_id, Account_Nbr, Security_Dep_Id
FROM Table_Name
WHERE ( (Receive_Date > :RESTART-RCV-DT)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id < :RESTART-CUSTOMER-ID)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id = :RESTART-CUSTOMER-ID AND
Account_Nbr < :RESTART-ACCT-NBR)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id = :RESTART-CUSTOMER-ID AND
Account_Nbr = :RESTART-ACCT-NBR AND
Security_Dep_Id < :RESTART-SEC-DEP-ID))
ORDER BY 1 ASC, 2 DESC , 3 DESC, 4 DESC
正如在其他答案中指出的那样,这种类型的分页过程不会管理或检测并发
分页事务期间可能发生的数据库更新。那是另一天的另一个话题......
开发可重启游标
构建分页服务器的关键是开发一个可从一组接收到的值重新启动的游标
来自客户交易。这将光标定位和方向的控制权交给客户端。
这也意味着客户端必须从服务器接收所有关键的定位数据,即使
客户实际上可能不会
将这些数据用于任何其他目的(例如,从您的问题中我得到的印象是客户可能不需要
保证金 ID,但作为服务器的定位参数提供)
构建分页服务器你需要知道
数据所需的排序顺序是什么(例如,接收日期降序,然后客户 ID 升序
帐号升序)。
您还需要知道唯一标识一行的数据集
由光标返回。在您的情况下,这将是保证金 ID(这是
您从中选择的表,因此该表中的每一行都必须是唯一的)。知道了这一点,你就可以建立一个
游标谓词(WHERE 子句中的内容)将按所需的排序顺序返回客户端所需的数据
还包括
完整的定位密钥(即保证金 ID)。如果两个或更多返回的行可能包含相同的数据,如果
最终的定位键被消除,因此将定位键作为排序条件包含在内很重要。
不管是升序还是降序,都需要包含在排序中,以确保一致
数据检索顺序。
可以遵循一个相当简单的公式来为可重新启动的游标构建谓词
支持分页服务器。基本上,这是连接一系列“AND”子句的“OR”子句的级联
按照客户要求的排序顺序逐渐变得更有选择性并最终定位
键。
要了解其工作原理,请考虑如何开发您的服务器的查询...
从最不经常更改的排序顺序开始...
SELECT ...
FROM ...
WHERE Receive_Date < restart value
这将检索指定重新开始接收日期之前的所有行,而不管其他
列重新启动值是(例如,客户 ID 的范围可以从最小值到最大值,只要接收日期
小于迄今为止“看到”的任何接收日期)。由于此列仅在所有从属排序列值之后更改值
已经用尽你可以确定这不会在完全重启键之前拾取任何行。
但是那些与重新启动请求在同一日期发生但具有
更大的客户 ID?这些可以用...捡起。
SELECT ...
FROM ...
WHERE Receive_Date = restart value AND
Customer_id > restart value
接收日期和客户 ID 与重启键相同但具有
更大的帐号?这些可以通过...获取。
SELECT ...
FROM ...
WHERE Receive_Date = restart value AND
Customer_Id = restart value AND
Account_Nbr > restart value
继续此模式,直到处理完完整的重新启动密钥。注意不等式
符号由排序顺序决定。当列按降序排序时使用<,当按升序排序时使用>。
还要注意 SELECT 和 FROM 子句
每个查询都完全相同 - 这意味着您可以使用 OR 连接将它们全部放在一起...
SELECT Receive_Date, Customer_id, Account_Nbr, Security_Dep_Id
FROM Table_Name
WHERE ( (Receive_Date < :RESTART-RCV-DT)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id > :RESTART-CUSTOMER-ID)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id = :RESTART-CUSTOMER-ID AND
Account_Nbr > :RESTART-ACCT-NBR)
OR (Receive_Date = :RESTART-RCV-DT AND
Customer_Id = :RESTART-CUSTOMER-ID AND
Account_Nbr = :RESTART-ACCT-NBR AND
Security_Dep_Id > :RESTART-SEC-DEP-ID))
ORDER BY 1 DESC, 2 ASC , 3 ASC, 4 ASC
你去...一个用于向前分页的可重新启动光标。向后分页光标的构造遵循类似的模式,只需翻转
排序并重复。