PostgreSQL 9.3: подготовка динамической строки

Я хочу подготовить динамическую строку, используя функцию.

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

Пример:

У меня есть строка string1, которая будет передана функции. И string2 присутствует в функции.

В функции присутствует одна строка string2:

string2 = 'A1,A2,A3,A4'

И строку string1 я передаю функции:

string1 = 'A1'

Тогда ожидаемая подготовленная строка должна выглядеть так:

A1 = 1 AND A2 IS NULL AND A3 IS NULL AND A4 IS NULL

Для приведенного выше результата я написал следующую функцию:

CREATE OR REPLACE FUNCTION f_test(string1 varchar)
RETURNS VOID AS
$$
DECLARE
    string2 varchar = 'A1,A2,A3,A4';
    string3 varchar;
    string4 varchar;
    string5 varchar;
    string6 varchar;
BEGIN
    string3 := REPLACE(string1,',',' = 1 AND ')||' = 1';

    RAISE INFO '%',string3;

    string4 := REPLACE(string2,string1,string3);

    RAISE INFO '%',string4; 

    string5 := REPLACE(string4,'1,',' 1 AND ');

    string6 := REPLACE(string5,',', ' IS NULL AND ')||' IS NULL ';

    RAISE INFO '%',string6; 
END;
$$
LANGUAGE PLPGSQL;

Вызов ФУНКЦИЯ

SELECT f_test('A1');

Результат: (правильно)

A1 =  1 AND A2 IS NULL AND A3 IS NULL AND A4 IS NULL 

Но застрял при проходе A4

SELECT f_test('A4');

Результат:(Неправильно)

A 1 AND A2 IS NULL AND A3 IS NULL AND A4 =  1 

Пока я ждал:

A1 IS NULL AND A2 IS NULL AND A3 IS NULL AND A4 =  1 

Если я позвоню:

SELECT f_test('A2,A4');

Тогда результат должен быть:

A1 IS NULL AND A2 = 1 AND A3 IS NULL AND A4 =  1 

person MAK    schedule 20.03.2015    source источник


Ответы (1)


Попробуй это

CREATE OR REPLACE FUNCTION f_test(string1 varchar)
RETURNS VOID AS
$$
DECLARE
    string2 varchar = 'A1,A2,A3,A4,A5,A6,A7';
    string3 varchar;
    string4 varchar;
    string5 varchar;
    string6 varchar;
    intCount int;
BEGIN
    string3 := REPLACE(string1,',',' = 1 AND ')||' = 1';

    RAISE INFO '%',string3;

    string4 := REPLACE(string2,string1,string3);

    RAISE INFO '%',string4; 
select string_agg(c,' AND ') into  string6 from (
select  * from (
select c ||'= 1' c from (
select regexp_split_to_table(string2,',') c
)t 
where c in (select regexp_split_to_table(string1,','))
union all 
select c ||' IS NULL ' c from (
select regexp_split_to_table(string2,',') c
)t 
where  c  not in (select regexp_split_to_table(string1,','))
) t group by c order by c 
)t;
    RAISE INFO '%',string6; 
END;
$$
LANGUAGE PLPGSQL;

Звоните : - select f_test('A3,A5') или select f_test('A3,A5,A2,A6')

person Vivek S.    schedule 20.03.2015
comment
AND нет. Пожалуйста, пройдите еще раз. - person MAK; 20.03.2015
comment
@MAK ты проверил мой ответ ?? - person Vivek S.; 20.03.2015
comment
Я ожидаю вывод, как A1 IS NULL AND A2 IS NULL AND A3 IS NULL AND A4 = 1 . - person MAK; 20.03.2015
comment
@MAK о, я скоро исправлю :D - person Vivek S.; 20.03.2015
comment
И еще кое-что. Вы использовали regexp_split_to_table('1,2,3,4', ',')::INT c1 в своем сценарии. Но я получаю string2 из другой таблицы, которая не исправлена. - person MAK; 20.03.2015
comment
@MAK вы можете пройти string2 вот так regexp_split_to_table(string2 , ',')::INT c1 , - person Vivek S.; 20.03.2015
comment
Просто попробуйте свой сценарий, передав еще одно значение в string2 в разделе объявлений. Это A1,A2,A3,A4,A5. - person MAK; 20.03.2015
comment
Давайте продолжим обсуждение в чате. - person MAK; 20.03.2015
comment
@MAK Just try your script by passing one more value in string2 at the declaration section. That is A1,A2,A3,A4,A5 О да, но вы должны указать все подробности в своем вопросе, - person Vivek S.; 20.03.2015
comment
@unique_I'd, извините за поздний ответ. Просто проверьте, передав «A3, A5». - person MAK; 20.03.2015
comment
Пожалуйста, проверьте выбор f_test('A3,A5'). - person MAK; 20.03.2015
comment
@MAK Я работал именно с тем, что вы упомянули в OP, но вы даете больше информации. после каждого обновления.Так запутался - person Vivek S.; 20.03.2015
comment
Ой! Я очень сожалею об этом. Это последнее испытание. - person MAK; 20.03.2015
comment
@MAK можно ли передать как select f_test('A1','A5') вместо select f_test('A1,A5'), если да я могу быстро дать вам ответ - person Vivek S.; 20.03.2015
comment
Ой! Итак, вы хотите передать два параметра для этого? - person MAK; 20.03.2015
comment
@MAK О! Итак, вы хотите передать для этого два параметра? › Я так не думаю :D !! - person Vivek S.; 20.03.2015