【问题标题】:PyODBC Iterating Update - "Not a Query"PyODBC 迭代更新 - “不是查询”
【发布时间】:2016-03-24 15:54:08
【问题描述】:

我正在努力从 SQL Server 2008 R2 表中提取客户服务工单的措辞(“Note”),然后运行情绪分析并使用该分析来更新同一个表中的“Sentiment”字段。以下是有关表格字段的更多信息:

TicketNoteID(PK, int, not null)
TicketID (FK, int, not null)
UserName (varchar(20), not null)
Note (varchar(max), not null)
Author (varchar(50), not null)
isExternal (bit, null)
DateTimeCreated (datetime, not null)
NoteID (int, null)
DateTimeUploaded (datetime, null)
Error (bit, null)
ErrorMessage (varchar(max), null)
Sentiment (float, null)

当我运行下面的代码时,我得到了这个错误:

pyodbc.ProgrammingError:没有结果。以前的 SQL 不是查询。

我已经根据其他关于同一错误的帖子对我的代码进行了建模,但我找不到任何可以解决问题的方法。代码如下:

import pyodbc
from textblob import TextBlob

cnxn = pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};SERVER=...')

cur = cnxn.cursor()

sql = """
    SELECT Note
    FROM dbo.DSDTicketNotes
    where Sentiment is NULL
"""
rows = cur.execute(sql)

for row in rows:
    note = cur.fetchone()
    row = str(note)
    blob = TextBlob(row)
    sent = blob.sentiment.polarity
    sentUpdate = cur.execute("UPDATE dbo.DSDTicketNotes SET Sentiment = ?", sent)

cur.close()
cnxn.close()

感谢您的帮助!

【问题讨论】:

  • UPDATE 语句看起来需要WHERE 子句,否则每次迭代都会更新所有行。

标签: python sql-server tsql pyodbc


【解决方案1】:

不可能同时遍历游标结果使用 same 游标来执行其他语句。

如果要求是逐个遍历SELECT 结果(例如结果太大而无法放入内存)并采取措施,请管理两个游标:

...
selectCur = cnxn.cursor()
updateCur = cnxn.cursor()

selectSQL = """
    SELECT TicketNoteID, Note
    FROM dbo.DSDTicketNotes
    where Sentiment is NULL
"""

updateSQL = """
    UPDATE dbo.DSDTicketNotes
    SET Sentiment = ?
    WHERE TicketNoteID = ?
"""

for row in selCur.execute(selectSQL):
    id = row[0]
    blob = TextBlob(str(row[1]))
    sent = blob.sentiment.polarity
    updateCur = updateCur.execute(updateSQL, (sent, id))
    updateCur.commit()
...

或者如果SELECT 结果集总是很小,则将结果拉入一个列表进行迭代。这允许游标重用:

...
cur = cnxn.cursor()

selectSQL = """
    SELECT TicketNoteID, Note
    FROM dbo.DSDTicketNotes
    where Sentiment is NULL
"""

updateSQL = """
    UPDATE dbo.DSDTicketNotes
    SET Sentiment = ?
    WHERE TicketNoteID = ?
"""

rows = cur.execute(selectSQL).fetchall()
for row in rows:
    id = row[0]
    blob = TextBlob(str(row[1]))
    sent = blob.sentiment.polarity
    cur = cur.execute(updateSQL, (sent, id))
    cur.commit()
...

无论使用哪种方法,您都需要在SELECT 中包含主键,以便它可以用于UPDATE 正在处理的特定行。

【讨论】:

  • 布莱恩,这太棒了。感谢您发送。也就是说,它让我们大部分时间都受益,但更新查询正在使用第一条记录中的情绪更新所有行。我试图扔一个计数器并使用 row[a],但这没有用...
  • 表的主键是什么?更好的是,使用 DDL 为表格编辑问题。
  • 布莱恩,我已经添加了请求的信息。谢谢!
猜你喜欢
  • 2023-04-03
  • 1970-01-01
  • 2013-08-21
  • 2011-12-06
  • 2015-08-15
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
  • 2017-11-11
相关资源
最近更新 更多