【问题标题】:How to split comma separated string inside stored procedure?如何在存储过程中拆分逗号分隔的字符串?
【发布时间】:2011-12-24 18:49:54
【问题描述】:

如何将逗号分隔的字符串拆分为存储过程中的字符串并将它们插入到表字段中?

使用火鸟 2.5

【问题讨论】:

    标签: sql string firebird firebird2.5


    【解决方案1】:

    这里是如何拆分字符串并将子字符串写入表格的示例:

    create procedure SPLIT_STRING (
      AINPUT varchar(8192))
    as
    declare variable LASTPOS integer;
    declare variable NEXTPOS integer;
    declare variable TEMPSTR varchar(8192);
    begin
      AINPUT = :AINPUT || ',';
      LASTPOS = 1;
      NEXTPOS = position(',', :AINPUT, LASTPOS);
      while (:NEXTPOS > 1) do
      begin
        TEMPSTR = substring(:AINPUT from :LASTPOS for :NEXTPOS - :LASTPOS);
        insert into new_table("VALUE") values(:TEMPSTR);
        LASTPOS = :NEXTPOS + 1;
        NEXTPOS = position(',', :AINPUT, LASTPOS);
      end
      suspend;
    end
    

    【讨论】:

    • 请注意:它不会为AINPUT 返回任何结果,例如',1,2',但它会为AINPUT 返回三个子字符串,例如'1,2,'
    【解决方案2】:

    我正在发布修改后的迈克尔的版本,也许它会对某人有用。

    变化是:

    1. SPLIT_STRING 是一个可选择的过程。
    2. 可以自定义分隔符。
    3. 它还解析分隔符是 P_STRING 中的第一个字符的情况。
    set term ^ ;
    create procedure split_string (
        p_string varchar(32000),
        p_splitter char(1) ) 
    returns (
        part varchar(32000)
    ) 
    as
      declare variable lastpos integer;
      declare variable nextpos integer;
    begin
        p_string = :p_string || :p_splitter;
        lastpos = 1;
        nextpos = position(:p_splitter, :p_string, lastpos);
        if (lastpos = nextpos) then
            begin
                part = substring(:p_string from :lastpos for :nextpos - :lastpos);
                suspend;
                lastpos = :nextpos + 1;
                nextpos = position(:p_splitter, :p_string, lastpos);
            end
        while (:nextpos > 1) do
            begin
                part = substring(:p_string from :lastpos for :nextpos - :lastpos);
                lastpos = :nextpos + 1;
                nextpos = position(:p_splitter, :p_string, lastpos);
                suspend;
            end
    end^
    set term ; ^
    

    【讨论】:

    • 干得好@MartjinPieters :)
    【解决方案3】:

    【讨论】:

    • 欢迎来到 Stack Overflow!虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。谢谢
    【解决方案4】:

    我使用的类似解决方案,不久前由 Jiri Cincura 发布 http://blog.cincura.net/232347-tokenize-string-in-sql-firebird-syntax/

    recreate procedure Tokenize(input varchar(1024), token char(1))
    returns (result varchar(255))
    as
    declare newpos int;
    declare oldpos int;
    begin
      oldpos = 1;
      newpos = 1;
      while (1 = 1) do
      begin
        newpos = position(token, input, oldpos);
        if (newpos > 0) then
        begin
          result = substring(input from oldpos for newpos - oldpos);
          suspend;
          oldpos = newpos + 1;
        end
        else if (oldpos - 1 < char_length(input)) then
        begin
          result = substring(input from oldpos);
          suspend;
          break;
        end
        else
        begin
          break;
        end
      end
    end
    

    【讨论】:

      【解决方案5】:

      它看起来不错,除了一件事,在我的 Firebird 服务器 Varchar 大小声明为 32000 导致“超出实施限制”异常,所以要小心。我建议改用 BLOB SUB_TYPE TEXT :)

      【讨论】:

        【解决方案6】:

        这适用于 Informix 数据库:

        DROP FUNCTION rrhh:fnc_StringList_To_Table;
        CREATE FUNCTION rrhh:fnc_StringList_To_Table (pStringList varchar(250))
            RETURNING INT as NUMERO;
        
            /* A esta Funcion le podes pasar una cadena CSV con una lista de numeros
             *      Ejem:  EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
             * y te devolvera una Tabla con dichos numeros separados uno x fila
             * Autor:  Jhollman Chacon @Cutcsa - 2019 */
        
            DEFINE _STRING VARCHAR(255);
            DEFINE _LEN INT;
            DEFINE _POS INT;
            DEFINE _START INT;
            DEFINE _CHAR VARCHAR(1);
            DEFINE _VAL INT;
        
            LET _STRING = REPLACE(pStringList, ' ', '');
            LET _START = 0;
            LET _POS = 0;
            LET _LEN = LENGTH(_STRING);
        
            FOR _POS = _START TO _LEN
                LET _CHAR = SUBSTRING(pStringList FROM _POS FOR 1);
        
                IF _CHAR <> ',' THEN 
                    LET _VAL = _CHAR::INT;
                ELSE 
                    LET _VAL = NULL;
                END IF;
        
                IF _VAL IS NOT NULL THEN 
                    RETURN _VAL WITH RESUME;
                END IF;
        
            END FOR;
        
        END FUNCTION;
        
        EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
        SELECT * FROM TABLE (fnc_StringList_To_Table('1,2,3,4'));
        

        【讨论】:

          猜你喜欢
          • 2011-04-29
          • 2014-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-24
          相关资源
          最近更新 更多