Я подумал, что было бы полезно опубликовать здесь некоторые ответы, полученные в одном из официальных списков рассылки PG (pgsql-bugs@lists.postgresql.org, https://lists.postgresql.org/).
Ответы Тома:
my_database=# SELECT file INTO my_file_now FROM public.my_datatable WHERE
my_id = '2fdf5297-8d4a-38b c -bb26-b8a4b7ba47e c '; ОШИБКА: отсутствует номер фрагмента 0 для значения тоста 3483039 в pg_toast_3473493
Мы исправили несколько ошибок за эти годы, которые проявляются в такого рода проблемы --- вы в курсе второстепенных выпусков? Также возможно, что переиндексация этой таблицы тостов исправит это.
На основе описанного выше поведения я создал следующую хранимую процедуру:
...
my_file_now BYTEA;
...
SELECT file
INTO my_file_now
FROM public.my_datatable WHERE my_id=my_id_now;
ВОПРОС: Почему ошибка, обнаруженная в запросе, не отслеживается блоком «EXCEPTION» в хранимой процедуре?
Я думаю, что plpg sql не потрудится разыменовать указатель TOAST при сохранении его в локальной переменной (хотя это утверждение очень возможно зависит от версии, и вы не сказали, какая у вас версия PG using).
Более надежный способ вызвать проблему - это выполнить какое-то вычисление, которое требует значения поля, возможно, в соответствии с
PERFORM md5(file) FROM public.my_datatable WHERE my_id=my_id_now;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'CORRUPTED MY_ID - % ', my_id_now;
DELETE FROM public.my_datatable WHERE my_id=my_id_now;
Я не знаю, что Я бы дал такую процедуру, как эта лицензия, чтобы удалить всю мою таблицу :-(. Если вам действительно все равно, сколько данных сохранилось, почему бы просто не TRUNCATE таблицы и покончить с этим? В противном случае выведите список проблем. некоторые строки для ручного просмотра кажутся более разумными.
Ответы Дэвида:
Спасибо за предложения! Мне показалось немного странным «pg sql» не «понимать» как исключение «ОШИБКА: отсутствует номер куска 0 для значения тоста 3483039 в pg_toast_3473493»
Я думаю, что точка зрения Тома состоит в том, что написанная вами функция никогда не пыталась распечатать значение поля, поэтому ошибка никогда не возникала в функции. Вы должны на самом деле попытаться манипулировать данными, чтобы получить ошибку. Если вы действительно получили функцию, которая действительно сталкивается с ошибкой, она должна (не проверяла себя) быть обработана в обработчике исключений; т. е. «Более надежный способ вызвать проблему - это выполнить какое-то вычисление, которое требует значения поля, возможно, в соответствии с [запрос для попытки]».