SQL INSERT INTO не работает с моей базой данных Access

Я работаю с довольно старым программным обеспечением (2000-е годы), которое взаимодействует с MS Access. Я использую Python для написания файлов MDB, которые мне нужно вставить в программное обеспечение. Мне нужно обновить значения 7 разных таблиц, чтобы получить ожидаемое значение. Для всех 7 таблиц я использую следующий код:

def sql_cols(df):
    cols_aux = tuple(df.columns)
    cols_aux = str(cols_aux).replace("'","")
    cols_aux = cols_aux.replace(', DESC', ', [DESC]')
    return cols_aux


for k in range(len(df)):
    vals = tuple(list(df.iloc[k]))
    cols = sql_cols(df)
    action = 'INSERT INTO Strategy {columns} VALUES {values}'.format(columns = cols, values = str(vals).replace("'",''))
    cursor.execute(action)
    conn.commit()

В 6 таблицах эта процедура работает, однако я продолжаю получать ('42000', '[42000] [Microsoft] [ODBC Microsoft Access Driver] Синтаксическая ошибка в операторе INSERT INTO. (-3502) (SQLExecDirectW)') в последней таблице. оператор действия для этой таблицы выглядит примерно так:

'INSERT INTO Strategy (STRATGY_ID, NUMBUDGETS, PDISC_RATE, INC_IMPS, OPT_METHOD, OBJ_FUNC, MININCVAL, EFFFZONE, BUDGETPD, REPORTING, NUM_GROUPS, MATRIX_DEF, NAME, [DESC], FLT_CONRTE, WRK_CONRTE, NET_CONRTE, START_YEAR, END_YEAR, CURRENCY, FLEET, NETWORK, NUM_SECSEL, NUM_VEHSEL, ANAL_MODE, NUMPRJOPTS, NUMSECOPTS, INC_NMT, DOECONANAL, DISC_RATE, BASE_OPTN, ACCCOSTS, FATALCOST, INJURYCOST, DAMAGECOST, ALLACCCOST, ENERGY, EMISSIONS, ACCLEFFECT, LOGFILE, INCSENSTVY, NUMSENSCEN, DOASSETVAL, EXCVEHDATA, EXCPERDATA) 
VALUES (0, 0,  , 0, 1, 0, 0, 95, 0, -1, 0, 0, Road_Networks_PA,  , 1, 1, 1, 2019, 2038, Reais, Vehicles 2017, Road_Networks_PA, 157, 12, 0,  , 157, -1, -1, 6.49,  , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  , 0, -1, -1)'

Я уже пытался заключить все столбцы в квадратные скобки, [], но это тоже не сработало. Может ли кто-нибудь помочь мне с этой проблемой?

Редактировать. Следуя совету Гордона, я изменил код, но появляется та же ошибка:

for k in range(len(df)):
    vals = tuple(list(df.iloc[k]))
    cols = sql_cols(df)
    action = 'INSERT INTO Strategy {columns} VALUES {values}'.format(columns = cols, values = str(vals))
    cursor.execute(action)
    conn.commit()

и оператор действия:

"INSERT INTO Strategy (STRATGY_ID, NUMBUDGETS, PDISC_RATE, INC_IMPS, OPT_METHOD, OBJ_FUNC, MININCVAL, EFFFZONE, BUDGETPD, REPORTING, NUM_GROUPS, MATRIX_DEF, NAME, [DESC], FLT_CONRTE, WRK_CONRTE, NET_CONRTE, START_YEAR, END_YEAR, CURRENCY, FLEET, NETWORK, NUM_SECSEL, NUM_VEHSEL, ANAL_MODE, NUMPRJOPTS, NUMSECOPTS, INC_NMT, DOECONANAL, DISC_RATE, BASE_OPTN, ACCCOSTS, FATALCOST, INJURYCOST, DAMAGECOST, ALLACCCOST, ENERGY, EMISSIONS, ACCLEFFECT, LOGFILE, INCSENSTVY, NUMSENSCEN, DOASSETVAL, EXCVEHDATA, EXCPERDATA) 
VALUES (0, 0, ' ', 0, 1, 0, 0, 95, 0, -1, 0, 0, 'Road_Networks_PA', ' ', 1, 1, 1, 2019, 2038, 'Reais', 'Vehicles 2017', 'Road_Networks_PA', 157, 12, 0, ' ', 157, -1, -1, 6.49, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' ', 0, -1, -1)"

Редактировать 2: Как спросил Кшитий Саксена, вот мои типы данных

Field Name  Data Type
STRATGY_ID  Number
NUMBUDGETS  Number
PDISC_RATE  Number
INC_IMPS    Yes/No
OPT_METHOD  Number
OBJ_FUNC    Number
MININCVAL   Number
EFFFZONE    Number
BUDGETPD    Yes/No
REPORTING   Yes/No
NUM_GROUPS  Number
MATRIX_DEF  Yes/No
NAME        Text
DESC        Text
FLT_CONRTE  Number
WRK_CONRTE  Number
NET_CONRTE  Number
START_YEAR  Number
END_YEAR    Number
CURRENCY    Text
FLEET       Text
NETWORK     Text
NUM_SECSEL  Number
NUM_VEHSEL  Number
ANAL_MODE   Number
NUMPRJOPTS  Number
NUMSECOPTS  Number
INC_NMT     Yes/No
DOECONANAL  Yes/No
DISC_RATE   Number
BASE_OPTN   Text
ACCCOSTS    Yes/No
FATALCOST   Number
INJURYCOST  Number
DAMAGECOST  Number
ALLACCCOST  Number
ENERGY      Yes/No
EMISSIONS   Yes/No
ACCLEFFECT  Yes/No
LOGFILE     Yes/No
INCSENSTVY  Yes/No
NUMSENSCEN  Number
DOASSETVAL  Yes/No
EXCVEHDATA  Yes/No
EXCPERDATA  Yes/No

person Bernardo Cascao    schedule 13.05.2019    source источник
comment
Вам нужны кавычки вокруг ваших строк.   -  person Gordon Linoff    schedule 13.05.2019


Ответы (3)


CURRENCY — это зарезервированное слово в Access SQL, поэтому, если у вас есть столбец с таким именем, вы должны заключить его в квадратные скобки. То есть это завершится ошибкой «Синтаксическая ошибка в операторе INSERT INTO». ...

crsr.execute("INSERT INTO Strategy (CURRENCY) VALUES ('USD')")

... но это будет работать:

crsr.execute("INSERT INTO Strategy ([CURRENCY]) VALUES ('USD')")
person Gord Thompson    schedule 13.05.2019

Как сказал Гордон, вам нужны кавычки вокруг строк, и вы не должны оставлять пустого места между запятыми. Попробуйте вставить 0 или Null или что-то другое, что лучше подходит для этого поля:

VALUES (0, 0, Null, 0,
person viilpe    schedule 13.05.2019

Столбцы VARCHAR требуют значений в кавычках. Попробуйте построить запрос следующим образом:

INSERT INTO Strategy (STRATGY_ID, NUMBUDGETS, PDISC_RATE, INC_IMPS, OPT_METHOD, OBJ_FUNC, MININCVAL, EFFFZONE, BUDGETPD, REPORTING, NUM_GROUPS, MATRIX_DEF, NAME, [DESC], FLT_CONRTE, WRK_CONRTE, NET_CONRTE, START_YEAR, END_YEAR, CURRENCY, FLEET, NETWORK, NUM_SECSEL, NUM_VEHSEL, ANAL_MODE, NUMPRJOPTS, NUMSECOPTS, INC_NMT, DOECONANAL, DISC_RATE, BASE_OPTN, ACCCOSTS, FATALCOST, INJURYCOST, DAMAGECOST, ALLACCCOST, ENERGY, EMISSIONS, ACCLEFFECT, LOGFILE, INCSENSTVY, NUMSENSCEN, DOASSETVAL, EXCVEHDATA, EXCPERDATA) 
VALUES (0, 0, NULL , 0, 1, 0, 0, 95, 0, -1, 0, 0, "Road_Networks_PA", NULL , 1, 1, 1, 2019, 2038, "Reais", "Vehicles 2017", "Road_Networks_PA", 157, 12, 0, NULL, 157, -1, -1, 6.49, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL , 0, -1, -1)

Добавьте NULL или "" (пустая строка) для столбцов, которые вы хотите оставить нулевыми или пустыми.

person Kshitij Saxena    schedule 13.05.2019
comment
Пробовал Null, None и пустую строку. Одна и та же ошибка у всех - person Bernardo Cascao; 13.05.2019
comment
Покажите структуру вашей таблицы. Значения VARCHAR должны быть заключены в кавычки. - person Kshitij Saxena; 13.05.2019
comment
Я отредактировал вопрос со структурой таблицы. - person Bernardo Cascao; 13.05.2019