系统变量 ::ROWCOUNT 存储先前执行的 DML、CALL 和 CREATE TABLE 语句的更新行数,或从 SELECT 语句返回的行数。没有累计以前执行的所有语句中的 ::ROWCOUNT 值。如果上一语句不返回值,则保留 ::ROWCOUNT 的上一个值。当在 PARALLEL EXECUTION 块后立即使用 ::ROWCOUNT 时,系统变量仅存储过程定义中最后一个语句的值。
注意在 SAP HANA 2.0 SPS03 之前,系统变量 ::ROWCOUNT 仅在 DML 语句之后更新。从 SAP HANA 2.0 SPS04 开始, ::ROWCOUNT 的行为发生更改,现在还针对 SELECT、CALL 和 CREATE TABLE 语句进行更新。 以下限制适用:
SELECT 语句返回的行数。
SELECT 语句的 ROWCOUNT 支持常规 SELECT 语句、SELECT INTO 语句和包含 SELECT 语句的表变量分配。它不包括 SELECT 子查询作为 DML 或 DDL 的一部分。
SELECT 语句执行 ROWCOUNT。
备注当在 SELECT 语句后使用 ::ROWCOUNT 时,它需要从结果集中获取整行以获取所选行的总数。当来自 SELECT 语句的结果分配给表变量或标量变量时,它几乎不会对性能产生任何影响。但是,无论从结果集中显式读取多少行,返回结果集的 SELECT 语句都不能避免隐式读取所有行。
以下示例演示如何在过程中使用 ::ROWCOUNT。假设我们有下表 T:
CREATE TABLE T (NUM INT, VAL INT);
INSERT INTO T VALUES (1, 1);
INSERT INTO T VALUES (2, 2);
INSERT INTO T VALUES (1, 2);
现在,我们要更新表 T 并想要返回更新的行数:
CREATE PROCEDURE PROC_UPDATE (OUT updated_rows INT) AS
BEGIN
UPDATE T SET VAL = VAL + 1 WHERE VAL = 2;
updated_rows = ::ROWCOUNT;
END;
通过使用 调用过程
CALL PROC_UPDATE (updated_rows => ?);我们得到以下结果:
UPDATED_ROWS
2
在下一个示例中,我们通过使用两个 update 语句来更改过程,最后我们再次获得行计数:
ALTER PROCEDURE PROC_UPDATE (OUT updated_rows INT) AS
BEGIN
UPDATE T SET VAL = VAL + 1 WHERE VAL = 3;
UPDATE T SET VAL = VAL + 1 WHERE VAL = 1;
updated_rows = ::ROWCOUNT;
END;
通过调用过程,您将看到更新的行数现在为 1。这是因为 las update 语句只更新了一行。
UPDATED_ROWS
1
如果现在想要获取所有更新行的数量,则必须在每个更新语句后检索行计数信息并将其累计:
ALTER PROCEDURE PROC_UPDATE (OUT updated_rows INT) AS
BEGIN
UPDATE T SET VAL = VAL + 1 WHERE VAL = 4;
updated_rows = ::ROWCOUNT;
UPDATE T SET VAL = VAL + 1 WHERE VAL = 2;
updated_rows = :updated_rows + ::ROWCOUNT;
END;
现在,再次调用此过程,更新的行数为 3:
UPDATED_ROWS
3
注意SAP HANA 2.0 SPS04 中 ::ROWCOUNT 的更新引入了不兼容的行为更改。有关详细信息、变通方法和支持工具,请参阅以下描述。
由于 ::ROWCOUNT 现在在 SELECT、CALL 和 CREATE TABLE 语句之后更新,因此如果系统变量 ::ROWCOUNT 未在 DML 语句之后直接使用,则现有过程的行为可能会更改。建议在建议目标语句之后直接使用 ::ROWCOUNT,并且可以保证不同版本之间的行为相同。
为了检测此类情况,SQLScript 代码分析器中引入了新规则:
根据 SQLScript 代码分析器规则的结果,您可以根据新标准行为更新过程。
以下场景显示了行为更改影响的简单示例。
示例代码行为更改示例create table mytab (i int);insert into mytab values (1); create table mytab2 (i int);insert into mytab2 values (2); do begin insert into mytab select * from mytab2; -- ::ROWCOUNT = 1 x = select * from mytab; -- ::ROWCOUNT = 1 (retained, SPS03), ::RWCOUNT = 2 (SPS04) select ::rowcount from dummy; -- 1 in SPS03, 2 in SPS04end; 语句::ROWCOUNT (SPS03)::ROWCOUNT (SPS04)DML更新的行数更新的行数SELECT 语句select * from mytab;N/A(保留先前值)从 SELECT 语句返回的行数具有 SELECT 语句的表变量语句tv = select * from mytab;N/A(保留先前值)从 SELECT 语句返回的行数SELECT INTO 语句select i into a from mytab;N/A(保留先前值)如果成功执行语句,则为 1,否则保留以前的值。SELECT INTO 语句(含缺省值)select i into a default 2 from mytab;N/A(保留先前值)如果分配了默认值,则为 0;如果从 SELECT 语句赋值,则为 1;否则保留以前的值。动态 SQL 中的 SELECT 语句exec 'select * from mytab';execute immediate 'select * from mytab';0SELECT 语句中的行数EXEC INTO(使用 SELECT 语句)exec 'select i, j from mytab' into s1, s2;exec 'select * from mytab' into tv;0含标量变量的 EXEC INTO 与 SELECT INTO 大小写类似。带有表变量的 EXEC INTO 与表变量 assign 语句大小写类似。嵌套的 CALL 语句call proc_nested;N/A(保留先前值)更新的行数。CREATE TABLE 语句create table tab_a as (select * from mytab);N/A(保留先前值)更新的行数