我们有一个基于Oracle的系统,用于管理设备并将其详细信息和配置存储在名为“configs”的表中。每个设备由多个模块组成,每个模块的配置保存为逗号分隔的字符串。例如:
device_id module values
1 1 3,4,2,3
1 2 4,1,3,4
1 3 2,1,2,3
1 4 6,4,2,1
1 5 1,4,2,3
1 6 1,3,4,4
2 1 3,4,2,3
2 2 4,1,3,4
2 3 2,3,2,3
2 4 6,4,2,1
2 5 1,8,2,3
2 6 1,3,4,4
3 1 3,4,2,3
3 2 4,1,3,4
3 3 2,1,2,3
3 4 6,4,2,1
3 5 1,4,2,3
3 6 1,3,4,4
4 1 3,4,2,3
4 2 4,1,3,4
4 3 2,1,2,4
4 4 6,4,2,1
4 5 1,4,2,3
4 6 1,3,7,4
我需要审核系统并识别其配置与已知良好配置不匹配的每个模块。理想情况下,我想运行这样的查询,假设设备1的配置是我的好配置:
select device_id,module
from configs
where values != (select values from configs where device_id = 1)
但是这会返回错误:
ORA-01427: single-row subquery returns more than one row
如果我将查询更改为此,则可以:
select device_id,module
from configs
where values = (select values from configs where device_id = 1 and module = 1);
但是我必须为“module”的每个值运行查询。
我想做的是编写一个允许我一次性执行此操作的查询。有人暗示我可以使用游标语句,但我很难找到一个“oracle游标傻瓜”类型的文章,到目前为止,我所看到的并没有帮助我,包括http://docs.oracle.com/cd/B28359_01/server.111/b28286/expressions006.htm#SQLRF52057。有谁能提出建议?
感谢。
答案 0 :(得分:0)
模块编号是否必须匹配?即,(模块2的)模块2的配置被认为是模块3(某些其他设备)的良好配置
如果是这样,有几个好的配置(这就是db说single-row subquery returns more than one row
的原因)。你必须考虑到这一点:
select device_id, module
from configs
where values not in (select values from configs where device_id = 1)
如果没有,您必须选择与所考虑的行匹配的那个,例如:
select device_id, module
from configs c1
where values = (
select values
from configs c2
where device_id = 1
and c1.module = c2.module
)
答案 1 :(得分:0)
产生错误的查询正在尝试比较单个值上下文中的项列表。您需要将“!=”更改为“not in”,它应该可以正常工作。以下是调整后的查询:
localStorage
答案 2 :(得分:0)
如果我理解你的话,我想你可以使用这样的东西:
DECLARE
device_string VARCHAR2 (100);
BEGIN
FOR i IN (SELECT * FROM configs WHERE device_id = 1)
LOOP
SELECT listagg(device_id, ';')
WITHIN GROUP (ORDER BY device_id)
INTO device_string
FROM configs
WHERE values != i.values AND module=i.module;
DBMS_OUTPUT.PUT_LINE(
' Bad config for module ' || i.module ||
' in devices: ' || device_string);
END LOOP;
END;