[英]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一樣工作)。
如果可能的話,我希望收到改變程序的答案,而不是表格,盡管歡迎所有答案!
上面的代碼是一個簡化,這是完整的代碼:
對象定義:
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.