Django pyodbc Ошибка хранимой процедуры - не все аргументы преобразованы во время форматирования строки

У меня есть функция django, которая вызывает хранимую процедуру в SQL Server 2008 через pyodbc следующим образом:

def new_user(self):
        # create a cursor
        cur = connection.cursor()
    try:
        cur.execute("{CALL sp_newPerson  (?,?,?,?,?)}",
                   (self.id, self.fname, self.lname, self.address))
        #returns 1 when there is a result set.
        #if cur.return_value == 1:        
        # grab the results
        results = cur.fetchall()
            return results
    finally:
            cur.close()

Всякий раз, когда вызывается функция, я получаю "error_message": "не все аргументы, преобразованные во время форматирования строки"

1 ответ

Кажется, что sp_newPerson() имеет 5 аргументов (если я правильно посчитал все ?), но вы пытались выполнить его только с 4 параметрами, или он имеет 4 параметра, но вы добавили один ? Больше:

cur.execute("{CALL sp_newPerson(?,?,?,?,?)}", (self.id, self.fname, self.lname, self.address, self.something))

или же:

cur.execute("{CALL sp_newPerson(?,?,?,?)}", (self.id, self.fname, self.lname, self.address))

РЕДАКТИРОВАТЬ:

Кажется, вы пытаетесь использовать функцию или процедуру с параметрами OUT.

У меня нет MS SQL, чтобы проверить, работает ли он с подготовленными вызовами ODBC Python. Другие базы данных имеют проблемы с этим. Вероятно, трудно написать код Python ODBC для получения возвращаемого значения или параметра OUT. Из C или Delphi ODBC-драйвер получает буфер, выделенный перед выполнением такой функции / процедуры, чтобы его можно было заполнить. В Python я не знаю, возможно ли это. Я обнаружил, что PreparedStatements работает в JDBC (я использую его из Jython), даже с мостом JDBC-ODBC, но JDBC использует специализированный API для задания параметров ввода и вывода. Смотрите также мой вопрос о вызове функции из базы данных Oracle: как получить результат функции базы данных Oracle через ODBC?

Я думаю, что лучшее, что вы можете сделать, это использовать обходной путь. Если sp_newPerson() это функция:

  1. Преобразуйте это в SELECT, Он может не работать в некоторых базах данных, особенно в Oracle, когда функция меняет базу данных (используйте INSERT, UPDATE или DELETE):

    cur.execute("SELECT sp_newPerson(?,?,?,?)", (self.id, self.fname, self.lname, self.address))
    for row in cur.fetchall(): 
        r = row[0]
    
  2. Преобразуйте это в INSERT Конечно, вам придется создать tmp стол, очистить его и т.д.:

    r = cur.execute("INSERT INTO tmp (new_person_id) VALUES (sp_newPerson(?,?,?,?))", (self.id, self.fname, self.lname, self.address))
    if r == 1:
        cur.execute("SELECT new_person_id FROM tmp")
        for row in cur.fetchall(): 
            r = row[0]
    
Другие вопросы по тегам