【问题标题】:Select IDs that match all items on table选择与表中所有项目匹配的 ID
【发布时间】:2017-01-25 22:57:48
【问题描述】:

所以我有一张名为 Mroom 的桌子,看起来像这样:

CREATE Mroom(ID_ROOM NUMBER(3), CHAR_NAME NVARCHAR2(30), CHAR_VALUE NUMBER(20));

表格的内容类似于:

1;冷气机; 1

1;水池; 2

2;水池; 1

这意味着 ID 为 1 的房间有 1 台空调和 2 个游泳池。 ID 2 的房间有一个游泳池。 我还创建了一个数据类型的表,我称之为 c_chars

CREATE OR REPLACE TYPE c_chars FORCE IS OBJECT (CHAR VARCHAR2(20), VALUE NUMBER(30));
/
CREATE OR REPLACE TYPE tab_chars FORCE IS TABLE OF c_chars;
/

而且我需要知道例如是否有任何房间至少有 1 台空调和一个游泳池。我当前的代码:

CREATE OR REPLACE PROCEDURE thisRoomOK(v_carateristicas IN tab_chars, lista OUT SYS_REFCURSOR)
IS BEGIN
OPEN lista FOR SELECT MRoom.ID_ROOM
FROM Mroom, TABLE(v_carateristicas) v_carateristicas
WHERE Mroom.CHAR_NAME = v_carateristicas.CHAR
AND Mroom.VALUE >= v_carateristicas.VALUE
GROUP BY Mroom.ID_ROOM
ORDER BY getSalas.Mroom.ID_ROOM;
END;
/

问题是如果我要求的房间至少有一个空调和一个游泳池。它将返回我两个房间,因为 rrom 2 有一个游泳池(它像 OR 一样工作,但我希望它像 AND 一样工作)。 p>

编辑 1:

如果可能的话,我希望收到改变程序的答案,但不是表格,尽管欢迎所有答案!

编辑 2:

上面的代码是简化的,这是完整的代码:

对象定义:

CREATE OR REPLACE TYPE c_valor FORCE IS OBJECT (CARATERISTICA VARCHAR2(20), VALOR NUMBER(30));
/
CREATE OR REPLACE TYPE tabc_valor FORCE IS TABLE OF c_valor;
/

程序:

CREATE OR REPLACE PROCEDURE getSalas_Carateristicas(v_carateristicas IN tabc_valor, lista OUT SYS_REFCURSOR)
IS BEGIN
OPEN lista FOR SELECT getSalas.ID_SALA
FROM getSalas, TABLE(v_carateristicas) v_carateristicas
WHERE getSalas.NOME_CARATERISTICA = v_carateristicas.CARATERISTICA
AND getSalas.VALOR >= v_carateristicas.VALOR
GROUP BY getSalas.ID_SALA
ORDER BY getSalas.ID_SALA;
END;
/

根据@XING的建议修改程序:

CREATE OR REPLACE PROCEDURE getSalas_Carateristicas(v_carateristicas IN tabc_valor, lista OUT SYS_REFCURSOR)
IS BEGIN
OPEN lista FOR SELECT getSalas.ID_SALA
FROM getSalas
INNER JOIN TABLE(v_carateristicas) v_carateristicas ON getSalas.NOME_CARATERISTICA = v_carateristicas.CARATERISTICA
AND getSalas.VALOR >= v_carateristicas.VALOR
GROUP BY getSalas.ID_SALA
ORDER BY getSalas.ID_SALA;
END;
/

【问题讨论】:

  • 看来您需要在group by 之后添加having 子句 - 如果您正在寻找两个特征(空调和游泳池),您需要having count(*) = 2。也就是说,将为该房间选择两行:第一行是因为它至少具有所需数量的空调,第二行是因为它至少具有所需数量的游泳池。一般来说,2 应该是tab_chars 中的特征数(?“字符”)。
  • @mathguy。放有并不能解决问题。问题取决于 OP 如何要求房间。他传递的所有价值观。
  • @mathguy,你是什么意思?
  • @Safirah ..你的问题没有解决,你按照我说的方法试过了吗。
  • @XING,是的,我试过了,但没用,chat.stackoverflow.com/rooms/134070/…

标签: sql oracle stored-procedures plsql


【解决方案1】:

我想问题出在你要求房间的方式上。请参阅下面的演示和内联说明。

过程:

CREATE OR REPLACE TYPE T541682.c_chars FORCE IS OBJECT (v_CHAR VARCHAR2(20), v_VALUE NUMBER(30));
/

CREATE OR REPLACE TYPE T541682.tab_chars FORCE IS TABLE OF c_chars;

/
    CREATE OR REPLACE PROCEDURE T541682.thisRoomOK (
       v_carateristicas      IN     tab_chars,
       lista                 OUT SYS_REFCURSOR)
    IS
    BEGIN
       OPEN lista FOR
            SELECT MRoom.ID_ROOM
              FROM Mroom 
              inner join TABLE (v_carateristicas) v_carateristicas
              ON     Mroom.CHAR_NAME = v_carateristicas.v_CHAR
             AND     Mroom.CHAR_VALUE = v_carateristicas.v_VALUE
          GROUP BY Mroom.ID_ROOM     
          ORDER BY Mroom.ID_ROOM;



END;
/


declare

var tab_chars :=tab_chars();

type var1 is table of MRoom.ID_ROOM%type index by pls_integer;

var_out var1;

x sys_refcursor;

begin

 var.extend(3);

 -- This is the way i populate my object for which i want to match with the table. Am sure you are passing all rows same as your table hence its getting the all the rows.

 var(1) := c_chars('air-conditioner',1);
 var(2) := c_chars('pool',2);

 -- Must be populating the third row as well. And as per your query both rows wil be picked up if you populate the object .

 --var(3) := c_chars('pool',1);

 -- Calling your procedure 

 thisRoomOK(v_carateristicas => var,lista => x);

 fetch x bulk collect into var_out ;

 --- displaying number of room
 for i in 1..var_out.count
  loop
    dbms_output.put_line('Room Number - '||var_out(i));
  end loop;  

 ---passing the sys_refcursor result to another procedure

  proc1(var_out);

end;

输出:

SQL> /
Room Number - 1

PL/SQL procedure successfully completed.

【讨论】:

  • 但是,如果有几个房间符合特征,那会起作用吗?例如,如果我要一个带空调的房间,会出现 2 个房间吗?而且我不想要dbms_ouput,因为另一个程序将使用输出值
  • 不..它不会显示 2 个房间,因为您的桌子 Mroom 没有 2 个带空调的房间。它将充当与通过条件的另一个表匹配的表。我用 dbms_ouput 来给你举个例子。你可以按照自己的方式使用它。你可以试试看是否有效
  • 是的,对不起,我指的是游泳池。
  • 您正在传递 2 个值并在查询中使用它。如果两个条件都满足,那么只有你会得到排。所以在所示的情况下,它只会返回一个。试一试,让我知道
  • 我会的,但是你能给我一些关于如何转换它以便过程返回光标的建议吗?
猜你喜欢
  • 2014-10-30
  • 2022-09-30
  • 2013-04-05
  • 2021-09-14
  • 2016-06-01
  • 1970-01-01
  • 2011-04-04
  • 2017-12-20
相关资源
最近更新 更多