oracle游标不更新数据
oracle cursor is not updating data
我举个例子来更好地说明情况:
我有两个table
CREATE TABLE AA
(
ID NUMBER NOT NULL PRIMARY KEY,
REFERENCE NVARCHAR2(100) NULL
)
CREATE TABLE BB
(
ID NUMBER NOT NULL PRIMARY KEY,
IDA NUMBER NOT NULL,
REFERENCE NVARCHAR2(100) NULL,
FOREIGN KEY (IDA) REFERENCES AA(ID)
)
和一些记录
INSERT INTO AA VALUES(1, NULL)
INSERT INTO AA VALUES(2, NULL)
INSERT INTO AA VALUES(3, NULL)
INSERT INTO AA VALUES(4, NULL)
INSERT INTO AA VALUES(5, NULL)
INSERT INTO BB VALUES(6, 1, 'AAA')
INSERT INTO BB VALUES(7, 2, 'BBB')
INSERT INTO BB VALUES(8, 3, 'CCC')
我必须通过 IDA
将 AA
的 REFERENCE
字段设置为 BB
中的值。
所以我决定使用游标
DECLARE
idA NUMBER;
reference NVARCHAR2(100);
CURSOR ref_cursor
IS
SELECT IDA, REFERENCE FROM BB;
BEGIN
OPEN ref_cursor;
LOOP
FETCH ref_cursor into idA, reference;
EXIT WHEN ref_cursor%NOTFOUND;
UPDATE AA
SET REFERENCE = reference
WHERE ID = idA;
DBMS_OUTPUT.put_line('reference of movement ' || idA || ' updated with ' || reference);
END LOOP;
CLOSE ref_cursor;
END;
通过执行它,我得到一个输出
reference of movement 1 updated with AAA
reference of movement 2 updated with BBB
reference of movement 3 updated with CCC
这正是我想要的,但是当我通过星号选择 table 检查数据时,我发现 REFERENCE
列仍然是 NULL
。
所以我找到了另一个光标
DECLARE
CURSOR ref_cursor
IS
SELECT IDA, REFERENCE FROM BB;
BEGIN
FOR ref_c IN ref_cursor
LOOP
UPDATE AA SET REFERENCE = ref_c.REFERENCE WHERE ID = ref_c.IDA;
END LOOP;
END;
这个实际上是在做更新。为什么这 2 个光标不同?
在你写的第一个游标中
UPDATE AA
SET REFERENCE = reference
WHERE ID = idA;
我认为你应该将变量重命名为不同的名称
当 SQL 语句在 PL/SQL 块内处理时,SQL 名称解析优先,因此 table 字段优先于同名变量.要解决此问题,您有两种方法:
更改变量名。
像您在第二个查询中所做的那样,为变量名称添加前缀。
我举个例子来更好地说明情况:
我有两个table
CREATE TABLE AA
(
ID NUMBER NOT NULL PRIMARY KEY,
REFERENCE NVARCHAR2(100) NULL
)
CREATE TABLE BB
(
ID NUMBER NOT NULL PRIMARY KEY,
IDA NUMBER NOT NULL,
REFERENCE NVARCHAR2(100) NULL,
FOREIGN KEY (IDA) REFERENCES AA(ID)
)
和一些记录
INSERT INTO AA VALUES(1, NULL)
INSERT INTO AA VALUES(2, NULL)
INSERT INTO AA VALUES(3, NULL)
INSERT INTO AA VALUES(4, NULL)
INSERT INTO AA VALUES(5, NULL)
INSERT INTO BB VALUES(6, 1, 'AAA')
INSERT INTO BB VALUES(7, 2, 'BBB')
INSERT INTO BB VALUES(8, 3, 'CCC')
我必须通过 IDA
将 AA
的 REFERENCE
字段设置为 BB
中的值。
所以我决定使用游标
DECLARE
idA NUMBER;
reference NVARCHAR2(100);
CURSOR ref_cursor
IS
SELECT IDA, REFERENCE FROM BB;
BEGIN
OPEN ref_cursor;
LOOP
FETCH ref_cursor into idA, reference;
EXIT WHEN ref_cursor%NOTFOUND;
UPDATE AA
SET REFERENCE = reference
WHERE ID = idA;
DBMS_OUTPUT.put_line('reference of movement ' || idA || ' updated with ' || reference);
END LOOP;
CLOSE ref_cursor;
END;
通过执行它,我得到一个输出
reference of movement 1 updated with AAA
reference of movement 2 updated with BBB
reference of movement 3 updated with CCC
这正是我想要的,但是当我通过星号选择 table 检查数据时,我发现 REFERENCE
列仍然是 NULL
。
所以我找到了另一个光标
DECLARE
CURSOR ref_cursor
IS
SELECT IDA, REFERENCE FROM BB;
BEGIN
FOR ref_c IN ref_cursor
LOOP
UPDATE AA SET REFERENCE = ref_c.REFERENCE WHERE ID = ref_c.IDA;
END LOOP;
END;
这个实际上是在做更新。为什么这 2 个光标不同?
在你写的第一个游标中
UPDATE AA
SET REFERENCE = reference
WHERE ID = idA;
我认为你应该将变量重命名为不同的名称
当 SQL 语句在 PL/SQL 块内处理时,SQL 名称解析优先,因此 table 字段优先于同名变量.要解决此问题,您有两种方法:
更改变量名。
像您在第二个查询中所做的那样,为变量名称添加前缀。