【问题标题】:Split a Linestring with Delimiters使用分隔符拆分线串
【发布时间】:2014-11-25 16:30:14
【问题描述】:

我有一个包含许多二进制形式坐标的数据库,例如 “ 01020020E61000000000000000000007495792B40D7CFFC208249494069999999B9A9B79B79B79B792B4055555555555556724940238949E89E1AD1BB4237A2237A2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 d.1 d222 b.

我使用 St_AsText 将其转换为 LineString。 我得到类似的东西

“线串((3.584731 60.739211,3.590472 60.738030,3.592740 60.736220))”

我需要将这个 LineString WITH Delimiters 拆分到一个洞 PL/pgSQL-Function 中。 我的第一个拆分将有分隔符','。

结果是

3.584731 60.739211 3.590472 60.738030 3.592740 60.736220

我的第二个分隔符是“”,所以我可以得到每一个点。我知道它很愚蠢,但它需要这样做。它是我公司大学的一个测试项目。 现在我可以用 3.590472*60.738030+3.592740 -60.736220 等点进行计算。

我的问题是将这个漏洞进程放在 PL/pgSQL 函数中,因为我对语言的语法有很大的问题。如果有人可以写一个示例函数,我将非常感激:)

【问题讨论】:

    标签: string split plpgsql


    【解决方案1】:

    你不需要开发新功能 - PostgreSQL 有很好的功能 - string_to_array(string, delimiter)

    postgres=> select string_to_array('1.0 2.0 3.2', ' ');
     string_to_array 
    -----------------
     {1.0,2.0,3.2}
    (1 row)
    
    postgres=> select * from  unnest(string_to_array('1.0 2.0 3.2', ' '));
     unnest 
    --------
     1.0
     2.0
     3.2
    (3 rows)
    

    在 plpgsql 中解析字符串是错误的想法——一些对较长字符串的操作可能会很慢。而且没有必要。 Postgres 具有解析数组、xml、json 的功能,并且(在必要时)您可以使用regular expressions

    postgres=> select * from regexp_split_to_table('1.0 2.0   3.3', e'\\s+');
     regexp_split_to_table 
    -----------------------
     1.0
     2.0
     3.3
    (3 rows)
    
    postgres=> select v[1] from regexp_matches('1.0 2.0   3.3', '[0-9]+\.[0-9]+','g') r(v);
      v  
    -----
     1.0
     2.0
     3.3
    (3 rows)
    

    PL/pgSQL 中一些简单的拆分字符串实现:

    postgres=# \sf split_string 
    CREATE OR REPLACE FUNCTION public.split_string(text, text)
    RETURNS SETOF text
    LANGUAGE plpgsql
    AS $function$
    DECLARE 
      pos int; 
      delim_length int := length($2);
    BEGIN
      WHILE $1 <> ''
      LOOP
        pos := strpos($1, $2);
        IF pos > 0 THEN
          RETURN NEXT substring($1 FROM 1 FOR pos - 1);
          $1 := substring($1 FROM pos + delim_length);
        ELSE
          RETURN NEXT $1;
          EXIT;
        END IF; 
      END LOOP;
      RETURN;
    END;
    $function$
    
    postgres=# select * from split_string('AHOJ NAZDAR BAZAR',' ');
     split_string 
    --------------
     AHOJ
     NAZDAR
     BAZAR
    (3 rows)
    

    【讨论】:

    • 首先谢谢你!我知道这是一个坏主意,但它是一个测试,我们想将 PL/pgSQL-Function 与 extern C-Function 进行比较。所以我需要 PL/pgSQL-Function :(
    • 我更新了我的回复——但又一次——它是错误的 plpgsql 用法和错误的基准。
    • 你是我的坏蛋英雄 :)))
    • 您将如何使用 PL/pgSQL 和外部 C-Function 进行基准测试?
    • 你必须在你的工作中选择一个可以在PLpgSQL中正常实现的过程。人工基准确实令人困惑。示例:我在 plpgsql 中实现了快速排序。对于大型数组,它比 C 内部快速排序实现慢 1000 倍。这个基准有什么好处。绝对零度。没有好心人会使用 plpgsql 函数进行排序。 PLpgSQL 是 SQL 操作的完美粘合剂——因为瓶颈是 SQL 操作。速度可与 PHP 媲美。但是对于密集的数字(字符串)操作,任何人都应该使用 PLPython 或 PLPerl 或 C。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 2018-02-27
    • 2011-09-11
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多