Pyodbc не возвращает ошибку из SQL Server

1

Хорошо, надеюсь, это что-то действительно глупое, что я упускаю из виду...

Я использую Python 3.7.2 и Pyodbc 4.0.24 на SQL Server 17 (14.0.2002.14)

На моем SQL Server я создаю таблицу как таковую:

create table test(
    test1 varchar(5)
)

Но когда я пытаюсь выдать ошибку (поскольку таблица уже существует), выполнив тот же запрос с помощью pyodbc, я не вижу никаких возвращенных ошибок:

def createSQLTable():
    try:
        sql_conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
                                    'Server=[SERVERNAME];'
                                    'Database=[DATABASENAME];'
                                    'Trusted_Connection=yes;')
        cursor = sql_conn.cursor()
        sql = '''set nocount on;
           use [DATABASENAME]
           create table test(test1 varchar(5));'''
        cursor.execute(sql)
    except Exception as e:
        print(e)
    finally:
        sql_conn.commit()
        cursor.close()
        sql_conn.close()

createSQLTable()

Если я запускаю тот же TSQL на SQL Server, я получаю сообщение об ошибке:

Сообщение 2714, уровень 16, состояние 6, строка 1 В базе данных уже есть объект с именем "test".

Так как же заставить Python/Pyodbc выдавать ту же или похожую ошибку?

  • 0
    @Parfait Спасибо за предложение, которое, к сожалению, ничего не изменило.
  • 0
    @Parfait Не везет с автокоммитом.
Показать ещё 3 комментария
Теги:
sql-server
python-3.x
pyodbc

1 ответ

1
Лучший ответ

Pyodbc не вызывает никаких исключений, поскольку нет ошибки с USE [DATABASENAME] которая является первой строкой типа транзакции в вашем запросе с несколькими операторами.

Pyodbc, как и большинство Python DB-API, не поддерживает несколько операторов SQL транзакций в одном вызове выполнения с некоторыми исключениями. Обычно выполняется только первый запрос.

Рассмотрите возможность отправки их по отдельности в пределах одного блока try:

cur.execute('set nocount on;')
cur.execute('use [DATABASENAME];')
cur.execute('create table test(test1 varchar(5));')

Или поместите строки в хранимую процедуру и выполните одно из следующих действий:

cursor.execute("EXEC mystoredProc")

cursor.execute("{CALL mystoredProc}")

Или оставьте только соответствующие строки, так как USE не требуется в спецификации соединения с базой данных.

cur.execute('''set nocount on
               create table test(test1 varchar(5)
            ''')
  • 0
    «Обычно запускается только первый запрос». - Не в моем опыте. Да, есть некоторые случаи, когда блокировка анонимного кода приведет к сбою или приведет к потенциально запутанным результатам (например, если опустить SET NOCOUNT ON; где это необходимо), но это скорее функция драйвера ODBC, чем самого pyodbc. pyodbc просто передает текст команды SQL в диспетчер драйверов ODBC и ожидает возвращения результатов.
  • 0
    Хороший вопрос @GordThompson. Я не хотел делать абсолютных заявлений, так как некоторые многострочные блоки кода могут запускаться особенно TSQL с его пакетными вызовами с использованием GO . Все зависит от API, драйвера, даже RDBMS.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню