2015-12-01 3 views
0

Я работаю в R на наборе данных, предоставляемом в MS Access. Поскольку я стараюсь сделать свой код воспроизводимым, я хочу избегать делать что-либо с данными с помощью Access.RODBC таблица чтения от Access с нестандартным именем

база данных содержит несколько таблиц, которые имеют не-ASCII символы (персидские имена)

подключиться к базе данных:

cns <- odbcConnectAccess2007(mdbfilename) 

, когда я получаю список таблиц с:

tbls <- sqlTables(cns) 
head(tbls ,10) 

Я получаю что-то вроде этого:

    TABLE_CAT TABLE_SCHEM     TABLE_NAME TABLE_TYPE REMARKS 
1 D:\\HEIS\\DataRAW\\80.mdb  <NA>   MSysAccessObjects SYSTEM TABLE <NA> 
2 D:\\HEIS\\DataRAW\\80.mdb  <NA>     MSysACEs SYSTEM TABLE <NA> 
3 D:\\HEIS\\DataRAW\\80.mdb  <NA> MSysNavPaneGroupCategories SYSTEM TABLE <NA> 
4 D:\\HEIS\\DataRAW\\80.mdb  <NA>   MSysNavPaneGroups SYSTEM TABLE <NA> 
5 D:\\HEIS\\DataRAW\\80.mdb  <NA> MSysNavPaneGroupToObjects SYSTEM TABLE <NA> 
6 D:\\HEIS\\DataRAW\\80.mdb  <NA>  MSysNavPaneObjectIDs SYSTEM TABLE <NA> 
7 D:\\HEIS\\DataRAW\\80.mdb  <NA>    MSysObjects SYSTEM TABLE <NA> 
8 D:\\HEIS\\DataRAW\\80.mdb  <NA>    MSysQueries SYSTEM TABLE <NA> 
9 D:\\HEIS\\DataRAW\\80.mdb  <NA>   MSysRelationships SYSTEM TABLE <NA> 
10 D:\\HEIS\\DataRAW\\80.mdb  <NA> R80P1 روستا?? 80 بخش ?ک  TABLE <NA> 

Как вы можете видеть, имя таблицы в строке 10 содержит нестандартные символы. Имя таблицы, показанной в MS-Access, - R80P1 روستایی 80 بخش یک. Поскольку MS-Access пытается отправить имя в локали системы (которая является персидской), она преобразует данные в кодировку Windows-Arabic (кодовая страница 1256), которая не содержит код для Персидского Yeh (ی) (который отличается от арабского Yeh (ي)).

Это делает невозможным чтение данных в таблице из R, как мы на самом деле не имеют название:

tbl <- tbls[10,3] 
RD <- sqlQuery(cns,paste0("Select Address from ",tbl)) 
head(RD) 

Я получаю эту ошибку:

[1] "07002 17 [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect "    
[2] "[RODBC] ERROR: Could not SQLExecDirect 'Select Address from R80P1 روستا?? 80 بخش ?ک'" 

Я пытался решить эту проблему по-разному

  1. Переименовать таблицы в MS-Access, так как мой скрипт будет загружать 30+ файлов из Интернета, d читать их, это не кажется целесообразным для этого ручного переименования для одного из файлов (с этим странным наименованием) в середине процесса.
  2. Измените кодировку при открытии соединения, я пробовал это со всеми 374 кодировками, доступными с iconvlist(), не решает проблему. Важным случаем: открытие соединения ODBC с использованием UTF-8, приводит к возврату имен проблемных таблиц как NA.
  3. Попробуйте прочитать таблицу не по имени, а по индексу в базе данных, но я не знаю, как сделать это с помощью RODBC (я знаю, что индекс по grepl ИНГАМ начальной части названия на латыни)
  4. Попробуйте используйте sqlFetch() с пользовательским SQL-запросом, который использует регулярное выражение для имени таблицы, я не знаю, как это сделать или даже если это возможно.

Любые предложения?

Edit: я должен добавить мой sessionInfo():

R version 3.2.2 (2015-08-14) 
Platform: x86_64-w64-mingw32/x64 (64-bit) 
Running under: Windows 8 x64 (build 9200) 

locale: 
[1] LC_COLLATE=Persian_Iran.1256 LC_CTYPE=Persian_Iran.1256 LC_MONETARY=Persian_Iran.1256 
[4] LC_NUMERIC=C     LC_TIME=Persian_Iran.1256  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] data.table_1.9.6 foreign_0.8-65 RODBC_1.3-12  yaml_2.1.13  

loaded via a namespace (and not attached): 
[1] tools_3.2.2 chron_2.3-47 

P.S.Для тех, кто заинтересован в борьбе с актуальной проблемой, файл я говорю о том, доступен для скачивания: http://www.amar.org.ir/Portals/0/amarmozuii/hazinedaramad/80.rar (~ 18 MB)

+1

В вашем названии таблицы есть пробелы. Попробуйте заключить в скобки '[]'. Кроме того, R показывает правильный символ Персидского Yeh в списке таблиц и даже в сообщении об ошибке. – Parfait

+1

Как говорит @Parfait, 'SELECT COUNT (*) AS n FROM [R80P1 روستایی 80 بخش یک]' работает для меня (в C#, используя 'System.Data.Odbc', в любом случае). –

+0

@parfait и @ gord-thompson, я попытался включить имя таблицы в скобках [], но это не сработало, и, как вы можете видеть в вопросе, R не отображает правильный символ Персидского Yeh в списке таблиц для меня. Я знаю, что это не ошибка R, или даже MS-Access, поскольку каждый из них отлично справляется с персидским языком. Возможно, ваш язык отличается, и это помогает. не могли бы вы добавить результаты 'Sys.locale()' здесь? –

ответ

1

this is not R's fault, or even MS-Access, as they each do fine with Persian.

Казалось бы, ограничение RODBC, который действительно кажется полагайтесь на языковой стандарт Windows для интерпретации кодировки символов имен таблиц. Когда я пытаюсь

> tbls <- sqlTables(cns) 
> head(tbls, 10) 

Я получаю

    TABLE_CAT TABLE_SCHEM     TABLE_NAME 
1 C:\\__tmp\\zzzTest\\80.MDB  <NA>   MSysAccessObjects 
2 C:\\__tmp\\zzzTest\\80.MDB  <NA>     MSysACEs 
3 C:\\__tmp\\zzzTest\\80.MDB  <NA> MSysNavPaneGroupCategories 
4 C:\\__tmp\\zzzTest\\80.MDB  <NA>   MSysNavPaneGroups 
5 C:\\__tmp\\zzzTest\\80.MDB  <NA> MSysNavPaneGroupToObjects 
6 C:\\__tmp\\zzzTest\\80.MDB  <NA>  MSysNavPaneObjectIDs 
7 C:\\__tmp\\zzzTest\\80.MDB  <NA>    MSysObjects 
8 C:\\__tmp\\zzzTest\\80.MDB  <NA>    MSysQueries 
9 C:\\__tmp\\zzzTest\\80.MDB  <NA>   MSysRelationships 
10 C:\\__tmp\\zzzTest\\80.MDB  <NA> R80P1 ??????? 80 ??? ?? 

, потому что мой Windows, локаль, английский (США), не признает любой персидских/арабских букв. Кроме того, я не могу запросить таблицу, даже если я указать его имя непосредственно

> RD <- sqlQuery(cns, 'SELECT Address FROM [R80P1 روستایی 80 بخش یک]') 
> head(RD) 
[1] "42S02 -1305 [Microsoft][ODBC Microsoft Access Driver] The Microsoft Access database engine cannot find the input table or query 'R80P1 <U+0631><U+0648><U+0633><U+062A><U+0627><U+06CC><U+06CC> 80 <U+0628><U+062E><U+0634> <U+06CC><U+06A9>'. Make sure it exists and that its name is spelled correctly." 
[2] "[RODBC] ERROR: Could not SQLExecDirect 'SELECT Address FROM [R80P1 <U+0631><U+0648><U+0633><U+062A><U+0627><U+06CC><U+06CC> 80 <U+0628><U+062E><U+0634> <U+06CC><U+06A9>]'"                                 

Если вы не хотите, чтобы переименовать таблицы в исходной базе данных, то вы могли бы рассмотреть следующие обходные пути:

  • Создайте новую базу данных Access с именем «80links.accdb».
  • Используйте External Data > Import & Link > Access для создания таблицы , связанной с таблицей, которая указывает на таблицу [R80P1 روستایی 80 بخش یک] в исходной базе данных («80.MDB»).
  • Переименуйте связанную таблицу, чтобы использовать английское имя без пробелов, например [Section_80_rural_R80P1]
  • Запустите ваши запросы по связанной таблице.
> mdbfilename <- 'C:\\__tmp\\zzzTest\\80links.accdb' 
> cns <- odbcConnectAccess2007(mdbfilename) 
> RD <- sqlQuery(cns, 'Select Address from Section_80_rural_R80P1') 
> head(RD) 
    Address 
1 11001 
2 11001 
3 11001 
4 11001 
5 11001 
6 11001 
Смежные вопросы