作为SQL新手,我试图确保将数据最初导入数据库不会创建重复条目,并且将以编程方式创建数据库。如果有一种更有效的方法(执行告诉操作),我不会感到惊讶,但是我的方法是删除数据库并重新创建它(如果已经存在),据我所知这是非常快的。我已经在函数外部成功使用了同一条语句,并且没有格式化字符串,但是在创建函数来执行此操作时,我通过PYODBC收到错误:
ProgrammingError: ('42S22', "[42S22] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'test'. (207) (SQLExecDirectW)")
这很令人困惑,因为我没有尝试引用任何列,更不用说表了;因此很难进行故障排除。功能如下:
def db_connect(db, driver='ODBC Driver 17 for SQL Server', host='', UID='', PWD='', autocommit=False):
"""Returns a connection and a cursor object for the specified database."""
conn = pyodbc.connect(driver=driver,
host=host,
database=db,
UID=UID,
PWD=PWD,
autocommit=autocommit
)
print(f'Connect established to database {db}')
return conn, conn.cursor()
def db_clear(db, recreate=True):
"""Drops and recreates the specified database, ready for insert."""
conn, curs = db_connect('master')
curs.execute(f"""IF EXISTS (SELECT name from sys.databases WHERE (name = {db}))
BEGIN
ALTER DATABASE {db} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE {db};
END;""")
if recreate:
curs.execute(f"CREATE DATABASE {db};")
conn.close()
print(f'{db} successfully dropped and recreated.')
else:
print(f'{db} successfully dropped.')
return
db_clear('test')
[包含END;""")
的行上引发了异常。工作版本(函数中未包含)和此函数版本之间只有两个区别,即我开始使用较新的驱动程序来更好地处理数据类型转换,并且在这些功能完成后,我关闭了自动提交功能以批量插入他们的工作。我尝试将这两个选项都恢复为函数中的原始设置,但收到相同的错误。任何帮助表示赞赏!
您的字符串格式
f"""IF EXISTS (SELECT name from sys.databases WHERE (name = {db}))
BEGIN
ALTER DATABASE {db} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE {db};
END;"""
正在生产
IF EXISTS (SELECT name from sys.databases WHERE (name = test))
BEGIN
ALTER DATABASE test SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE test;
END;
并且当SQL解析器看到WHERE (name = test)
时,它将test
解释为列名(在sys.databases表/视图中),就像它(正确)将name
解释为列名一样。
相反,您要做的是向WHERE子句提供parameter value。
sql = f"""IF EXISTS (SELECT name from sys.databases WHERE (name = ?))
BEGIN
ALTER DATABASE [{db}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [{db}];
END;"""
curs.execute(sql, db)