0

テーブル MMSTREPHDR から一意の短い名前を生成するためのこのコードがあります。私はすでにMMSTREPHDR にショートネームkv, kv1,を持っています。しかし、パラメータ kv を渡すと、それは私に与えられ、そうでは ありません(LOOPにあるため)。何が悪いのかわからない?kv2kv3kv1kv4

FUNCTION FUN_GENERATE_SNAME (p_name VARCHAR2)
  RETURN VARCHAR2
IS
  vl_sname   VARCHAR2 (15);
  n_cnt      NUMBER := 1;
  vl_sub     NUMBER;

  CURSOR c1 (vl_sname VARCHAR2)
  IS
     SELECT   a.repsname, a.repcode
       FROM   MMSTREPHDR a
      WHERE   TRIM (UPPER (a.repsname)) = TRIM (UPPER (vl_sname));
BEGIN
  vl_sname := TRIM (SUBSTR (p_name, 1, 15));

  FOR i IN c1 (vl_sname)
  LOOP
     vl_sub := LENGTH (TO_CHAR (n_cnt));
     vl_sname := SUBSTR (vl_sname, 1, (15 - vl_sub)) || n_cnt;
     n_cnt := n_cnt + 1;
  END LOOP;

  RETURN vl_sname;
EXCEPTION
  WHEN OTHERS
  THEN
     RETURN vl_sname;
END fun_generate_sname;
4

3 に答える 3

1

開始パラメーターは「kv」です。これは、カーソルに渡すものです。したがって、カーソルは1 つの行を選択しますMMSTREPHD.repsname = 'kv'

したがって、ループ ロジックは 1 回実行されます。したがって、cnt= . Hencevl_sname` は 'kv1' になります。これは、ループが正常に終了したときに取得する値です。


MMSTREPHD.repsnameこれを修正する最も明確な方法は、サブシステム名とレポート番号の 2 つの要素で構成されるスマート キーであることを認めることです。列を 2 つの列に分割すると、特定のサブシステムの次のレポート番号を簡単に見つけることができます。複合値を仮想列 (11g 以降) として保持することも、少し面倒なトリガーで維持することもできます。

さもないと:

 select concat(p_name
             , trim(to_char(max(to_number(nvl(replace(repsname,p_name),'0')))+1)) )
 into vl_sname
 from MMSTREPHD
 where repsname like p_name||'%'

警告 - これは (まだ) テストしていないため、ブラケットが正しくペアリングされない可能性があります。

于 2013-07-26T09:09:08.853 に答える
0

この機能を試してください

function FUN_GENERATE_SNAME(p_name varchar2) return varchar2 is
    l_idx     number;
    l_name_ln := length(trim(p_name));
begin
    select max(substr(trim(UPPER(a.repsname)), 1, -length(trim(UPPER(a.repsname)) + l_name_ln)) 
      into l_idx 
      from MMSTREPHDR a 
     where substr(trim(UPPER(a.repsname)), 1, l_name_ln) = trim(UPPER(vl_sname));

    if l_idx is null then
        -- mean name is unique
        return vl_sname;
    else
        return vl_sname ||(l_idx + 1);
    end if;
exception
    when others then
        return vl_sname;
end fun_generate_sname;
于 2013-07-26T13:13:27.170 に答える
0

以下のステートメントを次のように連結しています

  vl_sname := SUBSTR (vl_sname, 1, (15 - vl_sub)) || n_cnt;

ここで、n_cnt は上記のコードで 1 として初期値が与えられます。そのため、値を KV1 として取得する必要があります。null のままにしておく必要があり、ステートメントの後にループで 1 ずつインクリメントする必要があります。希望は役に立ちます

于 2013-07-26T07:44:02.140 に答える