[英]How to do a “Select * from” query using odbc
I'm using the odbc package in R, and I have an SQL Server database with a table that has a Name
column that is nvarchar(max)
and a PublishStatus
column that is an integer.我在 R 中使用odbc 包,我有一个 SQL Server 数据库,其中有一个表,该表的
Name
列是nvarchar(max)
, PublishStatus
列是整数。
This code doesn't work:此代码不起作用:
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)
It just produces the error message它只会产生错误信息
Error in result_fetch(res@ptr, n, ...) : nanodbc/nanodbc.cpp:2890: 07009: [Microsoft][ODBC Driver 11 for SQL Server]Invalid Descriptor Index
result_fetch(res@ptr, n, ...) 错误:nanodbc/nanodbc.cpp:2890: 07009: [Microsoft][ODBC Driver 11 for SQL Server]无效的描述符索引
If I attempt to query again, I get a different error message and as best I can tell there is no way to recover without closing R and reopening:如果我再次尝试查询,我会收到一条不同的错误消息,并且我可以告诉您,如果不关闭 R 并重新打开,就无法恢复:
Error: 'select PublishStatus,Name from MyTable' nanodbc/nanodbc.cpp:1587: HY000: [Microsoft][ODBC Driver 11 for SQL Server]Connection is busy with results for another command
错误:'select PublishStatus,Name from MyTable' nanodbc/nanodbc.cpp:1587: HY000: [Microsoft][ODBC Driver 11 for SQL Server]Connection is busy with results for another command
Because both R and R's odbc are terribly named, it's hard to google errors in this package.因为 R 和 R 的 odbc 的名字都非常糟糕,所以很难在这个包中用谷歌搜索错误。 In this SO it appears that the order of the columns matter, and it requires integer columns to be specified first in the query.
在这个 SO中,列的顺序似乎很重要,它需要在查询中首先指定整数列。
So this works所以这有效
query="select PublishStatus,Name from MyTable"
result=NULL
result=dbSendQuery(con,query) %>% dbFetch
head(result)
but this does not:但这不会:
query="select Name,PublishStatus from MyTable"
result=NULL
result=dbSendQuery(con,query) %>% dbFetch
head(result)
and the select *
query does not.而
select *
查询没有。
So my questions are:所以我的问题是:
select *
queries?select *
查询?Invalid Descriptor Index
error, is there a way to recover without restarting R?Invalid Descriptor Index
错误时,有没有办法在不重新启动 R 的情况下恢复? If not, this seems like an awfully bizarre deal breaker for this package.如果没有,这对于这个包裹来说似乎是一个非常奇怪的交易破坏者。
Edit : using the older RODBC library, it doesn't have this flaw, even with the same ODBC driver.编辑:使用旧的 RODBC 库,它没有这个缺陷,即使使用相同的 ODBC 驱动程序。 This works fine with
select * from
queries, and doesn't care about the order of the columns这适用于
select * from
查询,并且不关心列的顺序
library(RODBC)
con=odbcDriverConnect(ConnectionString_Hemonc)
result=sqlQuery(con,query,stringsAsFactors=FALSE)
close(con)
head(result)
I had previously abandoned RODBC because it is unable (in practice) to write data to a database, as I discovered here .我之前放弃了 RODBC,因为它无法(实际上)将数据写入数据库,正如我在此处发现的。
It looks like what happened is they built odbc
to read data faster, and a side effect of that is it's now very picky about the order in which data is read.看起来发生的事情是他们构建了
odbc
来更快地读取数据,其副作用是现在对读取数据的顺序非常挑剔。 Unfortunately, this demolishes my use case--I can't ask folks who only know basic SQL to use a tool that treats perfectly valid SQL as invalid.不幸的是,这破坏了我的用例——我不能要求只知道基本 SQL 的人使用将完全有效的 SQL 视为无效的工具。
I guess it's RODBC
for reading data, odbc
for writing data.我猜是
RODBC
用于读取数据, odbc
用于写入数据。 Yikes.哎呀。
Edit 2 : I tried ODBC Driver 13 for SQL Server
in the connection string instead of ODBC Driver 11
and it didn't fix the problem, but hey at least it was measurably faster.编辑 2 :我在连接字符串中尝试
ODBC Driver 13 for SQL Server
而不是ODBC Driver 11
,但它没有解决问题,但至少它明显更快。
I can hope that the below code and the article will help you.我希望下面的代码和文章能帮助你。 Getting Data From Excel and SQL Server using ODBC
使用 ODBC 从 Excel 和 SQL Server 获取数据
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.