1

我需要一些关于我的想法是否可行的建议。我有一种情况:

我需要对表格的每一行进行更新。更新涉及一些逻辑。逻辑很简单,但是需要对每一行都做。每行都有更新的可能性。

目前,我正在考虑编写一个 ESQL/C 程序来执行此操作。我正在考虑通过选择更新游标将每一行加载到其等效的 C 结构中,运行逻辑并提交。HOLD 关键字在游标上起什么作用?我对这个角色的作用有点困惑。

这些更新将在系统停机期间完成。该表包含大约 1.3 亿行。它有大约 45 列。大多数列的类型为 SMALLINT 和 INTEGER。

我在正确的轨道上吗?欢迎提出建议。

数据库将是 Informix(IDS 版本 11.50 FC6)

4

2 回答 2

2

完成这项工作的关键是在服务器中完成工作,而不是让服务器选择每一行,将其传递给客户端,然后从客户端接收数据。

UPDATE YourTable
   SET y = (CASE WHEN z > x THEN p ELSE y)
 WHERE key_column BETWEEN lo_val AND hi_val;

复杂的部分可能会将工作拆分为可管理的子事务;这就是“lo_val .. hi_val”条件的含义。如果您的逻辑日志足够大,可以处理所有 1.3 亿行正在更新的 [大约 (2 * (行大小 + X) * 行数),我相信 X 的值大约是 20] 有剩余空间,那么您可以一次完成。显然,这会“更新”每一行。

如果您决定必须在客户端执行此操作(一个错误,但是...),那么:

您将 SELECT 游标与 HOLD 一起使用,以便它在事务中保持打开并正确定位。你开始一个事务,获取几千行,根据需要更新每一行。确保您使用的是准备好的 UPDATE 语句;也许您使用 WHERE CURRENT OF 条件。


您是否建议将更新作为游标的一部分放在存储过程中?

不,尽管您可以在存储过程中执行此操作。这部分取决于您是否要定期执行此操作;如果是这样,也许存储过程是一个好主意,但我不会一次性练习。

这取决于您将如何确定 lo_val 和 hi_val。我可能会使用 I4GL(因为我精通它),然后我希望准备 UPDATE 语句(用问号代替“lo_val”和“hi_val”),然后我希望执行它多次,每次形成一个单一的语句事务。所以,如果你决定从 000000..099999、100000..199999 开始使用 lo_val..hi_val 范围......那么你会迭代:

for i = 0 to 10000000 step 100000
    let j = i + 99999
    execute p_update using i, j
end for

在 I4GL 中,您绝对不需要使用准备好的语句。如果您有 IDS 11,则可以在 SPL 中准备语句。在早期版本中,并且没有太大的性能影响(我怀疑您是否可以可靠地测量它),您可以简单地使用:

CREATE PROCEDURE update_your_table()
    DEFINE lo_val, hi_val INTEGER;

    FOR lo_val = 0 TO 1000000 STEP 100000
        LET hi_val = lo_val + 99999;
        UPDATE YourTable
           SET y = (CASE WHEN z > x THEN p ELSE y)
         WHERE key_column BETWEEN lo_val AND hi_val;
    END FOR;

END PROCEDURE;

未经测试的代码 - 使用风险自负!

于 2010-02-22T04:09:38.260 回答
0

SPL 是要走的路!.. 但我建议您复制该表并首先测试您的批量更新。

于 2010-02-27T23:00:04.633 回答