Netezza: ОШИБКА [HY000] ОШИБКА: pg_atoi: ошибка в [NULL]: невозможно проанализировать [NULL]

Я загрузил свои файлы в Netezza из db2, используя NZload. Чтобы использовать NZload, нам сначала нужно создать таблицу в Netezza для получения данных, поэтому для этой цели я создал таблицу Table1 со всеми столбцами, имеющими тип данных character varying. Я успешно загрузил все записи в эту таблицу.

Теперь я хочу изменить тип данных нескольких столбцов на date, чтобы я мог выполнять поиск по критериям месяца и года. Я создал другую таблицу, Table2, со столбцами, имеющими тип данных date, и при попытке переместить данные из Table1 в Table2 я получаю сообщение об ошибке:

"ERROR [HY000] ERROR: pg_atoi: error in "[NULL]": can't parse "[NULL]" "

Что я должен сделать, чтобы успешно выполнить это преобразование типа данных?

DDL для двух таблиц:

CREATE TABLE ID1
   (
      ID          CHARACTER VARYING(100) NULL,
      ID_NUM      CHARACTER VARYING(100) NULL,
      CREATE_TIME CHARACTER VARYING(100) NULL,
      CRT_DTE     CHARACTER VARYING(100) NULL,
      UPDATE_TIME CHARACTER VARYING(100) NULL,
      PLAN_YEAR   CHARACTER VARYING(100) NULL,
      DLV_DTE     CHARACTER VARYING(100) NULL,
      STATUS      CHARACTER VARYING(100) NULL
   );

CREATE TABLE ID2
   (
      ID          INTEGER NULL,
      ID_NUM      INTEGER NULL,
      CREATE_TIME DATETIME NULL,
      CRT_DTE     DATETIME NULL,
      UPDATE_TIME DATETIME NULL,
      PLAN_YEAR   INTEGER NULL,
      DLV_DTE     DATETIME NULL,
      STATUS      CHARACTER VARYING(100) NULL
   );

person Badrin    schedule 14.11.2014    source источник
comment
Можете ли вы предоставить ddl для двух таблиц? Такая ошибка обычно означает, что у вас есть данные в исходном столбце, которые нельзя неявно привести к целевому столбцу.   -  person ScottMcG    schedule 15.11.2014
comment
А также предоставьте образец того, как даты представлены в столбцах varchar для приема.   -  person ScottMcG    schedule 15.11.2014
comment
Скотт, создайте таблицу ID1 ( переменный символ ID (100) null, переменный символ ID_NUM (100) null, переменный символ CREATE_TIME (100) null, переменный символ CRT_DTE (100) null, переменный символ UPDATE_TIME (100) null, переменный символ PLAN_YEAR ( 100) null, переменный символ DLV_DTE(100) null, переменный символ STATUS(100) null )   -  person Badrin    schedule 17.11.2014
comment
Таблица 2: создать таблицу ID2 (ID целое число нуль, ID_NUM целое число нуль, CREATE_TIME datetime null, CRT_DTE datetime null, UPDATE_TIME datetime null, PLAN_YEAR integer null, DLV_DTE datetime null, символ STATUS Variing (100) null );   -  person Badrin    schedule 17.11.2014
comment
--Загрузить вставку данных в ID2 select * from ID1-- Ошибка (ОШИБКА [HY000] ОШИБКА: pg_atoi: ошибка в [NULL]: невозможно проанализировать [NULL] )-- Я изменил таблицу ID1:изменить таблицу ID1 изменить столбец update_time datetime; Это приводит к ошибке (ошибка ^ найдена DATETIME (на символе 73), ожидая DROP' or SET')   -  person Badrin    schedule 17.11.2014
comment
Я получил это сообщение об ошибке из-за строки в предложении WHERE, которая проверяла столбец varchar на наличие column <> -1. (-1 было случайным строковым значением, которое нужно было исключить.) Одинарные кавычки вокруг -1 избавили от ошибки: column <> '-1'   -  person Doug_Ivison    schedule 17.10.2019


Ответы (2)


Netezza будет неявно преобразовывать символьные столбцы в другие типы данных, когда сможет понять, как правильно преобразовать символьные данные.

Например:

TESTDB.ADMIN(ADMIN)=> insert into id1 values
TESTDB.ADMIN(ADMIN)-> (NULL, NULL , '1999-1-1', '2010-01-31', '2014-12-1', NULL, '1900-01-1', NULL);
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> insert into id2 select * from id1;
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> select * from id2;
 ID | ID_NUM |     CREATE_TIME     |       CRT_DTE       |     UPDATE_TIME     | PLAN_YEAR |       DLV_DTE       | STATUS
----+--------+---------------------+---------------------+---------------------+-----------+---------------------+--------
    |        | 1999-01-01 00:00:00 | 2010-01-31 00:00:00 | 2014-12-01 00:00:00 |           | 1900-01-01 00:00:00 |
(1 row)

Однако, основываясь на вашем DDL и выводе, я считаю, что это преобразование в INTEGER терпит неудачу. Кажется, что где-то в ваших данных в таблице ID1 есть столбец, содержащий текстовое значение «NULL».

TESTDB.ADMIN(ADMIN)=> insert into id1 values 
(NULL, 'NULL', NULL, NULL, NULL, NULL, NULL, NULL);
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> insert into id2 select * from id1;
ERROR:  pg_atoi: error in "NULL": can't parse "NULL"
TESTDB.ADMIN(ADMIN)=>

Я бы порекомендовал проверить столбцы в ID1, чтобы найти строку «NULL» и, возможно, заменить фактическим NULL, если это необходимо.

Как только это будет решено, вы можете обнаружить, что ваше представление даты в ваших столбцах varchar не преобразуется неявно из-за необычного формата. В этом случае вам может потребоваться явное преобразование с помощью функции to_date.

person ScottMcG    schedule 17.11.2014
comment
Скотт: Я проверил с Null select * from ID1, где идентификатор состояния '%null%' или где id = null для всех столбцов, и строки с нулевым значением не отображались. Есть ли способ, где я могу изменить тип данных id как целое число и тип данных Update_time с символа, изменяющегося на дату и время. если мы это сделаем, нет необходимости снова загружать в другую таблицу2, т.е. ID2 - person Badrin; 17.11.2014
comment
Вы не можете изменить тип столбца за один шаг. Вам нужно будет добавить новый столбец, обновить его, чтобы он был установлен на старый столбец, удалить старый столбец, а затем переименовать новый столбец в имя старого столбца. Проще всего было бы создать новую таблицу с измененным DDL и выбрать вставку в нее, а затем переименовать таблицы. - person ScottMcG; 17.11.2014
comment
Попробуйте это для каждого столбца последовательно, чтобы выяснить, где находятся неверные данные: выберите ID::INTEGER из ID1; выберите ID_NUM::INTEGER из ID1; выберите CREATE_TIME::TIMESTAMP из ID1; и т.д. И посмотрим, в какой колонке ошибка. Изменить: временная метка и дата и время являются синонимами. - person ScottMcG; 17.11.2014
comment
Есть 2,5 миллиона записей, и проверить неверные данные невозможно. - person Badrin; 18.11.2014
comment
Тем не менее, отправной точкой является определение того, какая колонка нас огорчает. Так что работа там не зависит от количества рядов. Вы не сможете получить данные в формате метки времени, если мы не знаем, какие столбцы являются проблемой. Моя догадка по-прежнему заключается в том, что это один из столбцов целых чисел. Если вы запустите select count(ID::INTEGER) from ID1; выберите count(ID_NUM::INTEGER) из ID1; выберите count(PLAN_YEAR::INTEGER) из ID1; дайте мне знать результаты. - person ScottMcG; 18.11.2014
comment
Он дал одинаковое количество строк для ID и ID_NUM; выберите plan_year::integer из CHECK_PLAN_ID1; выберите count(PLAN_YEAR::INTEGER) из CHECK_PLAN_ID1; Ошибка: pg_atoi: ошибка в [NULL]: невозможно проанализировать [NULL] - person Badrin; 18.11.2014
comment
Хорошо - если вы получили эту ошибку в ответ на запрос в отношении plan_year, запустите это, чтобы проверить значения, которые: выберите plan_year из id1, где plan_year не является нулевым порядком по plan_year desc limit 5; - person ScottMcG; 18.11.2014
comment
он отображает нулевые значения в столбце Plan_year - person Badrin; 18.11.2014
comment
Хорошо, так как мы указали, где PLAN_YEAR IS NOT NULL в нашем запросе, мы знаем, что то, что вы видите, не является настоящим NULL, это на самом деле текст (при условии, что вы видели слово NULL) или пустая строка (при условии, что вы ничего не видели). Вам нужно будет очистить их с помощью заявления об обновлении, прежде чем ваше преобразование будет работать. Мы, вероятно, расширили границы того, что мы должны делать в комментариях, поэтому, если вам нужна дополнительная помощь, я думаю, мы должны перенести ее в чат. - person ScottMcG; 18.11.2014
comment
Я не могу перейти в чат.., он показывает недостаточно репутации.. Я загрузился в id2, я изменил play_year на переменный персонаж; выберите id, DLV_DTE, STATUS из ID2, где месяц (DLV_DTE) = 10 и год (DLV_DTE) = 2013. ОШИБКА: Функция «МЕСЯЦ (TIMESTAMP)» не существует. Невозможно определить функцию, которая удовлетворяет заданным типам аргументов: - person Badrin; 19.11.2014
comment
Вы можете использовать экстракт или date_part, чтобы выполнить сравнение, которое вы ищете. Попробуйте выбрать id, DLV_DTE, STATUS из ID2, где извлечение (месяц из DLV_DTE) = 10 и извлечение (год из DLV_DTE) = 2013; - person ScottMcG; 19.11.2014
comment
Спасибо, Скотт, это сработало! Когда я загружаю таблицу из txt-файла в Netezza с помощью NZLOAD, я создал таблицу со всеми столбцами как символы, меняющиеся в Netezza, а затем загрузил, если я использовал тип данных Datetime для столбца даты, это выдало мне ошибку: [1, TIMESTAMP] ожидаемый разделитель даты, 2[/]. - person Badrin; 19.11.2014
comment
Взгляните на опции -datestyle и -datedlim для nzload. Разделителем по умолчанию является «-», но вы, похоже, используете «/», который можно изменить с помощью -datedelim. - person ScottMcG; 19.11.2014
comment
я использовал разделитель каналов '|' чтобы загрузить файл, я не могу использовать delim'-'or'/'bcz в моих данных, эти разделители присутствуют - person Badrin; 19.11.2014
comment
datedelim не зависит от значения, которое вы используете для общего разделителя. Он просто указывает для дат/временных меток только, какой разделитель используется в частях дат. Это не имеет никакого эффекта вне этого. - person ScottMcG; 19.11.2014
comment
Скотт, я не совсем понял тебя..., я пытался загрузить с разделителем "-", и он даже не отображает Nzbad, файл журнала. после этого я снова попытался использовать разделитель каналов и снова отобразил ту же ошибку. Мой вопрос: можем ли мы загрузить таблицу с помощью NZload, используя те же типы данных, что и предыдущая таблица (кстати, нам нужно преобразовать ее в текст или csv), а затем NZload сохранит старые типы данных из другой базы данных. - person Badrin; 19.11.2014
comment
Оставьте то же значение, которое вы используете для -delim, но укажите -datedelim '/' в качестве еще одной опции nzload. Это указывает, какой символ будет найден между частями дня, месяца и года даты. Например, 01.10.2014 разделитель даты равен «/». На 01.10.2014 это «-». «-» используется по умолчанию, но ваши данные используют «/» в соответствии с вашей ошибкой: [1, TIMESTAMP] ожидаемый разделитель даты, 2 [/]. Также есть опция -datestyle, которая указывает id формат даты: месяц, день, год или год, месяц, день и т. д. См. документацию здесь: tinyurl.com/jwvtdcz - person ScottMcG; 19.11.2014
comment
где я должен указать -datedelim '/' или при создании новой таблицы это в синтаксисе Nzload? я преобразовал файл в delim '/' и использовал в синтаксисе delim '/'. Это дало мне ошибку [1, TIMESTAMP] ожидаемый разделитель даты, 12[ ] - person Badrin; 20.11.2014
comment
Это опция для nzload, которую вы указываете в дополнение к -delim '|' - person ScottMcG; 20.11.2014

Я загрузился в id2, я изменил play_year на переменный характер; выберите идентификатор, DLV_DTE, STATUS из ID2, где месяц (DLV_DTE) = 10 и год (DLV_DTE) = 2013

ОШИБКА: Функция «МЕСЯЦ (TIMESTAMP)» не существует. Невозможно определить функцию, которая удовлетворяет заданным типам аргументов:

person Badrin    schedule 18.11.2014