0
点赞
收藏
分享

微信扫一扫

查字符类型转换date类型值时报错“ORA-00904: "GET_INTERNAL_VALUE": invalid identifier”

问题描述:查字符类型转换date类型值时报错“ORA-00904: "GET_INTERNAL_VALUE": invalid identifier”,如下所示:
数据库:oracle 11.2.0.4
1、异常重现
SYS@orcl> select get_internal_value('DF2304290000748902') from dual;
select get_internal_value('DF2304290000748902') from dual
       *
ERROR at line 1:
ORA-00904: "GET_INTERNAL_VALUE": invalid identifier
2、解决过程
SYS@orcl> CREATE OR REPLACE FUNCTION get_internal_value(p_value IN VARCHAR2)
  RETURN VARCHAR2 IS
  FOR i IN 1 .. 15 LOOP
  temp_n NUMBER := 0;
              ASCII(SUBSTR(RPAD(p_value, 15, CHR(0)), i, 1));
BEGIN
  RETURN TO_CHAR(ROUND(temp_n, -21));
  FOR i IN 1 .. 15 LOOP
  WHEN OTHERS THEN
    temp_n := temp_n + POWER(256, 15 - i) *
END get_internal_value;
              ASCII(SUBSTR(RPAD(p_value, 15, CHR(0)), i, 1));
  END LOOP;
  RETURN TO_CHAR(ROUND(temp_n, -21));
EXCEPTION
  WHEN OTHERS THEN
    RETURN p_value;
END get_internal_value;
 14  /

Function created.

SYS@orcl> select get_internal_value('DF2304290000748902') from dual;

GET_INTERNAL_VALUE('DF2304290000748902')
----------------------------------------------------------------------
354499932302760000000000000000000000

3、拓展知识
--创建get_external_value函数.
CREATE OR REPLACE FUNCTION get_external_value(p_value IN VARCHAR2)
  RETURN VARCHAR2 IS
  temp_n    NUMBER;
  temp_i    INTEGER;
  my_result VARCHAR2(32767) := NULL;
BEGIN
  IF LENGTH(p_value) <> 36 OR
     SUBSTR(p_value, 16) <> '000000000000000000000' OR
     p_value > POWER(256, 15) OR p_value < POWER(256, 14) THEN
    RETURN p_value; -- cannot get external value
  END IF;
  temp_n := p_value / POWER(256, 14); -- get most significant digits
  -- decoding most significant digits then shift multiplying by 256
  FOR i IN 1 .. 14 LOOP
    temp_i := TRUNC(temp_n);
    temp_n := (temp_n - temp_i) * 256;
    IF temp_i NOT BETWEEN 32 AND 126 OR temp_n NOT BETWEEN 32 AND 126 THEN
      EXIT; -- reached the tail
    END IF;
    my_result := my_result || CHR(temp_i); -- all but last byte
  END LOOP;
  IF temp_i NOT BETWEEN 32 AND 126 THEN
    RETURN my_result || '?'; -- cannot decode
  END IF;
  -- scan to the right starting at temp_i
  FOR i IN temp_i .. 126 LOOP
    IF get_internal_value(my_result || CHR(i)) = p_value THEN
      RETURN my_result || CHR(i); -- approximate value
    END IF;
  END LOOP;
  -- scan to the left starting at temp_i
  FOR i IN 32 .. temp_i LOOP
    IF get_internal_value(my_result || CHR(temp_i + 32 - i)) = p_value THEN
      RETURN my_result || CHR(temp_i + 32 - i); -- approximate value
    END IF;
  END LOOP;
  RETURN my_result || CHR(temp_i); -- this is the best we could do
EXCEPTION
  WHEN OTHERS THEN
    RETURN p_value;
END get_external_value;
/

SYS@orcl> select get_internal_value('2022-05-31') a,get_internal_value('2022-06-02') b from dual

A                                                B
---------------------------------------- ----------------------------------------
260592375524722000000000000000000000     260592375524722000000000000000000000

注意:对于varchar2类型的字段保留日期记录,跨月查询可能会导致执行计划异常.
参考网址:https://blog.51cto.com/hunt1574/5462623

举报

相关推荐

0 条评论