Python:SQL Server使用datetime插入多个值(从字符串转换日期和/或时间时转换失败)
我试图在python中的数据库表(SQL server)中插入多行:Python:SQL Server使用datetime插入多个值(从字符串转换日期和/或时间时转换失败),python,sql-server,datetime,sql-insert,pyodbc,Python,Sql Server,Datetime,Sql Insert,Pyodbc,我试图在python中的数据库表(SQL server)中插入多行: def write_to_database(values): conn = pyodbc.connect("Driver={SQL Server};" "Server=xxxx.database.windows.net;" f"Database={database};&qu
def write_to_database(values):
conn = pyodbc.connect("Driver={SQL Server};"
"Server=xxxx.database.windows.net;"
f"Database={database};"
"UID=user;"
"PWD=password;")
cursor = conn.cursor()
cursor.executemany("insert into KeyFigures (DateTime, Parameter, CommulativeTime, Value) values (?,?,?,?)", values)
conn.commit()
return()
date = datetime.datetime.now()
atom = date.strftime("%Y-%M-%d") + " " + date.strftime("%H:%M:%S") + ".4526800"
values = ([datetime.datetime.now().isoformat(), 1, "NULL", 2],[datetime.datetime.now().isoformat(), 1, "NULL", 47],[datetime.datetime.now().isoformat(), 1, "NULL", 78])
write_to_database(values)
我尝试了多种日期时间格式、字符串组合等,例如:
datetime.datetime.now().isoformat()
atom
"2020-02-23 11:30:53.4526800"
"2020-02-23T11:30:53.4526800"
但我一直收到同样的错误:
line 50, in write_to_database
cursor.executemany("insert into KeyFigures (DateTime, Parameter, CommulativeTime, Value) values (?,?,?,?)", values)
pyodbc.DataError: ('22007', '[22007] [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting date and/or time from character string. (241) (SQLExecDirectW)')
在SSMS中,以下工作:
INSERT INTO KeyFigures (DateTime, Parameter, CommulativeTime, Value) VALUES ('2020-02-23 11:30:53.4526800',2,null,21)
如何解决此错误
*****编辑****
@非常感谢你。这已经非常有用了,但在我的代码中不起作用。我仍然收到同样的错误。我还尝试插入一行,这段代码可以工作(使用execute而不是executemany):
如果报价之间没有日期,它就不起作用。这也是执行官的问题吗?当我把问号放在qoutes(“?”或“?”)之间时,给出的错误是只给出了3个参数,而不是4个。正如我在评论中提到的,如果使用强类型数据类型(因此不要将其转换为字符串),python和pyodbc将很好地处理这个问题。但是,我也建议更新到,而不是使用旧的本机SQL Server驱动程序。我还使用将光标放在一个
中,这样它就可以优雅地靠近
对于我用下面的定义创建的一个表,这很好,插入了两行,具有正确的日期和时间值:
创建表dbo.TestDateTable(i int,dt datetime2(7));
导入日期时间,pyodbc
def将_写入_数据库(值):
conn=pyodbc.connect(“驱动程序={ODBC驱动程序17 for SQL Server};”
“服务器=xxxx.database.windows.net;”
“数据库={Database};”
“UID=用户;”
“PWD=密码;”)
使用conn.cursor()作为光标:
cursor.executemany(“插入到dbo.TestDateTable(i,dt)值(?,);”中,值)
康涅狄格州提交
返回()
date=datetime.datetime.now()
值=([1,日期],[2,日期])
将\写入\数据库(值)
不要将它们转换为字符串,将参数作为强类型数据和时间值传递给游标,python可以很好地处理它。此外,您应该真正使用“不要使用动态SQL”来注入列值。使用插入…值(?,…
并在元组中传递参数值(对于.execute
)或元组列表(对于.executemany
)。这是一个很好的建议。但是,请注意,使用上下文管理器(和
块)退出时不会自动关闭光标。详细信息。谢谢@GordThompson。因此,您是否建议使用连接()在外部/内部显式关闭光标。关闭()
是多余的;除非我读错了链接。这个问题会被详细讨论。@Mogo,我编辑了我的开始文章。我尝试了你的代码,但没有成功。@Loesviser你的尝试没有参数化;你正在注射。这是一个主要的安全缺陷。请再次查看我的答案。如果你注射了,那么是的,你将不得不问uote值,但不应进行注入,因为这是一个安全缺陷。
def write_to_database(date,parameter,cummulativeTime,value):
conn = pyodbc.connect("Driver={ODBC Driver 17 for SQL Server};"
"Server=xxxx.database.windows.net;"
f"Database={database};"
"UID=user;"
"PWD=password;")
with conn.cursor() as cursor:
cursor.execute(f"INSERT INTO dbo.KeyFigures (DateTime, Parameter, CommulativeTime, Value) values ('{date}',{parameter},{cummulativeTime},{value})")
conn.commit()
return()
date = datetime.datetime.now()
write_to_database(date, 1, "NULL", 43)