2012-03-14 10 views
2

次のコードは、「28」と書かれた入力に基づいて、1つのフィールド、つまり文字列を返します。私は(代わりに28の)どんな数に渡すことができますし、機能がその選択の結果があることが判明何でも戻ってくるように私はこのうちのSQL関数を作成するにはどうすればよいパラメータを使用してSQL関数を作成するにはどうすればよいですか?

SELECT data.id, LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names 
    FROM (
    SELECT id, name, ROW_NUMBER() OVER (order by name) rownumber, COUNT(*) OVER() cnt 
     FROM (
     SELECT es.EVENT_ID as id, s.SERVICE_NAME as name FROM DT_SERVICES s 
      JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID 
     WHERE es.EVENT_ID = 28 
    ) 
) data 
WHERE rownumber = cnt 
START WITH rownumber = 1 
CONNECT BY PRIOR rownumber = rownumber-1; 

私は1つ作成しようとしましたが、私はコンパイルエラーを取得し続けます。

現在のSQL関数の作成に

create or replace function "DT_SERVICE_STRING" (id in VARCHAR2) 
    return VARCHAR2 is 
begin 
    DECLARE 
    result VARCHAR(200); 
    SELECT data.id, LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names 
    INTO result 
    FROM (
     SELECT id, name, ROW_NUMBER() OVER (order by name) rownumber, COUNT(*) OVER() cnt 
     FROM (
     SELECT es.EVENT_ID as id, s.SERVICE_NAME as name FROM DT_SERVICES s 
     JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID 
     WHERE es.EVENT_ID = id 
    ) 
) data 
    WHERE rownumber = cnt 
    START WITH rownumber = 1 
    CONNECT BY PRIOR rownumber = rownumber-1; 

    return result; 
end;​ 

エラー:
コンパイルは、失敗した7行目(午後3時22分21秒) PLS-00103:次のいずれかを期待したときにシンボルが "SELECT" が発生しました: begin関数のプラグマ・プロシージャ・サブタイプ・タイプ現在のカーソルの削除が先にある

+0

何がコンパイルエラーを起こしていますか? –

+0

Oracle Apexの関数として作成しようとしています – antonpug

+0

とはどのようなものですか、それは機能しませんか?あなたの既存の破損したコードで質問を更新してください。 –

答えて

4

SQL文から呼び出し可能なPL/SQL関数(SQLで定義された関数を持つことはできません)を想定すると、

あなただけの投稿コードに基づい
CREATE OR REPLACE FUNCTION get_conc_names(p_event_id IN dt_event_service.event_id%type) 
    RETURN VARCHAR2 
IS 
    l_conc_names VARCHAR2(32676); 
    -- You may want a smaller variable if you know the result will be smaller 
BEGIN 
    SELECT LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names 
    INTO l_conc_names 
    FROM (
     SELECT id, name, ROW_NUMBER() OVER (order by name) rownumber, COUNT(*) OVER() cnt 
     FROM (SELECT es.EVENT_ID as id, s.SERVICE_NAME as name 
       FROM DT_SERVICES s 
        JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID 
       WHERE es.EVENT_ID = p_event_id) 
     ) data 
    WHERE rownumber = cnt 
    START WITH rownumber = 1 
CONNECT BY PRIOR rownumber = rownumber-1; 
    RETURN l_conc_names; 
END; 

、あなただけでDECLAREを取り除くためにとBEGIN前とIS後にローカル変数resultの宣言を移動する必要があることが表示されます。

+0

しました。コンパイルが失敗しました。行8(15:27:25) PL/SQL:ORA-00947:値の不足コンパイルが失敗しました。行7(15:27:25) PL/SQL:SQL文が無視されました – antonpug

+0

@ antonpug - 私は私の答えを更新しました。あなたの 'SELECT'ステートメントが2つの列を選択していたことに気付かなかった。あなたは1つの値だけを返すので、実際には 'conc_names'文字列を選択する必要があると思います。 –

+0

Hm、それは変わった、同じエラーが続く。そして、ええ、私は自分自身も2つのコラムに気づいた。それは私に十分な価値がないと伝え続けます – antonpug

0

私は、解析関数が内側のインラインビューの内側にある必要があり、次に外側のインラインビューがそれらを選択できると思います。これが私がいつも行ってきた方法です。代わりにこれを試してみてください:

CREATE OR REPLACE FUNCTION get_conc_names(p_event_id IN dt_event_service.event_id%type) 
    RETURN VARCHAR2 
IS 
    l_conc_names VARCHAR2(32676); 
    -- You may want a smaller variable if you know the result will be smaller 
BEGIN 
    SELECT LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names 
    INTO l_conc_names 
    FROM ( 
     SELECT id, name, rownumber, cnt 
     FROM (SELECT es.EVENT_ID as id 
        ,s.SERVICE_NAME as name 
        ,ROW_NUMBER() OVER (order by name) as rownumber 
        ,COUNT(*) OVER() as cnt 
       FROM DT_SERVICES s 
        JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID 
       WHERE es.EVENT_ID = p_event_id) 
      ) data 
    WHERE rownumber = cnt 
    START WITH rownumber = 1 
    CONNECT BY PRIOR rownumber = rownumber-1; 
    RETURN l_conc_names; 
END; 
関連する問題