Функция для выбора значений столбцов путем сравнения со списком через запятую - PullRequest
0 голосов
/ 13 октября 2018

Я хочу сравнить строку с разделителями-запятыми со значениями столбцов.

Я сделал следующее, что не возвращает ожидаемый результат.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 приходит динамически, как указано выше, и теперь оновернуть NULL также в строке у меня есть «Java» и «Cpp», оба значения в соответствующем регистре.

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 голосов
/ 13 октября 2018

Вы получили первую ошибку:

ERROR:  column "Java,CPP" does not exist

... за пропущенные одинарные кавычки вокруг строкового литерала в функции звоните .Как и

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

Вы, вероятно, хотите обрезать эти двойные кавычки из входных данных, поэтому вызов должен быть действительно:

SELECT testing('Java,CPP');

Связанный:

При фиксированном вызове ошибка скрывается из-за несоответствия типов данных в функциитело наносит удар.Вы пытаетесь назначить 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() звонок.(Функции регулярного выражения являются мощными, но сравнительно дорогими.)

или аналогично 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() вместо 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 в качестве имени параметра.Легко неправильно истолковывается как 11 ...

0 голосов
/ 13 октября 2018

Вам нужно использовать 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

У вас также есть проблема в том, что вы назначаете несколько значений в одном операторе, для чего вам нужно использовать оператор 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;
...