代码之家  ›  专栏  ›  技术社区  ›  Matthew

如何使用odbc进行“Select*from”查询

  •  4
  • Matthew  · 技术社区  · 7 年前

    我用的是 odbc package 在R中,我有一个SQL Server数据库,其中的表具有 Name 列,即 nvarchar(max) PublishStatus 是整数的列。

    此代码无效:

    library(odbc)
    library(DBI)
    library(tidyverse)
    con_string="Driver=ODBC Driver 11 for SQL Server;Server=myServer; Database=MyDatabase; trusted_connection=yes"
    con=dbConnect(odbc::odbc(), .connection_string =con_string)
    query="select * from MyTable"
    result=NULL
    result=dbSendQuery(con,query) %>% dbFetch
    head(result)
    

    它只是产生错误信息

    获取结果时出错(res@ptr,n,…): nanodbc/纳米dbc。cpp:2890:07009:[Microsoft][ODBC Driver 11 for SQL Server]描述符索引无效

    如果我再次尝试查询,会收到另一条错误消息,并且我可以告诉您,如果不关闭R并重新打开,就无法恢复:

    nanodbc/纳米dbc。cpp:1587:HY000:[Microsoft][ODBC Driver 11 for SQL Server]连接正忙,另一个命令的结果

    因为R和R的odbc都是非常糟糕的名称,所以很难搜索这个包中的错误。在 this SO 似乎列的顺序很重要,它要求在查询中首先指定整数列。

    query="select PublishStatus,Name from MyTable"
    result=NULL
    result=dbSendQuery(con,query) %>% dbFetch
    head(result)
    

    但这并不是:

    query="select Name,PublishStatus from MyTable"
    result=NULL
    result=dbSendQuery(con,query) %>% dbFetch
    head(result)
    

    select *

    1. 有什么办法让我可以做吗 询问?
    2. 当我拿到 Invalid Descriptor Index 错误,有没有一种方法可以在不重新启动R的情况下进行恢复?

    :使用旧的RODBC库,即使使用相同的ODBC驱动程序,它也没有此缺陷。这适用于 select * from 查询,并且不关心列的顺序

    library(RODBC)
    con=odbcDriverConnect(ConnectionString_Hemonc)  
    result=sqlQuery(con,query,stringsAsFactors=FALSE)
    close(con)
    head(result)
    

    我之前放弃了RODBC因为 it is unable (in practice) to write data to a database, as I discovered here .

    odbc 为了更快地读取数据,它的一个副作用是现在对读取数据的顺序非常挑剔。不幸的是,这破坏了我的用例——我不能要求只懂基本SQL的人使用将完全有效的SQL视为无效的工具。

    我想是的 RODBC 用于读取数据,

    :我试过了 ODBC Driver 13 for SQL Server 在连接字符串中而不是 ODBC Driver 11

    1 回复  |  直到 7 年前
        1
  •  0
  •   Suraj Kumar zip    6 年前

    Getting Data From Excel and SQL Server using ODBC

    set-psdebug -strict
    $ErrorActionPreference = "stop" 
    
    $ExcelFilePath='MyPath\pubs.xlsx' #the full path of the excel workbook
    if (!(Test-Path $ExcelFilePath))
     {
     Write-Error "Can't find '$($ExcelFilePath)'. Sorry, can't proceed because of this"
     exit
     }
    
    try {
    $Connection = New-Object system.data.odbc.odbcconnection
    $Connection.ConnectionString = 'Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ='+$ExcelFilePath+'; Extended Properties="Mode=ReadWrite;ReadOnly=false; HDR=YES"' 
    $Connection.Open()
    }
    catch
    {
     $ex = $_.Exception
     Write-Error "whilst opening connection to $ExcelFilePath : Sorry, can't proceed because of this"
     exit
    }
    
    try { 
    $Query = New-Object system.data.odbc.odbccommand
    $Query.Connection = $connection
    $Query.CommandText = @'
    SELECT title, SUM(qty) AS sales,
     COUNT(*) AS orders
     FROM [titles$] t
     INNER JOIN [sales$] s ON t.title_id=s.title_id
     WHERE title like '%?'
     GROUP BY title
     ORDER BY SUM(qty) DESC
    '@ 
    
    $Reader = $Query.ExecuteReader([System.Data.CommandBehavior]::SequentialAccess) #get the datareader and just get the result in one gulp
    }
    catch
    {
     $ex = $_.Exception
     Write-Error "whilst executing the query '$($Query.CommandText)' $ex.Message Sorry, but we can't proceed because of this!"
     $Reader.Close()
     $Connection.Close()
     Exit;
    }
    
    Try
    {
    $Counter = $Reader.FieldCount #get it just once
    $result=@() #initialise the empty array of rows
     while ($Reader.Read()) {
     $Tuple = New-Object -TypeName 'System.Management.Automation.PSObject'
     foreach ($i in (0..($Counter - 1))) {
     Add-Member `
     -InputObject $Tuple `
     -MemberType NoteProperty `
     -Name $Reader.GetName($i) `
     -Value $Reader.GetValue($i).ToString()
     }
     $Result+=$Tuple
     }
     $result | Format-Table 
     }
    catch
    {
     $ex = $_.Exceptio
     Write-Error "whilst reading the data from the datatable. $ex.Message"
    }
    $Reader.Close()
    $Connection.Close()