好吧,希望这是我忽略的非常愚蠢的事情......
我在SQL Server 17上使用Python 3.7.2和Pyodbc 4.0.24(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()
如果我在SQL Server上运行相同的TSQL,则会收到错误消息:
Msg 2714,级别 16,状态 6,第 1 行 已存在名为 数据库中的"测试"。
那么如何让 Python/Pyodbc 抛出相同或类似的错误呢?
很抱歉死灵,但如果其他人正在搜索这个,pyodbc
不会返回错误,因为它首先是获取与错误无关的消息,例如 (1) rows affected
. 我通过在程序开始时拨打set nocount on
解决了我的问题,而不必根据接受的答案拆分呼叫。
Pyodbc 不会引发任何异常,因为多语句查询中的第一个事务类型行USE [DATABASENAME]
没有错误。
与大多数Python DB-API一样,Pyodbc 不支持在同一执行调用中执行多个事务性 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)
''')