Я нашел аккуратный способ в стеке потока обработки многопеременной инструкции case
с использованием значений ROW.Здорово, как чисто это выглядит ...
Однако я получаю ошибки, непосредственно сравнивая значение строки из 2 столбцов таблицы типа text
со строкой из строковых литералов.
IЯ использовал обходной путь с функцией spTup('Deposit', '' )
, которая работает, но может быть медленнее.Другой способ, который работает, это явное приведение строковых литералов к text
, но это создает много визуальных помех.
Вопросы:
- ПочемуPostgres не может сделать вывод, что строковые литералы должны обрабатываться как
text
тип? - Почему Postgres может выводить тип строкового литерала в строке одного элемента, но не в строке с 2 элементами?
- Мне показалось, что я справляюсь с обработкой типов в Postgres, но я не совсем понимаю этот сценарий, кто-нибудь может объяснить?
- Есть ли другой подход, который минимизирует визуальный беспорядок?
Я использую Postgres 10.1 на локальном хосте и 9.6.6 на тестовом и производственном сервере.
Тестовая настройка:
create table if not exists tblTest ( SeqID serial, EventType text, EventResult text, Amt decimal );
truncate table tblTest;
insert into tblTest( EventType, EventResult, Amt )
values ( 'Withdrawal', '', 1.11 ), ('Deposit', '', 2.22 ), ('Deposit', 'succeeded', 3.33 ), ('Deposit', 'failed', 4.44 );
create or replace function spTup( p_1 text, p_2 text )
returns record as $func$
select ( p_1, p_2 );
$func$ LANGUAGE sql IMMUTABLE;
-- Runs without error (using single element tuple)
select SeqID, EventType, case ( EventType ) when ( 'Deposit' ) then Amt else 9.999 end
from tblTest;
-- ERROR: cannot compare dissimilar column types text and unknown at record column 1
select SeqID, EventType, EventResult, case ( EventType, EventResult )
when ( 'Deposit', '' ) then Amt else 9.999 end
from tblTest;
-- Runs without error -- visually the cleanest apart from using spTup function
select SeqID, EventType, EventResult, case ( EventType, EventResult )::text
when ( 'Deposit', '' )::text then Amt else 9.999 end
from tblTest;
-- Runs without error
select SeqID, EventType, EventResult, case ( EventType, EventResult )
when ( 'Deposit'::text, ''::text ) then Amt else 9.999 end
from tblTest;
select SeqID, EventType, EventResult, case ( EventType, EventResult )
when spTup( 'Deposit', '' ) then Amt else 9.999 end
from tblTest;
-- ERROR: input of anonymous composite types is not implemented
select SeqID, EventType, EventResult, case ( EventType, EventResult )
when '( "Deposit", "" )' then Amt else 9.999 end
from tblTest;
-- Just out of interest
select ( 'Deposit', '' ), ( 'Deposit'::text, ''::text );
/**
row row
(Deposit,"") (Deposit,"")
**/
select SeqID, EventType, EventResult, ( EventType, EventResult )
from tblTest;
/**
seqid eventtype eventresult row
1 Withdrawal (Withdrawal,"")
2 Deposit (Deposit,"")
3 Deposit succeeded (Deposit,succeeded)
4 Deposit failed (Deposit,failed)
**/