Код SAS в PostgreSQL (PADB) - поле суммирования, если оно существует - PullRequest
0 голосов
/ 29 августа 2018

У меня проблема с фрагментом кода из SAS, который мне нужно преобразовать в SQL. Обычно я очень хорош в этом, но верно, я не сталкиваюсь с новым вызовом, и пока все мои идеи по его решению проваливаются, и я не нахожу правильный способ сделать это.

Мне нужно иметь возможность динамически выбирать поле для этого запроса, например, если поле имеет определенный шаблон в имени, мне нужно суммировать эти поля.

моя версия PostgreSQL - 8.0.2, PADB 5.3.3.1 78560

Таким образом, таблица может иметь или не иметь поле типа bas_txn_03cibc_vcl.

Я написал функцию, которая должна выводить ' ' as bas_txn_03cibc_vcl, когда поле не найдено в таблице information_schema, и использовать bas_txn_03cibc_vcl, если найден.

Но когда я выполняю команду, я получаю сообщение об ошибке, что UDF нельзя использовать в таблицах PADB.

«ОШИБКА: XX000: определяемая пользователем функция языка SQL« check_if_field_exists (изменение символа, изменение символа, изменение символа) »не может использоваться в запросе, который ссылается на таблицы PADB."

Прямо сейчас я создаю новый подход с использованием хранимой процедуры, но он ограничит вариант использования. Любая другая идея о том, как я могу выбрать поле динамически?

Функция:

CREATE OR REPLACE FUNCTION check_if_field_exists(_schm text, _tbl text, _field text)
RETURNS text AS
$BODY$
DECLARE 
    _output_ text:=  '' as _field;
BEGIN 
EXECUTE   'SELECT column_name into : _output_ FROM rdwaeprd.information_schema.columns 
where table_schema='''|| _schm||'''   
and table_name='''|| _tbl||'''   
and column_name='''|| _field||'''   
order by table_name,column_name;';  
RETURN _output_;
END
$BODY$
LANGUAGE PLPGSQL;

и тогда я бы использовал это так

select indiv_id,ae_psamson.check_if_field_exists('ae_psamson','activ_cc', 'tot_txn_03AMX_AMXE') ,tot_txn_03AMX_AMXD
from activ_cc
group by indiv_id,tot_txn_03AMX_AMXD;

Если функция будет возвращать '' как tot_txn_03AMX_AMXE, или просто tot_txn_03AMX_AMXE .... идея состоит в том, чтобы запрос не возвращал ошибку, если поле не существует.

Как я уже сказал, мне нужна новая функция или подход, так как этот не работает ...

1 Ответ

0 голосов
/ 04 сентября 2018

Мне удалось сделать функцию, которая заставит ее работать! В основном одна из проблем в том, что эта информационная схема использовала неподдерживаемую функцию в UDF. Это решение отлично работает:

CREATE OR REPLACE FUNCTION check_if_field_exists(_schm text, _tbl text, _field text)
RETURNS varchar(55)  AS
$BODY$
DECLARE 
    _output_ varchar(55) :=' 0 as '|| _field;
--  name := (SELECT t.name from test_table t where t.id = x);
BEGIN 
EXECUTE  'drop table if exists col_name';
EXECUTE  'create table col_name as SELECT att.attname::character varying(128) AS colname   
FROM pg_class cl, pg_namespace ns, pg_attribute att 
WHERE cl.relnamespace = ns.oid AND cl.oid = att.attrelid AND ns.nspname='''|| _schm ||''' 
and cl.relname='''|| _tbl ||''' 
and colname like '''|| _field||''''; -- INTO _output_;
select colname from col_name into _output_ ;  
if _output_ is null then 
_output_  :=' 0 as '|| _field;
end if;
RETURN _output_  ;
END 
$BODY$
LANGUAGE PLPGSQL;
...