我需要一些关于我的想法是否合适的建议。我有一个情况:
我需要对表格的每一行进行更新。更新中涉及一些逻辑。 逻辑非常简单,但需要为每一行完成。每一行都有可能得到更新。
目前,我正在考虑编写ESQL / C程序来执行此操作。我正在考虑将每一行加载到其中 等效C结构通过select for update游标,运行逻辑和提交。 HOLD关键字对游标的作用是什么?我对此的作用感到有点困惑。
这些更新将在系统停机期间完成。该表包含大约1.3亿行。它有 大约45列。大多数列都是SMALLINT和INTEGER类型。
我是否在正确的轨道上?建议欢迎。
数据库将是Informix(IDS版本11.50 FC6)
答案 0 :(得分: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,我相信有空间可供使用,那么你可以一次完成所有工作。显然,这会“更新”每一行。
如果您决定必须在客户端进行(错误,但......),那么:
使用带有HOLD的SELECT游标,使其保持打开状态并在事务中正确定位。您启动一个事务,获取几千行,根据需要更新每个行。确保使用准备好的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;
未经测试的代码 - 使用风险自负!
答案 1 :(得分:0)
SPL是要走的路!...但我建议您复制表并首先测试您的批量更新。