PLSQL 需要 REFCURSOR DATE + TIME
PLSQL Need REFCURSOR DATE + TIME
我正在使用这段代码,我遇到了 1 个问题,o_besteltijden 游标将其作为输出:01-06-15(一个日期),但我更喜欢这样的输出:16:00(所以只有时间)或 01-06-15 16:00:00(日期 + 时间)。那可能吗?
SET SERVEROUTPUT ON;
CREATE OR REPLACE TYPE t_openingstijd IS TABLE OF DATE;
CREATE OR REPLACE PROCEDURE zoekMogelijkeBesteltijden(p_winkelId IN INTEGER, p_datum IN DATE, p_periode IN INTEGER DEFAULT 21, p_bezorgen IN BOOLEAN,
o_open OUT BOOLEAN, o_besteltijden OUT SYS_REFCURSOR)
AS
v_foundWinkel NUMBER := 0;
v_winkel Winkel%ROWTYPE;
TYPE arrayVarchar IS VARRAY(7) OF VARCHAR2(2);
v_dagen arrayVarchar := arrayVarchar('ma', 'di', 'wo', 'do', 'vr', 'za', 'zo');
CURSOR v_openingstijden(p_id IN NUMBER, p_dag IN VARCHAR2) IS
SELECT * FROM Openingstijd
WHERE winkel_id = p_id
AND dag = p_dag;
v_besteltijden t_openingstijd := t_openingstijd();
v_eindUur NUMBER := 0;
v_eindMinuten NUMBER := 0;
v_beginUur NUMBER := 0;
v_beginMinuten NUMBER := 0;
-- Exceptions
v_winkelNotFound EXCEPTION;
BEGIN
-- Kijken of winkel wel bestaat.
SELECT COUNT(1) INTO v_foundWinkel
FROM Winkel
WHERE id = p_winkelId;
IF(v_foundWinkel = 0) THEN
RAISE v_winkelNotFound;
END IF;
-- Alle data krijgen van de winkel. Exclusief de openingstijden, producten en coupons.
SELECT * INTO v_winkel
FROM Winkel
WHERE id = p_winkelId;
FOR i_tijd IN v_openingstijden(p_winkelId,
v_dagen(TO_NUMBER(TO_CHAR(p_datum, 'D')))) LOOP
-- Instellen van huidige tijd om mee door te lopen.
v_eindUur := TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'HH24'));
IF(p_bezorgen = true) THEN
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 30) THEN
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 15) THEN
v_eindMinuten := 30;
ELSE
v_eindMinuten := 45;
END IF;
v_eindUur := v_eindUur - 1;
ELSE
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 45) THEN
v_eindMinuten := 0;
ELSE
v_eindMinuten := 15;
END IF;
END IF;
ELSE
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 15) THEN
v_eindMinuten := 45;
v_eindUur := v_eindUur - 1;
ELSE
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 30) THEN
v_eindMinuten := 0;
ELSIF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 45) THEN
v_eindMinuten := 15;
ELSE
v_eindMinuten := 30;
END IF;
END IF;
END IF;
-- Begin tijd berekenen
v_beginUur := TO_NUMBER(TO_CHAR(i_tijd.open, 'HH24'));
IF(TO_NUMBER(TO_CHAR(i_tijd.open, 'MI')) < 15) THEN
v_beginMinuten := 0;
ELSIF(TO_NUMBER(TO_CHAR(i_tijd.open, 'MI')) < 30) THEN
v_beginMinuten := 15;
ELSIF(TO_NUMBER(TO_CHAR(i_tijd.open, 'MI')) < 45) THEN
v_beginMinuten := 30;
ELSE
v_beginMinuten := 45;
END IF;
-- Eerste uur vol maken.
IF(v_beginMinuten != 0) THEN
FOR i IN 1 .. ((60 - v_beginMinuten) / 15) LOOP
v_besteltijden.extend;
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':' || v_beginMinuten * i, 'HH24:MI');
END LOOP;
v_beginUur := v_beginUur + 1;
v_beginMinuten := 0;
END IF;
-- Tot het laatste uur volmaken.
IF(v_beginUur != v_eindUur) THEN
FOR x IN 1 .. (v_eindUur - v_beginUur) LOOP
FOR i IN 1 .. 4 LOOP
v_besteltijden.extend;
IF(i = 1) THEN
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':00', 'HH24:MI');
ELSE
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':' || 15 * (i - 1), 'HH24:MI');
END IF;
END LOOP;
v_beginUur := v_beginUur + 1;
END LOOP;
END IF;
-- Laatste uur ook maar eens volmaken.
IF(v_beginUur = v_eindUur AND v_eindMinuten >= v_beginMinuten) THEN
FOR i IN 1 .. (v_eindMinuten / 15) + 1 LOOP
v_besteltijden.extend;
IF(i = 1) THEN
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':00', 'HH24:MI');
ELSE
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':' || 15 * (i - 1), 'HH24:MI');
END IF;
END LOOP;
END IF;
END LOOP;
-- Data terug in output cursor.
OPEN o_besteltijden FOR
SELECT * FROM TABLE(CAST(v_besteltijden AS t_openingstijd));
-- Is de winkel momenteel open?
FOR i_openingstijd IN v_openingstijden(p_winkelId,
v_dagen(TO_NUMBER(TO_CHAR(SYSDATE, 'D')))) LOOP
IF(o_open = true) THEN
IF(TO_NUMBER(TO_CHAR(SYSDATE, 'HH24MI')) >= TO_NUMBER(TO_CHAR(i_openingstijd.open, 'HH24MI'))
AND TO_NUMBER(TO_CHAR(SYSDATE, 'HH24MI')) <= TO_NUMBER(TO_CHAR(i_openingstijd.gesloten, 'HH24MI'))) THEN
o_open := true;
ELSE
o_open := false;
END IF;
END IF;
END LOOP;
EXCEPTION
WHEN v_winkelNotFound THEN
dbms_output.put_line('Winkel niet gevonden.');
END;
/
这里的问题好像是这样的:
您正在将 o_besteltijden
设置为从 CAST(v_besteltijden AS t_openingstijd)
中选择的值,其中 v_besteltijden
是根据 to_date
[=30 计算得出的=]
t_openingstijd
是日期类型 (CREATE OR REPLACE TYPE t_openingstijd IS TABLE OF DATE;
) 的 table。所以你的答案将采用日期格式。
相反,如果您需要 timestamp
类型,则必须对这些变量进行更改并在其中存储 timestamp 以获得所需的输出 date+time or time through formatting.
我正在使用这段代码,我遇到了 1 个问题,o_besteltijden 游标将其作为输出:01-06-15(一个日期),但我更喜欢这样的输出:16:00(所以只有时间)或 01-06-15 16:00:00(日期 + 时间)。那可能吗?
SET SERVEROUTPUT ON;
CREATE OR REPLACE TYPE t_openingstijd IS TABLE OF DATE;
CREATE OR REPLACE PROCEDURE zoekMogelijkeBesteltijden(p_winkelId IN INTEGER, p_datum IN DATE, p_periode IN INTEGER DEFAULT 21, p_bezorgen IN BOOLEAN,
o_open OUT BOOLEAN, o_besteltijden OUT SYS_REFCURSOR)
AS
v_foundWinkel NUMBER := 0;
v_winkel Winkel%ROWTYPE;
TYPE arrayVarchar IS VARRAY(7) OF VARCHAR2(2);
v_dagen arrayVarchar := arrayVarchar('ma', 'di', 'wo', 'do', 'vr', 'za', 'zo');
CURSOR v_openingstijden(p_id IN NUMBER, p_dag IN VARCHAR2) IS
SELECT * FROM Openingstijd
WHERE winkel_id = p_id
AND dag = p_dag;
v_besteltijden t_openingstijd := t_openingstijd();
v_eindUur NUMBER := 0;
v_eindMinuten NUMBER := 0;
v_beginUur NUMBER := 0;
v_beginMinuten NUMBER := 0;
-- Exceptions
v_winkelNotFound EXCEPTION;
BEGIN
-- Kijken of winkel wel bestaat.
SELECT COUNT(1) INTO v_foundWinkel
FROM Winkel
WHERE id = p_winkelId;
IF(v_foundWinkel = 0) THEN
RAISE v_winkelNotFound;
END IF;
-- Alle data krijgen van de winkel. Exclusief de openingstijden, producten en coupons.
SELECT * INTO v_winkel
FROM Winkel
WHERE id = p_winkelId;
FOR i_tijd IN v_openingstijden(p_winkelId,
v_dagen(TO_NUMBER(TO_CHAR(p_datum, 'D')))) LOOP
-- Instellen van huidige tijd om mee door te lopen.
v_eindUur := TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'HH24'));
IF(p_bezorgen = true) THEN
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 30) THEN
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 15) THEN
v_eindMinuten := 30;
ELSE
v_eindMinuten := 45;
END IF;
v_eindUur := v_eindUur - 1;
ELSE
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 45) THEN
v_eindMinuten := 0;
ELSE
v_eindMinuten := 15;
END IF;
END IF;
ELSE
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 15) THEN
v_eindMinuten := 45;
v_eindUur := v_eindUur - 1;
ELSE
IF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 30) THEN
v_eindMinuten := 0;
ELSIF(TO_NUMBER(TO_CHAR(i_tijd.gesloten, 'MI')) < 45) THEN
v_eindMinuten := 15;
ELSE
v_eindMinuten := 30;
END IF;
END IF;
END IF;
-- Begin tijd berekenen
v_beginUur := TO_NUMBER(TO_CHAR(i_tijd.open, 'HH24'));
IF(TO_NUMBER(TO_CHAR(i_tijd.open, 'MI')) < 15) THEN
v_beginMinuten := 0;
ELSIF(TO_NUMBER(TO_CHAR(i_tijd.open, 'MI')) < 30) THEN
v_beginMinuten := 15;
ELSIF(TO_NUMBER(TO_CHAR(i_tijd.open, 'MI')) < 45) THEN
v_beginMinuten := 30;
ELSE
v_beginMinuten := 45;
END IF;
-- Eerste uur vol maken.
IF(v_beginMinuten != 0) THEN
FOR i IN 1 .. ((60 - v_beginMinuten) / 15) LOOP
v_besteltijden.extend;
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':' || v_beginMinuten * i, 'HH24:MI');
END LOOP;
v_beginUur := v_beginUur + 1;
v_beginMinuten := 0;
END IF;
-- Tot het laatste uur volmaken.
IF(v_beginUur != v_eindUur) THEN
FOR x IN 1 .. (v_eindUur - v_beginUur) LOOP
FOR i IN 1 .. 4 LOOP
v_besteltijden.extend;
IF(i = 1) THEN
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':00', 'HH24:MI');
ELSE
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':' || 15 * (i - 1), 'HH24:MI');
END IF;
END LOOP;
v_beginUur := v_beginUur + 1;
END LOOP;
END IF;
-- Laatste uur ook maar eens volmaken.
IF(v_beginUur = v_eindUur AND v_eindMinuten >= v_beginMinuten) THEN
FOR i IN 1 .. (v_eindMinuten / 15) + 1 LOOP
v_besteltijden.extend;
IF(i = 1) THEN
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':00', 'HH24:MI');
ELSE
v_besteltijden(v_besteltijden.count) := TO_DATE( v_beginUur || ':' || 15 * (i - 1), 'HH24:MI');
END IF;
END LOOP;
END IF;
END LOOP;
-- Data terug in output cursor.
OPEN o_besteltijden FOR
SELECT * FROM TABLE(CAST(v_besteltijden AS t_openingstijd));
-- Is de winkel momenteel open?
FOR i_openingstijd IN v_openingstijden(p_winkelId,
v_dagen(TO_NUMBER(TO_CHAR(SYSDATE, 'D')))) LOOP
IF(o_open = true) THEN
IF(TO_NUMBER(TO_CHAR(SYSDATE, 'HH24MI')) >= TO_NUMBER(TO_CHAR(i_openingstijd.open, 'HH24MI'))
AND TO_NUMBER(TO_CHAR(SYSDATE, 'HH24MI')) <= TO_NUMBER(TO_CHAR(i_openingstijd.gesloten, 'HH24MI'))) THEN
o_open := true;
ELSE
o_open := false;
END IF;
END IF;
END LOOP;
EXCEPTION
WHEN v_winkelNotFound THEN
dbms_output.put_line('Winkel niet gevonden.');
END;
/
这里的问题好像是这样的:
您正在将
[=30 计算得出的=]o_besteltijden
设置为从CAST(v_besteltijden AS t_openingstijd)
中选择的值,其中v_besteltijden
是根据to_date
t_openingstijd
是日期类型 (CREATE OR REPLACE TYPE t_openingstijd IS TABLE OF DATE;
) 的 table。所以你的答案将采用日期格式。
相反,如果您需要 timestamp
类型,则必须对这些变量进行更改并在其中存储 timestamp 以获得所需的输出 date+time or time through formatting.