通过与逗号分隔列表进行比较来选择列值的功能

时间:2018-10-13 09:55:35

标签: sql arrays postgresql parameter-passing

我想用逗号分隔的字符串与列值进行比较。

我执行了以下操作,但未返回预期结果。 ll = '"Java,CPP"'正在动态发展。

create or replace function testing(ll text)
returns void as
$body$
Declare

       foo text[];
       ko text[];
BEGIN
       select unique_code into foo from codings
       where  unique_code = ANY (regexp_split_to_array(ll, '\,'));
       raise info '%',foo;
END;
$body$
Language plpgsql;

我遇到了错误

ERROR:  column "Java,CPP" does not exist
LINE 1: SELECT "Java,CPP"
               ^
QUERY:  SELECT "Java,CPP"
CONTEXT:  PL/pgSQL function testing() line 8 at assignment

ll的值像上面一样动态地变化,现在在我有'Java'和'Cpp'的行中也返回NULL,这两个值都是大小写匹配的。

select unique_code from codings;

unique_code
  Java
  Python
  CPP
  C
  Haskell

我也尝试过修剪,但是没有用。更新的代码在这里:

create or replace function testing(ll text)
returns void as
$body$
Declare

       foo text[];
       --ll text;
       ko text[];
       oo text;
BEGIN
      --oo := replace(ll,'"','');
      raise info '%',regexp_split_to_array(trim(both '"' from ll), '\,');
      ko := regexp_split_to_array(trim(both '"' from ll), '\,');

       ---ll := "CH-PREP,CH-PRMB";
       --select(regexp_split_to_array(ll, '\|')) into ko;
        --foo := array(select unique_key from membership_map);
       select  unique_code into foo from codings where  unique_code = ANY(ko);
       raise info '%',foo;
       --raise info '%', ko;
END;
$body$
Language plpgsql;

然后:

select testing('"Java,CPP"');

ERROR: malformed array literal: "Java"
DETAIL: Array value must start with "{" or dimension information
CONTEXT: PL/pgSQL function testing(text) line 16 at SQL statement

2 个答案:

答案 0 :(得分:1)

您需要使用TRIM从您的"值中剥离ll

select unique_code 
from codings 
where unique_code = ANY (regexp_split_to_array(trim(both '"' from '"Java,CPP"'), '\,'));

输出示例数据:

unique_code
Java
CPP

SQLFiddle demo

您还有一个问题,就是要在一个语句中分配多个值,为此您需要使用ARRAY运算符。更改

select unique_code into foo from codings where unique_code = ANY(ko);

select array(select unique_code from codings where unique_code = ANY(ko)) into foo;

答案 1 :(得分:1)

您遇到第一个错误:

ERROR:  column "Java,CPP" does not exist

...在 函数调用 中的字符串文字周围缺少单引号。喜欢

SELECT testing("Java,CPP");  -- missing ''!

您可能想修剪输入中的双引号,因此调用实际上应该是:

SELECT testing('Java,CPP');

相关:

在修复了 call 的情况下,函数主体中的数据类型不匹配导致了潜伏错误。您尝试将unique_code text分配给foo text[]

ERROR: malformed array literal: "Java" 

例如,这将起作用:

CREATE OR REPLACE FUNCTION testing(_ll text[])  -- taking array of text
  RETURNS text[] AS
$func$
DECLARE
   foo text[];
BEGIN
   foo := ARRAY(  -- array constructor
      SELECT unique_code 
      FROM   codings
      WHERE  unique_code = ANY(_ll)
      );

   RETURN foo;
END
$func$  LANGUAGE plpgsql;

致电:

SELECT testing('{Java,CPP}');  -- note syntax of array literal

请参阅:

传递有效数组文字还可避免进行昂贵且不必要的regexp_split_to_array()调用。 (Regexp函数功能强大但相对昂贵。)

VARIADIC 功能相同:

CREATE OR REPLACE FUNCTION testing(VARIADIC _ll text[])
...  -- rest as above

您仍然可以在调用中使用关键字VARIADIC传递数组文字(或真实的数组值):

SELECT testing(VARIADIC '{Java,CPP}'); -- with array

或者您可以传递元素值列表(最多100个):

SELECT testing('Java','CPP');          -- with list of values

相关:


如果您绝对必须以原始格式传递字符串,请trim()加上双引号,并使用便宜得多的string_to_array()而不是{ {1}}:

regexp_split_to_array()

致电:

CREATE OR REPLACE FUNCTION testing(_ll text)
  RETURNS text[] AS
$func$
DECLARE
   foo text[];
BEGIN
   foo := ARRAY(
      SELECT unique_code 
      FROM   codings
      WHERE  unique_code = ANY(string_to_array(trim(_ll, '"'), ','))
      );

   RETURN foo;
END
$func$  LANGUAGE plpgsql;

此外:请勿使用神秘的SELECT testing('"Java,CPP"'); -- even with enclosing double quotes 作为参数名称。容易误读为ll ...