【问题标题】:Python & SQL via pyodbc - executing queries via loop with dynamic where clausePython & SQL via pyodbc - 通过带有动态 where 子句的循环执行查询
【发布时间】:2023-03-23 16:33:01
【问题描述】:

我正在尝试通过 pyodbc 生成和执行 SQL 语句。我希望有多个 SQL 语句,所有这些语句都以相同的 SELECT & FROM 开头,但在 WHERE 中具有不同的值。我的 WHERE 子句中的值来自循环遍历一个表 - SQL 脚本在表中找到的每个不同的值,我需要 Python 生成另一个使用该值作为 WHERE 子句的 SQL 语句。

我快要完成了,我只是在努力让 pyodbc 将我的查询字符串放在 SQL 喜欢的格式中。到目前为止我的代码:

import pyodbc

cn = pyodbc.connect(connection info)

cursor = cn.cursor()

result = cursor.execute('SELECT distinct searchterm_name FROM table1')

for row in result:
    sql = str("SELECT * from table2 WHERE table1.searchterm_name = {c}".format(c=row)),

#print sql

此代码生成这样的输出,其中“name here”基于 table1 中的值。

('SELECT * from ifb_person WHERE searchterm_name = (u\'name here\', )',)

我只需要删除查询和 where 子句周围的所有废话,让它看起来像这样。然后我可以将它传递给另一个 cursor.execute()

SELECT * from ifb_person WHERE searchterm_name = 'name here'

编辑

for row in result:
    cursor.execute("insert into test (searchterm_name) SELECT searchterm_name FROM ifb_person WHERE searchterm_name = ?",
               (row[0],))

此查询失败,错误为pyodbc.ProgrammingError: No results. Previous SQL was not a query.

基本上我想要做的是让 Python 为它在 table1 中找到的每个结果生成一个新的 SQL 语句。第二个查询是针对表 ifb_person 运行搜索并将结果插入到表“test”中。我想为 table1 中找到的每个结果运行单独的 SQL 语句

【问题讨论】:

  • 如何通过参数化正确执行此操作? cursor.execute("SELECT * FROM ifb_person WHERE searchterm_name = ?", (row[0],))。不要使用format 构建字符串来查询数据库。就像您可以阅读的有关该主题的所有指南都会以粗体显示的那样,这可能会让您对 sql 注入持开放态度。
  • 您的结果也作为元组返回,这就是为什么您需要在row 上使用[0] 索引。目前,您正在将元组转换为其字符串表示形式。我的评论应该有效;这里的生产/测试辩论有点无关紧要,因为从一开始就可以正确输入的字符较少。
  • 我无法正确看到您编辑的评论,但看起来您现在正在尝试组合查询,这不是您问题中的方法。我不知道该查询应该做什么,或者为什么你现在只有[0],而不是row[0]
  • @roganjosh 抱歉没有意识到这不清楚 - 我希望第一个查询的结果根据它的输出动态创建(并执行)sql 查询
  • 没关系,无论如何它应该在你的问题中。现在查询看起来像我以前的历史论文;重言式的练习。 cursor.execute("INSERT INTO test VALUES (?)", (row[0],)) 或类似的东西(我无法测试 atm)。查询的其余部分只是循环往复。

标签: python sql pyodbc


【解决方案1】:

pyodbc 允许我们遍历 Cursor 对象以返回行,在此期间 Cursor 对象仍在“使用中”,因此我们不能使用相同的 Cursor 对象执行其他操作。例如,这段代码会失败:

crsr = cnxn.cursor()
result = crsr.execute("SELECT ...")  # result is just a reference to the crsr object
for row in result:
    # we are actually iterating over the crsr object
    crsr.execute("INSERT ...")  # this clobbers the previous crsr object ...
    # ... so the next iteration of the for loop fails with " Previous SQL was not a query."

我们可以通过使用fetchall() 将所有行检索到result 中来解决这个问题...

result = crsr.execute("SELECT ...").fetchall()  
# result is now a list of pyodbc.Row objects and the crsr object is no longer "in use"

...或在循环中使用不同的 Cursor 对象

crsr_select = cnxn.cursor()
crsr_insert = cnxn.cursor()
crsr_select.execute("SELECT ...")
for row in crsr_select:
    crsr_insert.execute("INSERT ...")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    相关资源
    最近更新 更多