cx_Oracle.DatabaseError: ORA-00904: "DATETIME". "DATETIME": неверный идентификатор - PullRequest
0 голосов
/ 14 октября 2018

Я пытаюсь экспортировать базу данных Oracle с помощью Python cx_Oracle.Я подключаюсь к БД, запрашиваю все нужные мне строки и затем строю из них оператор INSERT.Я использую код, подобный следующему:

table_name = "AUDIT"
where_clause = "id > 10"
query = "SELECT * FROM " + table_name + " WHERE " + where_clause
curs = db_conn.cursor()
curs.execute(query)
res = curs.fetchall()
columns = []
for i in range(0, len(curs.description)):
    columns.append(curs.description[i][0])
column_names = ",".join(columns)
statement = "INSERT INTO %s (%s) VALUES %s" % (table_name, column_names, row)
print statement

Типы: NUMBER, VARCHAR2, DATE, NUMBER, и я получаю оператор вставки, который выглядит хорошо ... за исключением поля даты:

INSERT INTO AUDIT_LOG (LOG_DBID,USER_NAME,EVENT_DATE,SEVERITY) VALUES ('AUDIT_LOG_SQ.nextval', 'user@do',datetime.datetime(2018, 4, 28, 1, 57, 42), '1')

Когда я пытаюсь выполнить это, через sqlplus или с помощью того же курсора, я получаю следующую ошибку:

Error starting at line 1 in command:
INSERT INTO AUDIT_LOG (LOG_DBID,USER_NAME,EVENT_DATE,SEVERITY) VALUES ('AUDIT_LOG_SQ.nextval', 'SYSTEM@do',datetime.datetime(2018, 4, 28, 1, 57, 42), '1')
Error at Command Line:1 Column:95
Error report:
SQL Error: ORA-00904: "DATETIME"."DATETIME": invalid identifier
00904. 00000 -  "%s: invalid identifier"

Без элемента datetime запросы работают нормально. Как вставить результат, полученный из курсора?

Я проверил экспорт SQL_Developer для сравнения с моим, и у них есть другой способ его обработки:

INSERT INTO AUDIT_LOG (LOG_DBID,USER_NAME,EVENT_DATE,SEVERITY) VALUES ('AUDIT_LOG_SQ.nextval', 'user@do',to_timestamp('25-APR-18','DD-MON-RR HH.MI.SSXFF AM'), '1')

Который я действительно не нашел способа дублировать (не превращая весь запрос в некрасивую конкатенацию строк), и я не уверен, что мне нужно - должно быть что-то, что я упускаю!

Любая помощь будет оценена, спасибо!

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Ошибка SQL: ORA-00904: «DATETIME». «DATETIME»: неверный идентификатор

Вы получаете эту ошибку, поскольку datetime.datetime не является допустимым синтаксисом Oracle.Вы это знаете, потому что знаете, как Oracle SQL Developer форматирует временные метки.Но вы не хотите копировать явную логику to_timestamp().

Мне неясно, откуда вы получаете значения EVENT_DATE, но, учитывая, что это функция аудита, может быть, то, что вынужно sysdate, встроенный Oracle, который дает нам текущую дату и время.

0 голосов
/ 14 октября 2018

Я не знаю, как делать то, что вы делаете, но - поскольку в течение 5 часов нет ответов, позвольте мне сказать пару слов.

Это утверждение, которое не удалось:

INSERT INTO AUDIT_LOG (LOG_DBID,USER_NAME,EVENT_DATE,SEVERITY) VALUES 
('AUDIT_LOG_SQ.nextval', 'SYSTEM@do',datetime.datetime(2018, 4, 28, 1, 57, 42), '1')

Что вы ожидаете от datetime.datetime?Для меня (и, по-видимому, Oracle) это выглядит так, как будто есть пользователь с именем datetime (первый, перед точкой), который имеет функцию с именем datetime (второй, за точкой).).Скорее всего, ни одно из этих двух значений не соответствует действительности, верно?

Я бы посоветовал вам попробовать функцию TO_DATE, которая бы принимала два параметра: дату (и время) и соответствующую маску формата, такую ​​как

to_date('2018-04-28 01:57:42', 'yyyy-mm-dd hh24:mi:ss')

Вы бы поместили это вместо вашей datetime конструкции.

Однако я боюсь, что - даже если вы сделаете это - INSERT может снова потерпеть неудачу из-за первойзначение, которое вы вводите.

LOG_DBID выглядит как ID (NUMBER тип данных);это?INSERT вы написали, пытаетесь вставить в нее строку - потому что вы заключили ее в одинарные кавычки: 'audit_log_sq.nextval'.AUDIT_LOG_SQ - это имя последовательности.Итак, если вы хотите вставить числовое значение в этот столбец, вы должны опустить одинарные кавычки.

Наконец, утверждение о том, что может работать (по крайней мере, в самой Oracle) будет выглядеть так:

INSERT INTO AUDIT_LOG (LOG_DBID,USER_NAME,EVENT_DATE,SEVERITY) VALUES 
(AUDIT_LOG_SQ.nextval, 
 'SYSTEM@do', 
  to_date('2018-04-28 01:57:42', 'yyyy-mm-dd hh24:mi:ss'), 
 '1')

Надеюсь, это имеет смысл, даже в вашем контексте.

...