【问题标题】:pandas + pyodbc ODBC SQL type -150 is not yet supported尚不支持 pandas + pyodbc ODBC SQL 类型 -150
【发布时间】:2017-08-14 14:55:58
【问题描述】:

我知道这方面有很多主题,但我认为这是非常具体的。 我获取当前代码用于审计目的:

import pandas as pd
import pyodbc

query = """
--Top 50 high total CPU Queries
SELECT TOP 50
'High CPU Queries' as Type,
serverproperty('machinename') as 'Server Name',
isnull(serverproperty('instancename'),serverproperty('machinename')) as 'Instance Name',
        COALESCE(DB_NAME(qt.dbid),
        DB_NAME(CAST(pa.value as int)), 
        'Resource') AS DBNAME,
    qs.execution_count as [Execution Count],
    qs.total_worker_time/1000 as [Total CPU Time],
    (qs.total_worker_time/1000)/qs.execution_count as [Avg CPU Time],
    qs.total_elapsed_time/1000 as [Total Duration],
    (qs.total_elapsed_time/1000)/qs.execution_count as [Avg Duration],
    qs.total_physical_reads as [Total Physical Reads],
    qs.total_physical_reads/qs.execution_count as [Avg Physical Reads],
    qs.total_logical_reads as [Total Logical Reads],
    qs.total_logical_reads/qs.execution_count as [Avg Logical Reads],
SUBSTRING(qt.text,qs.statement_start_offset/2, 
        (case when qs.statement_end_offset = -1 
        then len(convert(nvarchar(max), qt.text)) * 2 
        else qs.statement_end_offset end -qs.statement_start_offset)/2)
        as query_text     
    FROM sys.dm_exec_query_stats qs
    cross apply sys.dm_exec_sql_text(qs.sql_handle) as qt
    outer apply sys.dm_exec_query_plan (qs.plan_handle) qp
    outer APPLY sys.dm_exec_plan_attributes(qs.plan_handle) pa
    where attribute = 'dbid'   
    ORDER BY 
        [Total CPU Time] DESC
"""
cnxn = pyodbc.connect('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
cnxn.execute(query).fetchall()
cnxn.close()

我收到以下错误:

cnxn.execute(sql_status_20).fetchall() 回溯(最近一次通话最后): 文件“”,第 1 行,在 pyodbc.ProgrammingError: ('ODBC SQL type -150 is not yet supported. column-index=1 type=-150', 'HY106')

谁能帮我解决这个问题?我对许多使用日期的 SQL Server 审计脚本有同样的问题,我无法更改驱动程序,因为我的生产环境中有各种 SQL 版本。

【问题讨论】:

    标签: sql-server pandas odbc pyodbc


    【解决方案1】:

    如果您无法更改驱动程序,则需要更改查询以返回它支持的数据类型。

    SQL类型-150为SQL_VARIANT,由SERVERPROPERTY返回。解决方法是将列显式CAST 设置为支持的类型,例如nvarchar

    CAST(SERVERPROPERTY('machinename') AS nvarchar(100)) AS 'Server Name',
    CAST(ISNULL(SERVERPROPERTY('instancename'),SERVERPROPERTY('machinename')) AS nvarchar(100)) AS 'Instance Name',
    

    【讨论】:

      【解决方案2】:

      如果很难将现有查询更改为显式 CAST 或 CONVERT 麻烦的值,那么您可以考虑尝试使用 pyodbc Output Converter Function。它使您能够定义一个 Python 函数,该函数将应用于为给定 ODBC SQL 类型返回的原始字节。

      例如,此测试代码因您描述的错误而失败:

      import pyodbc
      
      cnxn = pyodbc.connect('DSN=SQLmyDb', autocommit=True)
      crsr = cnxn.cursor()
      
      server_name = crsr.execute("SELECT SERVERPROPERTY('machinename')").fetchval()
      print(server_name)
      
      crsr.close()
      cnxn.close()
      

      但这在 Python3 下对我来说可以正常工作

      import pyodbc
      
      
      def handle_sql_variant_as_string(value):
          return value.decode('utf-16le')
      
      
      cnxn = pyodbc.connect('DSN=SQLmyDb', autocommit=True)
      crsr = cnxn.cursor()
      
      cnxn.add_output_converter(-150, handle_sql_variant_as_string)
      server_name = crsr.execute("SELECT SERVERPROPERTY('machinename')").fetchval()
      print(server_name)
      
      crsr.close()
      cnxn.close()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-15
        • 2014-07-23
        • 1970-01-01
        • 2011-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多