【问题标题】:HANA: Split string?HANA:拆分字符串?
【发布时间】:2014-12-30 16:35:30
【问题描述】:

有没有办法在HANA中拆分字符串?

类似于 SQL Server 中的等效项:SELECT * FROM dbo.fnSplitString('valueA,valueB', ',')

【问题讨论】:

  • 不是真的...这是所有 SQL 变体中非常常见的请求,答案很简单。因为HANA SQL没有自带函数,所以需要用户自己编写。因为我知道人们最终会在 StackOverflow 上搜索这个功能,所以我认为提出这个问题会很好。
  • 然后将此评论的一些内容添加到您的厌食问题中。会得到更好的回应。
  • 如果我问了同样的问题,但说的是 C# 而不是 HANA,那么每个人都会直观地知道我在这里要求什么。我看不出这个问题的问题。

标签: sql hana


【解决方案1】:

试试这个,

Refer Here

CREATE PROCEDURE SPLIT_TEST(TEXT nvarchar(100))
AS
BEGIN
  declare _items nvarchar(100) ARRAY;
  declare _text nvarchar(100);
  declare _index integer;
  _text := :TEXT;
  _index := 1;

  WHILE LOCATE(:_text,',') > 0 DO
  _items[:_index] := SUBSTR_BEFORE(:_text,',');
  _text := SUBSTR_AFTER(:_text,',');
  _index := :_index + 1;
  END WHILE;
  _items[:_index] := :_text;

  rst = UNNEST(:_items) AS ("items");
  SELECT * FROM :rst;
END; 

CALL SPLIT_TEST('A,B,C,E,F')

【讨论】:

  • 感谢您的可用代码 :) 如何在另一个函数中使用输出?仍然没有更简单的方法来做到这一点?
【解决方案2】:

另一种拆分字符串的方法是使用表类型使用出站变量:

CREATE TYPE UTIL_VARCHAR_LIST AS TABLE
(
    VarcharValue Varchar(5000)
);

CREATE PROCEDURE UTIL_SPLIT_STRING
(
    IN iv_split_string Varchar(5000),
    IN iv_split_character Varchar(1) DEFAULT ',',
    OUT ot_string_list UTIL_VARCHAR_LIST
) LANGUAGE SQLSCRIPT
AS
BEGIN
    DECLARE TEMP_STR VARCHAR(5000) := :iv_split_string || :iv_split_character;
    DECLARE OUT_VAR VARCHAR(5000) ARRAY;
    DECLARE POS INTEGER :=1;
    DECLARE FLAG INTEGER := 1;
    DECLARE LEFT_STR VARCHAR(5000);

    WHILE(LENGTH(:TEMP_STR) > 0 )
    DO
        LEFT_STR := SUBSTR_BEFORE (:TEMP_STR,:iv_split_character);
        TEMP_STR := SUBSTR_AFTER (:TEMP_STR,:LEFT_STR || :iv_split_character);
        OUT_VAR[POS] := LEFT_STR;
        POS := :POS + 1;
    END WHILE;

    ot_string_list = UNNEST(:OUT_VAR) AS ("VARCHARVALUE");
END;

【讨论】:

    【解决方案3】:

    在 SP10 之前,您需要创建一个 SPLIT 字符串的函数。

    • 如果你需要一些字符,你可以使用 SUBSTR()

    • 在 SP9 或更高版本上,您可以使用 REGEX

    【讨论】:

      【解决方案4】:

      我知道这个问题有点老了,但我从来没有找到一个好的解决方案。 所以我为此创建了一个 Table UDF,我认为这比为此调用一个过程要好,因为您不需要创建附加变量。 好了,代码就到这里,希望对你有帮助!

      感谢 Peder Rice,因为我只修改了他的代码。干杯!

          FUNCTION "TF_SPLIT_STRING" 
      (
          i_string nvarchar(255)
      ) 
          RETURNS table(type char(1), value nvarchar(255))
          LANGUAGE SQLSCRIPT
          SQL SECURITY INVOKER AS
      BEGIN
          --> DECLARATIONS
          -- The remaining string after checking for the delimiter
          declare v_remaining VARCHAR(256)    := :i_string;
          -- The current vale that is being handled
          declare v_current   VARCHAR(255)    := '';
      
          -- The current positions of the resulting arrays
          declare v_pos_include   INTEGER := 1;
          declare v_pos_exclude   INTEGER := 1;
      
          -- The arrays containing the results
          declare a_include   VARCHAR(12) array := ARRAY(0);
          declare a_exclude   VARCHAR(12) array := ARRAY(0);
      
          -- The delimiter and the excluder
          declare v_delimiter char(1) := ',';
          declare v_excluder char(1) := '-';
      
          --> SETUP BLOCK
          if substr(:v_remaining, length(:v_remaining), 1) <> :v_delimiter
          then
              v_remaining := :v_remaining || :v_delimiter;
          end if;
      
          --> EXECUTION BLOCK
          --  While there is a string to process
          --      ->  Split the string into the current value and the remaining
          --      ->  Check if there is an excluder character in the current value
          --      ->  If an excluder character is found, push the current value, 
          --          without the excluder, to the resulting array of excluding values
          --      ->  If no excluder is found, push the value to the resulting array
          --          of including values
          --      ->  The corresponding position variable is incremented accordingly
          while( LENGTH(:v_remaining) > 0 )
          do
              v_current := SUBSTR_BEFORE (:v_remaining,:v_delimiter);
              v_remaining := SUBSTR_AFTER (:v_remaining, :v_current || :v_delimiter);
      
              if substring(:v_current, 1, 1) = :v_excluder
              then
                  a_exclude[v_pos_exclude] := SUBSTR_AFTER (:v_current, :v_excluder);
                  v_pos_exclude := :v_pos_exclude + 1;
      
              else
                  a_include[v_pos_include] := v_current;
                  v_pos_include := :v_pos_include + 1;
      
              end if;
          end while;
      
          --> ASSIGNMENTS BLOCK
          -- format counter and divisions as table
          o_include = unnest(:a_include) AS ("VALUE");
          o_exclude = unnest(:a_exclude) AS ("VALUE");
      
          return 
              select  'I' as type, value from :o_include
              union all
              select  'E' as type, value from :o_exclude
              ;
      
      END;
      

      【讨论】:

        【解决方案5】:

        使用 SUBSTR_REGEXPR 函数的解决方案。我上周在 Hana 中将它用作 Script_View 并且可以确认它有效。

        Begin
        VAR_OUT =
            select *
            from ( select
            ST.PARAM, -- Source table id
            NT.Element_Number, -- Occurrence number within source table row
        SUBSTR_REGEXPR( '([;])([^;]*)(?=;)'
        IN   CONCAT(CONCAT(';',ST.VALUE),';')
             OCCURRENCE NT.Element_Number
            GROUP 2
            ) splitted      -- string piece
        from 
        "_SYS_BIC"."Financial_Planning_and_Analysis/ZZTPARPAR_SOURCE" as ST, -- source  table
        SERIES_GENERATE_INTEGER(1, 0, 10 ) as NT -- numbers table
            ) tbl
        where splitted is not null
        order by PARAM, Element_Number;
        End     
        

        Before and After

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-28
          • 2014-05-27
          相关资源
          最近更新 更多