【发布时间】:2014-08-28 22:46:57
【问题描述】:
我对@987654321@ 语句的用法有疑问。有没有办法让我只用 SQL 编写以下场景而不是编写存储过程?
我试图简化案例。
myTable有4列,其值如下:
COMP1 COMP2 NO ACTIVE
0 0 4 N
4 1 Y
2 2 21 Y
3 1 1 Y
1 3 43 Y
2 1 Y
3 1 12 Y
2 2 0 Y
3 2 Y
1 1 5 N
- 我想选择值
WHERE ACTIVE = 'Y'并开始更新 它们在 NO 列中的值按COMP1, COMP2 ASC排序。 编号必须从表
WHERE ACTIVE = 'N'中的MAX(NO)值开始具有相同 COMP1 和 COMP2 的行将具有相同的 NO 值。
(评论后更新)NO 列并不总是 NULL。此列中存在错误值,需要更新查询进行更正。
这样,UPDATE 语句执行后,myTable 将如下(如果我们订购的话)
COMP1 COMP2 NO ACTIVE
0 0 4 N
1 1 5 N
1 3 6 Y
2 1 7 Y
2 2 8 Y
2 2 8 Y
3 1 9 Y
3 1 9 Y
3 2 10 Y
4 1 11 Y
我想知道是否可以在不需要选择整个列表并在存储过程中循环访问 CURSOR 的情况下做到这一点。
(更新:我写了SP,简化版如下,可能有问题,因为我改了所有名字,删除了很多条件。)
PROCEDURE updateAllNo
IS
CURSOR c1
IS
SELECT *
FROM MyTable SE
WHERE SE.ACTIVE = 'Y'
ORDER BY SE.COMP1, SE.COMP2;
v_last_no NUMBER := 0;
v_last_comp2 DATE := SYSDATE + 100;
v_last_comp1 DATE := SYSDATE + 100;
v_now_comp2 DATE := SYSDATE;
v_now_comp1 DATE := SYSDATE;
BEGIN
SELECT MAX (SE.NO)
INTO v_last_no
FROM MyTable SE
WHERE SE.ACTIVE = 'N';
SELECT MAX (SE.COMP1), MAX (SE.COMP2)
INTO v_last_comp1, v_last_comp2
FROM MyTable SE
WHERE SE.ISLEMBASARILI = 'E'
AND SE.NO = v_last_no;
FOR r1 IN c1
LOOP
BEGIN
v_now_comp2 := r1.COMP2;
v_now_comp1 := r1.COMP1;
IF v_now_comp2 != v_last_comp2 OR v_now_comp1 != v_last_comp1
THEN
v_last_no := v_last_no + 1;
END IF;
UPDATE MyTable SE
SET SE.NO = v_last_no
WHERE SEQ_ID = r1.seq_id;
v_last_comp2 := v_now_comp2;
v_last_comp1 := v_now_comp1;
END;
END LOOP;
COMMIT;
END;
我正在使用 Oracle 11g。
【问题讨论】:
标签: sql oracle sql-update