PLSQL Need REFCURSOR DATE + TIME

96 views Asked by At

im using this code and I had 1 problem, the o_besteltijden cursor has this as output: 01-06-15 ( a date), but I prefer output like: 16:00 (so only time) Or 01-06-15 16:00:00 (date + time). is that possible?

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;
/
1

There are 1 answers

0
Ajo Koshy On BEST ANSWER

The problem here seems to be as follows:

  1. You are setting o_besteltijden as a value selected from CAST(v_besteltijden AS t_openingstijd) where v_besteltijden is calculated from to_date

  2. t_openingstijd is a table of date type (CREATE OR REPLACE TYPE t_openingstijd IS TABLE OF DATE;). So your answer will be in date format.

Instead if you need the timestamp type you have to make changes to these variables and get timestamp stored in them to get the output as desired date+time or time through formatting.