Same dbGetQuery() call via odbc connection gives “Invalid Descriptor Index” error on some PCs but script runs fine on others

試著忘記壹切 提交于 2020-03-03 08:06:50

问题


I have an R script that works fine on my PC. I have sent it to a colleague to use as a source for Power BI, however it does not run (even from base R without Power BI) on their PC.

The issue seems to be with DBI::GetQuery via an odbc connection, and the script is as such (I've changed the names of intellectual property and shortened the very long case_when statements):

Database_connection <- dbConnect(drv = odbc::odbc(),
                               Driver = "SQL Server",
                               server = "addressofserver.database.windows.net",
                               database = "database",
                               uid = "UserName",
                               pwd = "UserPassword")

events_typed<-  dbGetQuery(Database_connection, "


SELECT
--- FIELDS: ---
ThemeEvents.Id as EventId,
[ThemeEvents].[VisitedStoreCode] AS Store_Unique_Number,
CONCAT([dbo].Stores.PostCodeOuter, ' ', [dbo].Stores.PostCodeInner) as Postcode,
Themes.[Name] AS Theme_Name,
ProductCategories.Type As Type,
ProductCategories.ProductType AS ProductType,
CASE -- flag whether Store has been Visited in both Themes (will only work after Themes filter added)
WHEN ThemeEvents.VisitedStoreCode IN (SELECT VisitedStoreCode FROM dbo.ThemeEvents JOIN [dbo].Themes on [dbo].ThemeEvents.Theme_Id = [dbo].Themes.Id WHERE [Themes].[name] = 'Theme One')
AND ThemeEvents.VisitedStoreCode IN (SELECT VisitedStoreCode FROM dbo.ThemeEvents JOIN [dbo].Themes on [dbo].ThemeEvents.Theme_Id = [dbo].Themes.Id WHERE [Themes].[name] = 'Theme Two')
THEN 'TRUE'
ELSE 'FALSE'
End AS Visited_In_Both_Themes,
Sum(ThemeEventSalesLines.[Qty]) as PacksSold
Sum(ThemeEventSalesLines.[SalesSubTotal]) as SalesSubTotal -- 
FROM [dbo].ThemeEvents
-- JOINS: ----
LEFT JOIN [dbo].Themes on [dbo].ThemeEvents.Theme_Id = [dbo].Themes.Id
LEFT JOIN [dbo].Stores on [dbo].ThemeEvents.VisitedStoreCode = [dbo].Stores.StoreCode
LEFT JOIN  ThemeEventSales on ThemeEventSales.EventId = ThemeEvents.Id
LEFT JOIN  ThemeEventSalesLines on ThemeEventSalesLines.ThemeEventSale_Id = ThemeEventSales.Id
LEFT JOIN  ThemeProducts on ThemeProducts.Id = ThemeEventSalesLines.ProductId
LEFT JOIN  ( --put the code for the product categories output here:
SELECT [Id]
,[Name]
,[StandardSKUCode]
,[TypeVariantGroupCode]
,[IsActive]
,[PriceSectorCode]
,CASE 
WHEN [Name] like '%Apple%' THEN 'Fruit'
WHEN [Name] like '%Banana%' THEN 'Fruit'
WHEN [Name] like '%Carrot%' THEN 'Vegetable'
WHEN [Name] like '%Tablecloth%' THEN 'Accessory'
WHEN [Name] like '%Candlestick%' THEN 'Accessory'
WHEN [TypeVariantGroupCode] = 00071 THEN 'Fruit'
ELSE 'False Product/Not Mapped' END AS [Type],
CASE 
WHEN [Name] like '%Apple%' THEN 'Food'
WHEN [Name] like '%Banana%' THEN 'Food'
WHEN [Name] like '%Carrot%' THEN 'Food'
WHEN [Name] like '%Tablecloth%' THEN 'Non-Edible'
WHEN [Name] like '%Candlestick%' THEN 'Non-Edible'
WHEN [TypeVariantGroupCode] = 00071 THEN 'Food'
ELSE 'False Product/Not Mapped' END AS ProductType,
CASE
WHEN [Name] like '%Multipack%' THEN 'TRUE'
ELSE 'FALSE' END AS IsMultipack,
CASE
WHEN [Name] like '%Apple%' AND [Name] like '%British%' THEN 'British Fruit'
WHEN [Name] like '%Carrot%' AND [Name] like '%British%' THEN 'British Vegetable'
WHEN [Name] like '%Carrot%' THEN 'Irish Vegetable'
WHEN [Name] like '%Banana%' AND [Name] like '%Jamaican%' THEN 'Jamaican Fruit'
WHEN [TypeVariantGroupCode] = 00071 THEN 'Unidentified Fruit'
WHEN [Name] like '%Apple%' THEN 'Unidentified Fruit'
ELSE NULL END as TypeLocation
FROM [dbo].[Products]
) AS ProductCategories 
ON ProductCategories.Id = ThemeProducts.ProductId --- join to Theme products table not to products table here
--- CONDITIONS & GROUPING: ---
where VisitedStoreCode NOT LIKE '%p%'
and ([Themes].[name] = 'Theme One' -- I have checked and the names are correct
or [Themes].[name] = 'Theme Two')
group by ThemeEvents.Id, VisitedStoreCode, Themes.[Name], CONCAT([dbo].Stores.PostCodeOuter, ' ', [dbo].Stores.PostCodeInner), Type, ProductType, RebateGiven, ThemeEvents.PacksSold
order by EventId
")

Which returns the error message (in Power BI):

Error in result_fetch(res@ptr, n) : 
  nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC SQL Server Driver]Invalid Descriptor Index 
Calls: dbGetQuery ... dbGetQuery -> .local -> dbFetch -> dbFetch -> result_fetch
Execution halted
Warning message:
In dbClearResult(rs) : Result already cleared

And when ran in Base R:

Error in result_fetch(res@ptr, n) : 
  nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC SQL Server Driver]Invalid Descriptor Index

The SQL script itself runs fine when used to read from the database directly in Power BI (this is not useful as the rest of the R script modifies it considerably after import), but it does not run within the R script/dbGetQuery call on their computer. However as stated it runs fine on my own PC. We have installed all the required libraries for the script and checked that they are installed.

Additionally, a more basic query such as:

test<-  dbGetQuery(Database_connection, "SELECT TOP 10 * FROM dbo.ThemeEvents")

works perfectly fine.

All the previous questions about this error message imply it's something to do with the structure of the query or SQL database, or the order of columns in the output, but both of us are running the same query against the same database in the same R script, using the same credentials. Does anyone know why it might generate an error on one computer but not another? I can't work out how to fix it because it already runs fine on my own PC, but I want it to be capable of being ran by other colleagues so that they can use it in their Power BI reports (they do not code in R themselves).


回答1:


Underneath the [R]/package:odbc layer, there sits an ODBC driver that is responsible for the ODBC API implementation.

To answer your question re: why you might be seeing an error on one machine, but not on another, it could be the case that on different machines package:odbc is paired with different drivers (that come with their own idiosyncrasies). For example, the SQL Server driver from Microsoft is known to throw the error you logged, however other ones (I believe, including the open source FreeTDS driver) do not.

odbc::odbcListDrivers() can give you an idea which drivers are available on the machine you are using.



来源:https://stackoverflow.com/questions/59455111/same-dbgetquery-call-via-odbc-connection-gives-invalid-descriptor-index-erro

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!