Как сделать запрос «Выбрать * из» с помощью odbc - PullRequest
0 голосов
/ 21 мая 2018

Я использую пакет odbc в 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)

Он просто выдает сообщение об ошибке

Ошибка в result_fetch (res @ ptr, n,...): nanodbc / nanodbc.cpp: 2890: 07009: [Microsoft] [ODBC Driver 11 для SQL Server] Индекс недопустимых дескрипторов

Если я попытаюсь выполнить запрос снова, я получу другое сообщение об ошибкеи, насколько я могу судить, невозможно восстановить без закрытия R и повторного открытия:

Ошибка: «выберите PublishStatus, имя из MyTable» nanodbc / nanodbc.cpp: 1587: HY000: [Microsoft][Драйвер ODBC 11 для SQL Server] Соединение занято результатами для другой команды

Поскольку оба odbc для R и R ужасно названы, в этом пакете сложно погуглить ошибки Google.В этом 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. Есть ли способ сделать это, чтобы я мог сделать select * запросов?
  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, поскольку не может (на практике) записать данные вбаза данных, как я обнаружил здесь .

Похоже, что произошло, они построили odbc для более быстрого чтения данных, и побочным эффектом этого является то, что теперь он очень требователен к порядку, в котором данныечитать.К сожалению, это разрушает мой вариант использования - я не могу просить людей, которые знают только базовый SQL, использовать инструмент, который рассматривает совершенно допустимый SQL как недопустимый.

Я думаю, это RODBC для чтения данных, odbc для записи данных.Yikes.

Edit 2 : я попытался ODBC Driver 13 for SQL Server в строке подключения вместо ODBC Driver 11, и это не решило проблему, но, по крайней мере, это было заметно быстрее.

1 Ответ

0 голосов
/ 29 октября 2018

Я могу надеяться, что приведенный ниже код и статья помогут вам. Получение данных из Excel и SQL Server с использованием 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() 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...