2016-12-25 8 views
2

Как я могу вернуть значение для expirydate-sysdate? Это дает мне ошибку. Может кто-нибудь мне помочь?Как создать функцию вычесть две даты?

CREATE OR REPLACE FUNCTION calc_remain_data(accountNumber account.account_number%TYPE) 
    RETURN date IS 
     CridetCardNo number(8); 
     expirydate date; 
     res date; 
    BEGIN 

     SELECT credit_card_number into CridetCardNo 
     FROM c_relation 
     WHERE account_number = accountNumber ; 

     SELECT expiry_date into expirydate 
     FROM credit_card 
     WHERE credit_card_number = CridetCardNo; 

     SELECT expirydate-SYSdate as result 
     from dual ; 

     return result ; 
    END; 
+2

Вы забыли задать вопрос. – Mureinik

+3

Почему так много операторов выбора –

ответ

1

Вы можете использовать этот

CREATE OR REPLACE FUNCTION calc_remain_data(accountNumber account.account_number%TYPE) 
RETURN number IS 
    l_CreditCardNo number(8); 
    l_expirydate date; 
    l_result number; 
BEGIN 

    SELECT credit_card_number INTO l_CreditCardNo 
    FROM c_relation 
    WHERE account_number = accountNumber ; 

    SELECT expiry_date INTO l_expirydate 
    FROM credit_card 
    WHERE credit_card_number = l_CreditCardNo; 

    l_result := l_expirydate - sysdate; 

    return l_result ; 
END; 

Editted: изменить тип возвращаемого значения, как прокомментировал

+2

'l_expirydate - sysdate' возвращает число, а не' DATE', поэтому ему нельзя назначить переменную, определенную как 'date' –

+0

Я знал, что что-то не было: D – GurV

3

Вам не нужно два различных ЗЕЬЕСТ, вы можете сделать это более эффективно с одним JOIN.

Результат вычитания одной даты из другой не является датой, а числом, представляющим количество дней между этими двумя датами. Таким образом, вы не можете назначить результат l_expirydate - sysdate переменной, заданной как DATE.

Вы не сказали нам, что именно эта функция должна возвращать. Если «оставшиеся данные» предназначается, чтобы быть дней затем определяют l_result, как number и изменить функцию, чтобы вернуть номер:

CREATE OR REPLACE FUNCTION calc_remain_data(accountNumber account.account_number%TYPE) 
    RETURN number --<< HERE 
IS 
    l_remaining_days number; --<< NOT a date! 
BEGIN 

    -- you can store the result of the calculation directly in the variable 
    SELECT cc.expiry_date - sysdate 
     INTO l_remaining_days 
    FROM c_relation cr 
    JOIN credit_card cc ON cc.credit_card_number = cr.credit_card_number 
    WHERE account_number = accountNumber; 

    return l_remaining_days; 
END; 
/
0

вы можете использовать интервального типа данных:

CREATE OR REPLACE FUNCTION CALC_REMAIN_DATA (
    ACCOUNTNUMBER ACCOUNT.ACCOUNT_NUMBER%TYPE) 
    RETURN INTERVAL DAY TO SECOND--You can specify desired type here 
IS 
    CRIDETCARDNO NUMBER (8); 
    EXPIRYDATE  DATE; 
    RES   DATE; 
BEGIN 
    SELECT CREDIT_CARD_NUMBER 
    INTO CRIDETCARDNO 
    FROM C_RELATION 
    WHERE ACCOUNT_NUMBER = ACCOUNTNUMBER; 

    SELECT EXPIRY_DATE 
    INTO EXPIRYDATE 
    FROM CREDIT_CARD 
    WHERE CREDIT_CARD_NUMBER = CRIDETCARDNO; 

    RETURN NUMTODSINTERVAL (EXPIRYDATE - SYSDATE, 'Day');--this function convert float number to interval type and has another version numtoyminterval 
               --^this specify the unit to calculate the interval 
END; 

на самом деле тип даты не поможет вам много здесь, вместо этого тип интервалов помогает получить значение разницы в две даты в {Временная секунда по часовой стрелке дня} или вы можете использовать другой тип интервала Год в месяц, который вычисляет значение в {Year Month}

Смежные вопросы