簡體   English   中英

選擇與表中所有項目匹配的 ID

[英]Select IDs that match all items on table

所以我有一張名為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;
/

我需要知道例如是否有任何房間至少有一台空調和一個游泳池。 我目前的代碼:

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一樣工作)。

編輯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;
/

我想問題在於你要房間的方式。 請參閱下面的演示和內聯說明。

過程:

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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM