SQL.fetchall() 使用 Python 失败,出现 SQLState 24000(无效游标状态)

Posted

技术标签:

【中文标题】SQL.fetchall() 使用 Python 失败,出现 SQLState 24000(无效游标状态)【英文标题】:SQL.fetchall() fails with the SQLState 24000 (Invalid cursor state) with Python 【发布时间】:2018-07-17 16:41:04 【问题描述】:

目前我成功连接到数据库,然后执行一些 sql 语句,但是当我尝试检索查询结果时,我遇到以下raise ProgrammingError(state,err_text) pypyodbc.ProgrammingError: ('24000', '[24000] [Microsoft][ODBC SQL Server Driver]Invalid cursor state')

这是我的代码:

# Connection to MSSQL
import pypyodbc

connection_live_db = pypyodbc.connect(driver="SQL Server", server="xxx.xxx.xxx.xxx", uid="test",
                                                  pwd="xxxx", Trusted_Connection="No")

credit_hold_co = connection_live_db.cursor()

# read the sql file in buffer and close
read_sql_file = open('C:\\Users\\userX\\Documents\\Scripts\\credit_hold_co.sql','r')
sql_file = read_sql_file.read()
read_sql_file.close()

# split each sql statement by ;
sqlCommands = sql_file.split(';')

results_sql = ""

# iterate over each command and execute it
for command in sqlCommands:
    try:
        credit_hold_co.execute(command)
    except ValueError:
        print(command)
    # retrieve results
    results = results + str(credit_hold_co.fetchall())


# close sql connection
credit_hold_co.close()

这是我尝试执行的 sql 命令的示例:

-- credit_hold_co
if OBJECT_ID('tempdb..#Credit_Hold_CO') is not NULL
drop table #Credit_Hold_CO;

create table #Credit_Hold_CO
    ([co_num] varchar(30),
     [credit_hold] char(1),
     [credit_hold_reason] char(5),
     ['Type of credit hold reason'] varchar(20),
     [credit_hold_date] datetime );

insert into #Credit_Hold_CO([co_num],[credit_hold],[credit_hold_reason],['Type of credit hold reason'],[credit_hold_date])
  select distinct co_num, credit_hold, credit_hold_reason, 
   (case 
       when credit_hold_reason = 'PD' then 'Past due payments'
       when credit_hold_reason = 'BR' then 'Bankruptcy'
    end) as 'Type of credit hold reason',
 credit_hold_date
 FROM [Database].[dbo].[co] where credit_hold = '1';

select * from #Credit_Hold_CO
order by orig_site;

drop table #Credit_Hold_CO;

我找到了一些指向当前问题的链接,例如pypyodbc invalid cursor name 和SQL statement invalid cursor state 24000,并且都建议创建另一个游标以避免第一个游标的结果无效,但没有提供更多详细信息。

问题和答案于 7 月 17 日 @13:31 MT 更新:

    如何正确检索我的 sql 语句的结果? 请参阅下面的答案。 我是否非常需要另一个游标或有更好的方法来解决这个问题? 不,另一个游标不是解决方案,而是从 SQL 查询中删除临时表。

【问题讨论】:

['Type of credit hold reason'] varchar(20), 无效,不确定这是否只是一个示例,但名称中不能有引号 运行 ['Type of credit hold reason'] varchar(20) 在查询中工作正常。 哎呀!糟糕:) 不用担心,感谢您尝试提供一些可能出错的线索。 我有一些代码几乎完全符合您的要求。没有足够的空间把它作为评论。我可以建议运行:credit_hold_co = connection_live_db.cursor() 并在 while 循环中关闭它吗?这听起来像你的2. 项目:) 【参考方案1】:

Alejandro BR 和我继续我们广泛的 cmets 进入 *** 聊天。经过一些调试,它是两个折叠:

-该文件应该是 ANSI 编码的,或者如果是 UTF-8,则按如下方式读取: open("your location","r", encoding="utf-8", errors="replace")

-以以下方式简化 Python 以使其脱离实际,然后继续循环它。每个SELECT都需要一个光标

在下面找到更新的查询:

# Connection to MSSQL
import pypyodbc

connection_live_db = pypyodbc.connect(driver="SQL Server", server="xxx.xxx.xxx.xxx", uid="test",
                                              pwd="xxxx", Trusted_Connection="No")

credit_hold_co = connection_live_db.cursor()

# read the .txt file that contains the query 
# Avoid strange characters by saving the file in ANSI
# or use the following code from below if you save in UTF-8
read_sql_file = open('C:\\Users\\userX\\Documents\\Scripts\\credit_hold_co.txt','r', encoding="utf-8", errors="replace")
sql_file = read_sql_file.read()
read_sql_file.close()

# Execute the file that contains the sql query 
credit_hold_customer_orders.execute(sql_file) 

# store the results in variable
results = credit_hold_customer_orders.fetchall() 

# close cursor
credit_hold_customer_orders.close() 
print(results)

另外,我们必须从 txt 文件更新 sql 查询:

select distinct co_num, credit_hold, credit_hold_reason, 
   (case 
       when credit_hold_reason = 'PD' then 'Past due payments'
       when credit_hold_reason = 'BR' then 'Bankruptcy'
    end) as 'Type of credit hold reason',
 credit_hold_date
 FROM [Database1].[dbo].[co] where credit_hold = '1'

union all

select distinct co_num, credit_hold, credit_hold_reason, 
   (case 
       when credit_hold_reason = 'PD' then 'Past due payments'
       when credit_hold_reason = 'BR' then 'Bankruptcy'
    end) as 'Type of credit hold reason',
 credit_hold_date
 FROM [Database2].[dbo].[co] where credit_hold = '1'

【讨论】:

以上是关于SQL.fetchall() 使用 Python 失败,出现 SQLState 24000(无效游标状态)的主要内容,如果未能解决你的问题,请参考以下文章

python使用独立空间

使用嵌入式 Python

python使用cookie登陆网页

Python基础 -- Python环境的安装pip的使用终端运行python文件Pycharm的安装和使用Pycharm基本设置:设置Python文件默认格式

在python使用SSL(HTTPS)

python 爬虫使用方法分享——安装python