2017-01-28 14 views
1

与えられた日付から生まれた人の数をパラメータとして計算する関数を作成しなければなりませんでした。dateパラメータを持つ関数を正しく呼び出す方法は?

「YY/MM/DD」と書かれた生年月日のPersonという名前のテーブルがあります。

create or replace function persons_count(p_date date) RETURN NUMBER IS cnt NUMBER; 
BEGIN` 
    SELECT COUNT(*) INTO cnt FROM person 
    WHERE date_of_birth > To_Date(p_date,'dd.mm.yyyy'); 
    RETURN cnt; 
END; 

と私は、この機能を実行しようとした:次のように

機能がある

SET SERVEROUTPUT ON 

DECLARE 
    num NUMBER; 
BEGIN 
    num := persons_count('82/11/01'); 
    dbms_output.put_line(num); 
END; 

をしかし、それは動作しません。パラメータの数が有効でないか、日/月が無効であるというメッセージが表示されます。

+0

特定の日付以降に雇われている人の数が何人か探しているなら、なぜそのDOBを見ていますか? –

+0

私は間違いました。私は、特定の日付以降に生まれた人を探しています。 –

答えて

2

あなたの関数は日付パラメータを受け取りますが、文字列を渡しています。関数内では、既に日付である引数を日付に変換していますが、これはあまり意味がありません。どちらも暗黙的な変換を行うためにセッションNLS_DATE_FORMATに依存しています。機能内には、効果的にやっている:

WHERE date_of_birth > To_Date(to_char(p_date, NLS_DATE_FORMAT),'dd.mm.yyyy'); 

をコールして、あなたがやっている間、:

persons_count(to_date('82/11/01', NLS_DATE_FORMAT)); 

をあなたは幸運なら、あなたのセッションが権利を設定されますが、ここにあなたがいます競合するフォーマットに頼っているので、どちらか一方が失敗したり、予期しない回答が得られたりします。 NLSの設定に頼るべきではなく、日付を文字列に変換して戻すべきではありません。あなたが実際に>= p_dateを望むかもしれないが

create or replace function persons_count(p_date date) 
RETURN NUMBER IS 
    cnt NUMBER; 
BEGIN 
    SELECT COUNT(*) INTO cnt 
    FROM person 
    WHERE date_of_birth > p_date; 
    RETURN cnt; 
END; 

あなたはより多くのような何かをしたいです。 (4桁の年を注意してください。でも、RR書式モデル要素で、2桁の年を使用していない)

num := persons_count(to_date('1982/11/01', 'YYYY/MM/DD)); 

、またはANSIの日付リテラル:そしてなど、明示的な日付とそれを呼び出します:

num := persons_count(DATE '1982-11-01'); 

私は

を "YY/MM/DD" と書かれた誕生日の人という名前のテーブルを持っています列のデータ型がDATEの場合、列には固有の書式はありません。テーブルを照会し、そのようにフォーマットされた日付値を表示すると、NLS_DATE_FORMATはYY/MM/DDまたはRR/MM/DDになります。クライアントの設定で日付を暗黙的にフォーマットしています。それはそのように格納されていないし、クライアント/セッション設定を変更すると、それが表示される方法が変更されます。それは可能です実際には、それはフォーマットされた文字列として格納されているが、それは本当に悪い考えであり、あなたの質問は実際に日付であることを意味します。

+0

はい、表の列のデータ型はDATEです。助けてくれてありがとう、それは今すぐ働く:) –

関連する問題