Код SAS в PostgreSQL(PADB) - поле суммирования, если оно существует
У меня возникла проблема с фрагментом кода из 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 ответ
Мне удалось сделать функцию, которая заставит это работать! В основном одна из проблем в том, что эта информационная схема использовала неподдерживаемую функцию в 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;