Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle Shortname函数工作不正常_Oracle_Plsql - Fatal编程技术网

Oracle Shortname函数工作不正常

Oracle Shortname函数工作不正常,oracle,plsql,Oracle,Plsql,有以下代码可用于从MMSTREPHDR表生成唯一的shortname。 我已经在MMSTREPHDR中有了短名称kv,kv1,kv2,kv3。但在传递参数kv时,它会给我kv1,而不是kv4(因为它在循环中)。不知道怎么了 FUNCTION FUN_GENERATE_SNAME (p_name VARCHAR2) RETURN VARCHAR2 IS vl_sname VARCHAR2 (15); n_cnt NUMBER := 1; vl_sub NUMB

有以下代码可用于从MMSTREPHDR表生成唯一的shortname。 我已经在MMSTREPHDR中有了短名称
kv
kv1
kv2
kv3
。但在传递参数kv时,它会给我
kv1
,而不是
kv4
(因为它在循环中)。不知道怎么了

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;

您将下面的语句连接为

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

在上面的代码中,n_cnt的初始值为1,这就是为什么它将您的值取为KV1。您应该将其保持为null,after语句应该在循环中将其递增1。希望有用

您的起始参数为“kv”。这是传递给光标的内容。因此,光标将选择一行,即
mmstreph.repsname='kv'
所在的行

因此,循环逻辑将执行一次。所以
cnt
=
。因此
vl_sname`变为“kv1”,这是循环完全退出时得到的值


解决这个问题的最干净的方法是承认
mmstreph.repsname
是一个智能钥匙,由两个元素组成:子系统名称和报告编号。将该列拆分为两列可以轻松找到给定子系统的下一个报告编号。您甚至可以将复合值保留为虚拟列(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||'%'
警告-我还没有测试过这个功能,所以括号可能无法正确配对。

试试这个功能

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;

您的循环只运行一次。所以,你得到的n_cnt为1。仅此评论就足以回答我的问题。