oracle 9i 我自己写的一个函数 如下 出的问题是返回的有效数据只有100条 (有效数据是指 经过函数处理过的)
PS:写的很烂 但是还是可以用的 急 啊~~ 求大神帮助
CREATE OR REPLACE FUNCTION F_GETCHNOTE(CHCODE IN VARCHAR2)
  RETURN VARCHAR2 IS
  RECHCODE   VARCHAR2(4000);
  NEWCODE    VARCHAR2(4000);
  LENNEWCODE NUMBER(10, 2); 
  
BEGIN
  LENNEWCODE := LENGTH(TRIM(CHCODE));
  
  IF LENNEWCODE > 2 THEN 
  NEWCODE := SUBSTR(trim(CHCODE),LENNEWCODE-1,LENNEWCODE);
  ELSE 
  NEWCODE := '';
  END IF;
  
  IF LENGTH(NEWCODE)>0 THEN
     IF LENGTHB(SUBSTR(NEWCODE,1,1))<2 THEN
        RECHCODE := SUBSTR(CHCODE,0,LENNEWCODE-1)||SUBSTR(NEWCODE,1,1);
        IF LENGTHB(SUBSTR(NEWCODE,2,1))<2 THEN
           RECHCODE := TRIM(CHCODE);
        ELSE
           RECHCODE := SUBSTR(CHCODE,0,LENNEWCODE-1);
        END IF;
     ELSE
        RECHCODE := SUBSTR(CHCODE,0,LENNEWCODE-2);
     END IF;
  ELSE
     RECHCODE := TRIM(CHCODE);
  END IF;
  RETURN(TRIM(RECHCODE));
END ;

解决方案 »

  1.   

    CHCODE数据是两头为中文中间为英文和数字的字符串 我要把这个字符串结尾的中文去掉 (是一个字或两个字)
    我要达到的目的就是这样的 
      

  2.   

    CREATE OR REPLACE FUNCTION F_GETCHNOTE(CHCODE IN VARCHAR2)
      RETURN VARCHAR2 IS
      RECHCODE   VARCHAR2(4000);
      NEWCODE    VARCHAR2(4000);
      LENNEWCODE NUMBER(10, 2); 
      
    BEGIN
      LENNEWCODE := LENGTH(TRIM(CHCODE));--获取原字符长度
      
      IF LENNEWCODE > 2 THEN 
      NEWCODE := SUBSTR(trim(CHCODE),LENNEWCODE-1,LENNEWCODE);--截取后两位字符,赋值给newcode
      ELSE 
      NEWCODE := '';
      END IF;
      
      IF LENGTH(NEWCODE)>0 THEN--判断newcode字符的长度
         IF LENGTHB(SUBSTR(NEWCODE,1,1))<2 THEN--判断newcode第一位是几个字节(汉字是两个字节)
            RECHCODE := SUBSTR(CHCODE,0,LENNEWCODE-1)||SUBSTR(NEWCODE,1,1);
            IF LENGTHB(SUBSTR(NEWCODE,2,1))<2 THEN--判断newcode第二位是几个字节
               RECHCODE := TRIM(CHCODE);
            ELSE
               RECHCODE := SUBSTR(CHCODE,0,LENNEWCODE-1);
            END IF;
         ELSE
            RECHCODE := SUBSTR(CHCODE,0,LENNEWCODE-2);
         END IF;
      ELSE
         RECHCODE := TRIM(CHCODE);
      END IF;
      RETURN(TRIM(RECHCODE));
    END ;
      

  3.   

    oracle 9i 啊 哥 亲哥  不支持的。。
      

  4.   


     
      NEWCODE := SUBSTR(trim(CHCODE),-2,2);--直接截取最后2个字符 如果字符串不满足2个字符 会返回空
      --然后判断NEWCODE是有什么字符组成
      IF  LENGTHB(NEWCODE)=2  --2个非中文    都保留
      IF  LENGTHB(NEWCODE)=3  --最后一个中文 去掉
      IF  LENGTHB(NEWCODE)=4  --2个中文      都去掉
      
     
      

  5.   


    CREATE OR REPLACE FUNCTION F_GETCHNOTE(CHCODE IN VARCHAR2)
      RETURN VARCHAR2 IS
      RECHCODE   VARCHAR2(4000);
      NEWCODE    VARCHAR2(4000);
      LENNEWCODE NUMBER(10,2); 
      
    BEGIN
      LENNEWCODE := LENGTH(TRIM(CHCODE));
      NEWCODE := SUBSTR(trim(CHCODE),-2,2);
      
      IF LENGTHB(NEWCODE)=2 THEN
         RECHCODE := TRIM(CHCODE);
      ELSIF LENGTHB(NEWCODE)=3 THEN
         RECHCODE := SUBSTR(TRIM(CHCODE),1,LENNEWCODE-1);
      ELSIF LENGTHB(NEWCODE)=4 THEN
         RECHCODE := SUBSTR(TRIM(CHCODE),1,LENNEWCODE-2);
      ELSE RECHCODE := TRIM(CHCODE);
      END IF;
      RETURN(TRIM(RECHCODE));
    END ;
    更改如上 逻辑明显清晰了 但是 仍未解决 只计算100条数据的命运。是否是权限的问题呢??
    感谢HJ_daxian帮助 能在帮忙看看吗
      

  6.   

    我的思路:
    你的规则:
    CHCODE数据是两头为中文中间为英文和数字的字符串 我要把这个字符串结尾的中文去掉 (是一个字或两个字)
    我要达到的目的就是这样的
    那就SUBSTR截取后2位,利用LENGTHB和LENGTH的差异……
    前者比后者大2,则2个汉字,
    前者比后者大1,则1个汉字,
    前者比等于后者,则0个汉字,
    create or replace function FUNC_SUB(CHCODE varchar2) return varchar2 is
    RECHCODE   varchar2(4000);
    NEWCODE    varchar2(4000);
    LENNEWCODE number(10, 2);
    begin
    LENNEWCODE := LENGTH(trim(CHCODE)); if LENNEWCODE > 2 then
    NEWCODE := SUBSTR(trim(CHCODE), LENNEWCODE - 1, 2); 
    else
    NEWCODE := '';
    end if;
    if ((LENGTHB(NEWCODE) - LENGTH(NEWCODE)) = 2) then
    RECHCODE := SUBSTR(trim(CHCODE), 1, LENNEWCODE - 2);
    elsif (LENGTHB(NEWCODE) - LENGTH(NEWCODE) = 1) then
    RECHCODE := SUBSTR(trim(CHCODE), 1, LENNEWCODE - 1);
    else
    RECHCODE := trim(CHCODE);
    end if; return(RECHCODE);
    end FUNC_SUB;
      

  7.   

    能算出结果的 只有一百条 不管数据传进去多少条 只有100  select F_GETCHNOTE(t.1)
    from t_table t
    where rownum < 111
      

  8.   

    回复xpingping  你的逻辑也没问题  好用 我试了  但是 和我出同样的问题 不管传进去多少条数据 只计算前100条 我确定不是逻辑上的问题 可能是权限不够 这方面我不太懂。
      

  9.   

    返回的只有100? 目测的符合条件的数据大概多少?  select count(*) from t_table 返回多少呢? 如果是权限的话  可以设定只返回100? 可以问下数据库管理的看看你的操作权限是不是都有  
      

  10.   


    select regexp_replace('北京ab!·#¥%……—*()——+|}{“:?》《cdefghijklm世纪nopqrstuvwxyz★!@#$%^&*()_+|}{":?><m,./kl;o[]=-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789轻,型。越,.野汽车','[^[:alpha:]]|[a-z,A-Z]','') as result 
    from dual这个是支持正则表达式的 oracle 10g 查出中文的语句 (来源于网络) 
    9i 蛋痛啊
      

  11.   

    select count(*) from t_table 查的话大概上万条数据 考虑到时效 就没查那么多条 
    返回的只有100? 目测的符合条件的数据大概多少? --这个符合条件的就是你查出数据的前100条 101以后返回空值。。可以问下数据库管理的看看你的操作权限是不是都有--小公司 哪有dba管这个。。但是 我试过 同表空间的其他函数 查询正常 只有我这个是只计算100条 
    下班了 我晚上再来
      

  12.   


     这是要查询出所有的中文哇  10g可用 ps:蛋疼砸了吧
      

  13.   


    CREATE OR REPLACE FUNCTION F_GETCHNOTE(CHCODE IN VARCHAR2)
      RETURN VARCHAR2 IS
      RECHCODE   VARCHAR2(4000);
      NEWCODE    VARCHAR2(4000);
      LENNEWCODE NUMBER(10,2); 
      
    BEGIN
    /*  LENNEWCODE := LENGTH(TRIM(CHCODE));
      NEWCODE := SUBSTR(trim(CHCODE),-2,2);*/--第二次注释
      
    /*  IF LENGTHB(NEWCODE)=2 THEN
         RECHCODE := TRIM(CHCODE);
      ELSIF LENGTHB(NEWCODE)=3 THEN
         RECHCODE := SUBSTR(TRIM(CHCODE),1,LENNEWCODE-1);
      ELSIF LENGTHB(NEWCODE)=4 THEN
         RECHCODE := SUBSTR(TRIM(CHCODE),1,LENNEWCODE-2);
      ELSE RECHCODE := TRIM(CHCODE);
      END IF;*/--第一次注释
      
      RECHCODE :=CHCODE;
      RETURN(RECHCODE);
      --RETURN(TRIM(RECHCODE));
    END ;为了排除逻辑上 或者语法上的错误导致 计算结果只有100的现象 我特别分两次注释了运算逻辑 并直接将传进的参数返回  但是  仍然只有100条返回 其他为空 至此 排除 逻辑和语法错误 正在分析是否为权限问题
    各位高人 望指点迷津  谢~~~~~~~~
      

  14.   

    问题找到了:
        我忽视了提取数据的那张表的字段为NVARCHAR2类型 而我在函数定义参数和变量时用的是VARCHAR2类型 我在网上查了下VARCHAR2和NVARCHAR2的区别 大概是明白什么意思了 但是具体导致的原因有待进一步验证!问题回顾:
        问题:表中有一列数据为两头有中文中间是英文和数字的数据,要求去除尾部中文(尾部中文包含空格情况,会有一个字,两个字的情况)。
        方案:通过length()和lengthb()对中文返回数的不通解决。
        遇到的问题:函数只能计算前100条数据(假设传进的数据大于100条),其他数据返回空。
    PS:我认为在存储过程中或许也能出现这种情况 请各位朋友注意区分类型
    以下: 我分别贴出VARCHAR2和NVARCHAR2的简单区别 和 我更正后的函数 
        
        区别:(来源于网络)
    Oralce官方文档“Datatypes”部分对NVARCHAR2、VARCHAR2以及VARCHAR有一段描述,可以清晰得到它们的区别。罗列在此,供大家参考。
    【链接】http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements001.htm#sthref71NVARCHAR2 DatatypeThe NVARCHAR2 datatype is a Unicode-only datatype. When you create a table with an NVARCHAR2 column, you supply the maximum number of characters it can hold. Oracle subsequently stores each value in the column exactly as you specify it, provided the value does not exceed the maximum length of the column.The maximum length of the column is determined by the national character set definition. Width specifications of character datatype NVARCHAR2 refer to the number of characters. The maximum column size allowed is 4000 bytes. Please refer to Oracle Database Globalization Support Guide for information on Unicode datatype support.VARCHAR2 DatatypeThe VARCHAR2 datatype specifies a variable-length character string. When you create a VARCHAR2 column, you supply the maximum number of bytes or characters of data that it can hold. Oracle subsequently stores each value in the column exactly as you specify it, provided the value does not exceed the column's maximum length of the column. If you try to insert a value that exceeds the specified length, then Oracle returns an error.You must specify a maximum length for a VARCHAR2 column. This maximum must be at least 1 byte, although the actual string stored is permitted to be a zero-length string (''). You can use the CHAR qualifier, for example VARCHAR2(10 CHAR), to give the maximum length in characters instead of bytes. A character is technically a code point of the database character set. CHAR and BYTE qualifiers override the setting of the NLS_LENGTH_SEMANTICS parameter, which has a default of bytes. For performance reasons, Oracle recommends that you use the NLS_LENGTH_SEMANTICS parameter to set length semantics and that you use the BYTE and CHAR qualifiers only when necessary to override the parameter. The maximum length of VARCHAR2 data is 4000 bytes. Oracle compares VARCHAR2 values using nonpadded comparison semantics.To ensure proper data conversion between databases with different character sets, you must ensure that VARCHAR2 data consists of well-formed strings. See Oracle Database Globalization Support Guide for more information on character set support.VARCHAR DatatypeDo not use the VARCHAR datatype. Use the VARCHAR2 datatype instead. Although the VARCHAR datatype is currently synonymous with VARCHAR2, the VARCHAR datatype is scheduled to be redefined as a separate datatype used for variable-length character strings compared with different comparison semantics.【注意】
    VARCHAR2是Oracle提供的特定数据类型,Oracle可以保证VARCHAR2在任何版本中该数据类型都可以向上和向下兼容。
    VARCHAR在Oracle中不建议使用。具体到NVARCHAR2和VARCHAR2的区别,从使用角度来看区别在于:NVARCHAR2在计算长度时和字符集相关的,例如数据库是中文字符集时以长度10为例,则1、NVARCHAR2(10)是可以存进去10个汉字的,如果用来存英文也只能存10个字符。2、而VARCHAR2(10)的话,则只能存进5个汉字,英文则可以存10个。  

    更正后函数CREATE OR REPLACE FUNCTION F_GETCHNOTE(CHCODE IN NVARCHAR2)
      RETURN NVARCHAR2 IS
      RECHCODE   NVARCHAR2(4000);
      NEWCODE    NVARCHAR2(4000);
      LENNEWCODE NUMBER(10,2); 
      
    BEGIN
      LENNEWCODE := LENGTH(TRIM(CHCODE));
      NEWCODE := SUBSTR(trim(CHCODE),-2,2);
      
      IF LENGTHB(NEWCODE)=2 THEN
         RECHCODE := TRIM(CHCODE);
      ELSIF LENGTHB(NEWCODE)=3 THEN
         RECHCODE := SUBSTR(TRIM(CHCODE),1,LENNEWCODE-1);
      ELSIF LENGTHB(NEWCODE)=4 THEN
         RECHCODE := SUBSTR(TRIM(CHCODE),1,LENNEWCODE-2);
      ELSE RECHCODE := TRIM(CHCODE);
      END IF;
      RETURN(TRIM(RECHCODE));
    END ;
    以上问题告一段落 感谢HJ_daxian使我逻辑上更清楚了 还有各位朋友的帮忙 我决定把分给HJ_daxian同志 理由是头像很拉风~ 
    至此感谢各位 结贴