2016-11-21 18 views
0
create or replace 
    FUNCTION JDT_UDC_Desc 
    (
    V_SY IN VARCHAR2, 
     V_RT IN VARCHAR2, 
     V_KY IN VARCHAR2 
    ) 
    RETURN VARCHAR2 
    AS 
     V_DL01 VARCHAR2(30); 


BEGIN 



    EXECUTE IMMEDIATE 'select drdl01 
     from PRODCTL.F0005 
       WHERE DRSY = V_SY 
    AND DRRT = V_RT 
     AND ltrim(rtrim(drky)) =ltrim(rtrim(V_KY))' 
INTO V_DL01 
using V_SY,V_RT,V_KY; 
END; 

コンパイル。私は、実行をクリックし、値の下に入力します。ORA-00904無効な識別子 - ダイナミックOracle関数

V_SY ='00', 
V_RT = '01', 
V_KY='04'; 

そして、私はエラーの下に取得

ORA-00904 V_KY無効な識別子

誰も私は、このエラーの理由を理解することはできますか?

+0

まず、ここでは動的SQLを使用する理由はありません。動的SQLに頼らざるを得ないことは稀です。静的SQLを使用すると、コードはより効率的でメンテナンス性が向上します。 –

+0

@JustinCave私は、この関数が静的変数ではなく動的変数を使用したいと考えています。値V_SY、V_RT、V_KYは動的変数です。私は静的にはうまくいくと思っていますが、アプリケーションの目的には必要です – Simi

+0

これは動的SQLを使う必要はありません。あなたが照会したいテーブルの名前または返すカラムが実行時にしか分かっていない場合は、動的SQLを使用します。静的SQLは、バインド変数の値が実行時に決定される問合せを完全に処理できます。実際、実際のアプリケーションのすべての静的SQLの99.99%は、実行時まで値がわからない変数/パラメータを使用します。 –

答えて

1

ここでは、動的SQLを使用する理由は何もないようです。動的SQLに頼ることは稀です。コードはより効率的でメンテナンス性に優れています。

create or replace 
    FUNCTION JDT_UDC_Desc 
    (
     V_SY IN VARCHAR2, 
     V_RT IN VARCHAR2, 
     V_KY IN VARCHAR2 
    ) 
    RETURN VARCHAR2 
    AS 
     V_DL01 VARCHAR2(30); 
    BEGIN 
     select drdl01 
     into V_DL01 
     from PRODCTL.F0005 
     WHERE DRSY = V_SY 
     AND DRRT = V_RT 
     AND trim(drky) =trim(V_KY); 

     return v_dl01; 
    END; 

第2に、わかりやすい変数名とわかりやすい名前の列と表を選んだ場合は、本当に役に立ちます。 F0005は、テーブルに含まれる内容については何も教えてくれません。 v_syおよびdrsyには、変数または列に含まれるものについては何も教えてくれません。これは、このコードを維持することをはるかに難しくする必要があるようにします。

+0

これらのテーブルは私によって作成されていません。このテーブルは、tablename @ dblink_instanceのようなdblinkからのみアクセスできます。私はエラー 'ORA-01403:データが見つかりませんでした'上記のコードを試しました-------------------------------- ---- 'DRDLY = '00'とDRRT = '01'とltrim(rtrim(drky))= '04''からDRDL01を選択します。これはエディタをチェックインすると1レコードを返します – Simi

+0

この関数は何とかしません実行時のV_SY、V_RT、V_KYの値 – Simi

+0

@Simi - "何とか値を取らない"よりも具体的にする必要があります。 ORA-01403:データが見つかりませんでした例外が発生した場合は、行が少なくとも実行中のセッションのコンテキスト内に存在しません。誰かがまだ別のトランザクションに行を挿入していない可能性がありますコミット。これにより、行を挿入したセッションで行が表示されますが、別のセッションには表示されません。 –

2

リテラル値 'V_SY'、 'V_RT'および 'V_KY'を文に渡しているため、それらを列名として解釈しているため、無効な識別子エラーです。

EXECUTE IMMEDIATE 'select drdl01 
      from PRODCTL.F0005 
      WHERE DRSY = :1 
      AND DRRT = :2 
      AND ltrim(rtrim(drky)) =ltrim(rtrim(:3))' 
INTO V_DL01 
using V_SY,V_RT,V_KY; 
+0

このコードではデータが見つかりません00,01,04として値を入力しました – Simi

+0

selectステートメントをこれらの値とともにコピーアンドペーストしてエディタで直接実行し、データを返すかどうかを確認してください。 – bassrek

+0

私はそれを試みた。それは1レコードを返しました – Simi

関連する問題