一个主要问题是您没有限制UPDATE 语句。您实际上是在更新整个表中的每一行。每当你写UPDATE 和DELETE 语句时要注意这一点,否则你会引起重大问题,你的同事不会感谢你。我建议您将所有这些类型的语句写成SELECT 语句,以确保您正确地限制了WHERE 子句,然后将其转换为更危险的语句。
至于您的具体问题 - 是的 - 您需要遍历游标中的每条记录,然后更新表中的 SINGLE 对应行。
这是一个更新的示例:
CREATE OR REPLACE PROCEDURE update_data
IS
CURSOR c1
IS
SELECT primary_key_column, /* SELECT THIS SO THAT YOU CAN IDENTIFY THE SINGLE ROW TO UPDATE */
SUBSTR(t.address, 3, 4) AS info /*NAME THIS SO IT CAN BE REFERENCED IN THE LOOP */
FROM table_1 t
WHERE t.age > 21;
BEGIN
FOR r /* NAME THE ROW */ IN c1 LOOP /* ORACLE AUTMOATICALLY OPENS THE CURSOR HERE */
UPDATE table_1 t
SET t.info = r.info
WHERE t.primary_key_column = r.primary_key_column; /* LIMIT THE UPDATE TO THIS ROW ONLY */
END LOOP; /* ORACLE AUTOMATICALLY CLOSES THE CURSOR HERE */
END;
你可以使用OPEN, FETCH, CLOSE 方法你当前使用的循环,但我个人认为FOR ... IN 语法更易读,更容易编写,并且可以处理打开和关闭游标给你,所以我在这里用过。
要注意的主要事情是UPDATE 现在仅限于一条记录,因此循环中的每次迭代都会更新您在SUBSTR 上运行的同一条记录,而不是整个表。
或者,这可以通过一个语句来完成:
UPDATE table_1 t
SET t.info = SUBSTR(t.address, 3, 4)
WHERE t.age > 21;
只要确保您正确限制了您的 UPDATE。