ОШИБКА: недопустимый синтаксис ввода для числового типа: » «

#sql #postgresql

#sql #postgresql

Вопрос:

Получение следующей ошибки в одном из моих представлений:

Ошибка SQL [22P02]: ОШИБКА: недопустимый синтаксис ввода для числового типа: » «

Я думаю, это потому, что я использовал следующую команду COALESCE .

 COALESCE(to_number(a_id, '999999999999999'::text), b_id::numeric) AS c_id,
  
  • a_id имеет тип text
  • b_id имеет тип int4

Какие изменения я должен внести, чтобы заставить его работать?

Комментарии:

1. Иногда в вашем столбце появляются пробелы. Как бы вы хотели справиться с этим случаем?

2. Реальный вопрос: почему вы храните числа в text столбце. Вы действительно должны преобразовать это в столбец int or numeric

Ответ №1:

Судя по сообщению об ошибке, в вашем a_id столбце содержатся значения, которые не являются числовыми. Чтобы пометить такие записи, нарушающие правила, вы можете попробовать:

 SELECT *
FROM yourTable
WHERE NOT a_id ~ '^[0-9] (.[0-9] )?$';
  

Что касается того, как обрабатывать такие данные, решать вам.

Комментарии:

1. Я не вижу такого значения в своем столбце

2. @AbHiNaVAgRaWaL Попробуйте мой обновленный ответ, чтобы найти значения, которые не являются числовыми (целочисленными или с плавающей запятой).

3. Спасибо. Новая реализация работает. Однако, как можно решить проблему такого типа?

4. @ab: решение вашей проблемы заключается в том, чтобы не хранить числа в столбцах text / varchar

Ответ №2:

Похоже на обычную ошибку порта Oracle-> Postgres. Для Oracle NULL и пустой строки /- идентичны. Таким образом, вы можете использовать пустую строку практически в любом месте. Только Oracle имеет эту функцию — для любых других баз данных SQL пустой строки нет NULL . Для Postgres тоже. Вы не можете привести пустую строку к числовому типу в Postgres.

Примечание — очень трагично, что ваш столбец id имеет числовой тип, хотя есть цифры — это может быть довольно медленно с другими негативными последствиями.

Исправить легко, когда вы знаете причину:

 COALESCE(to_number(CASE trim(a_id) WHEN '' THEN NULL ELSE a_id END, '999999999999999'::text),
         b_id::numeric) AS c_id,
  

или, если есть больше пробелов, вы можете использовать

В любом случае — при переносе данных из Oracle в Postgres обычно лучше сразу заменить пустые строки на нули.

Существует еще одна проблема с производительностью — работа с numeric типом выполняется медленнее, чем с int4 типом. Использование numeric типа для идентификации — плохая идея.

Комментарии:

1. Я все еще вижу ту же ошибку даже после использования условия case

2. @AbHiNaVAgRaWaL — да, потому что у вас есть пробел, который не является пустой строкой. Я изменил ответ

3. @AbHiNaVAgRaWaL — конечно, нет, в этом случае вам следует заменить пробел пустой строкой — но это сигнал, поэтому входные данные неверны и должны быть очищены в первую очередь

4. @PavelStehule . , , я бы не стал описывать переопределение Oracle '' as NULL в нарушение стандарта a «feature». «Ошибка» кажется более подходящим описанием.

5. @GordonLinoff — это может быть долгое обсуждение :). Конечно, это не концептуальная функция. Но у него есть некоторые преимущества, и, вероятно, это очень старая функция, где процессор был намного медленнее, а технические специалисты создали много грязных трюков. Мне это тоже не нравится, но эта функция здесь, и мы должны с этим смириться 🙂