#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
ornumeric
Ответ №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
''
asNULL
в нарушение стандарта a «feature». «Ошибка» кажется более подходящим описанием.5. @GordonLinoff — это может быть долгое обсуждение :). Конечно, это не концептуальная функция. Но у него есть некоторые преимущества, и, вероятно, это очень старая функция, где процессор был намного медленнее, а технические специалисты создали много грязных трюков. Мне это тоже не нравится, но эта функция здесь, и мы должны с этим смириться 🙂