W tym poście chciałbym przedstawić dwie funkcje jakie zostały wprowadzone do PostgreSQL 16: pg_input_is_valid
oraz pg_input_error_info
Moim zdaniem ułatwiają pracę z walidacją parametrów a zwłaszcza takich, które chcemy konwertować.
Dokumentację tych funkcji znajdziesz tutaj. Tak pokrótce napiszę Ci, że obie służą do tego samego: sprawdzają czy wartość zmiennej jest wymaganego typu. pg_input_is_valid
zwraca true
(czyli boolean
😉) jeśli wartość zmiennej jest danego typu a pg_input_error_info
zwraca record (message text, detail text, hint text, sql_error_code text)
czyli trochę więcej szczegółów 😉 Oczywiście to samo można zrobić w inny sposób i każdy z nas zna przynajmniej milion takich sposobów ale lepiej mieć wybór i to nie tylko w bazach danych 😉
Aby zaprezentować Ci jak można ich użyć napiszę prostą funkcję get_interval_hours
, która będzie przyjmować tablicę stringów z interwałami a zwracać będzie ilość godzin po zsumowaniu tych interwałów. Czyli dla dwóch interwałów po 1 dzień powinna zwrócić 48 godzin. Natomiast jeśli jeden z elementów przesłanej tablicy nie jest typu INTERVAL
to rzuci wyjątkiem.
CREATE OR REPLACE FUNCTION get_interval_hours( intervals TEXT[] )RETURNS int AS $CODE$ DECLARE interval_text TEXT; hours INT; e TEXT; BEGIN hours = 0; FOREACH interval_text IN ARRAY intervals LOOP IF pg_input_is_valid(interval_text, 'INTERVAL') THEN SELECT EXTRACT(epoch FROM interval_text::INTERVAL)::INT/3600 + hours INTO hours; ELSE SELECT message INTO e FROM pg_input_error_info(interval_text, 'date'); RAISE EXCEPTION '[%] is not valid: %', interval_text, e; END IF; END LOOP; RETURN hours; END $CODE$ LANGUAGE plpgsql;
Ok to teraz sprawdźmy czy dobrze działa:
SELECT public.get_interval_hours(ARRAY['1 day','1 day', '1 week'])
Zwraca 216
czyli działa dobrze 🙂No to teraz sprawdźmy co się stanie jak wywołamy funkcję z błędną wartością aaaa
:
SELECT public.get_interval_hours(ARRAY['1 day','1 day', '1 week','aaa'])
Funkcja zwróci nam:
ERROR: [aaa] is not valid: invalid input syntax for type date: "aaa" CONTEXT: PL/pgSQL function get_interval_hours(text[]) line 16 at RAISE SQL state: P0001
Mam nadzieję, że ten krótki post przyda Ci się w przyszłości.