PyQt6 Table Widget单元格编辑后保存至SQL Server报错求助
问题分析与解决方案
错误根源
- Invalid column name 'ID':你的
CONTROLE_DIFAL表不存在名为ID的列,或者你写错了主键列的名称(比如实际主键是CODIGO、REGISTRO_ID等)。 - WHERE条件参数错误:你用
current_value(修改前的单元格值)作为行定位条件,这完全错误——必须用表的主键值(每行唯一的标识)来定位要更新的行。 - 列名获取逻辑错误:直接创建
cursor后访问cursor.description会返回None(因为没有执行任何查询),无法正确获取列名。
修正后的代码示例
假设你的表主键列名为CODIGO,且加载TableWidget时主键列在第0列,以下是修复后的代码:
from PyQt6.QtWidgets import QTableWidgetItem def update_data(self): selected_row = self.tableWidget.currentRow() selected_column = self.tableWidget.currentColumn() new_value = self.edit_line.text() if selected_row != -1 and selected_column != -1: # 获取当前行的主键值(替换0为你的主键列索引) primary_key_value = self.tableWidget.item(selected_row, 0).text() # 方式1:提前定义表的列名(推荐,避免额外查询) column_names = ["CODIGO", "NOME", "VALOR", "DATA"] # 替换为你的实际列名 # 方式2:通过查询获取列名(如果列名可能变动) # cursor = db.cnxn.cursor() # cursor.execute("SELECT TOP 0 * FROM CONTROLE_DIFAL") # column_names = [col[0] for col in cursor.description] target_column = column_names[selected_column] # 替换WHERE后的主键列名为你的实际主键名(这里是CODIGO) query = f"UPDATE CONTROLE_DIFAL SET {target_column} = ? WHERE CODIGO = ?" cursor = db.cnxn.cursor() try: cursor.execute(query, (new_value, primary_key_value)) db.cnxn.commit() # 用连接对象提交事务更可靠 # 更新TableWidget界面,保持与数据库同步 self.tableWidget.setItem(selected_row, selected_column, QTableWidgetItem(new_value)) print("数据更新成功") except Exception as e: print(f"更新失败: {str(e)}") db.cnxn.rollback() # 出错时回滚事务 finally: cursor.close()
关键修复点
- 主键列名匹配:将
WHERE CODIGO = ?中的CODIGO替换为你的表实际主键列名。 - 正确定位行:通过当前行的主键值定位,确保只更新目标行。
- 列名获取:要么提前定义列名列表,要么执行空查询获取列元数据,避免
cursor.description为空的问题。 - 异常处理:添加事务回滚和错误捕获,防止程序崩溃并排查问题。
- 界面同步:更新TableWidget的单元格内容,确保界面显示与数据库一致。
内容的提问来源于stack exchange,提问作者Rodrigo andrade
相关产品推荐
相关产品推荐

