Функция SQL не работает при попытке записать таблицу в схему, отличную от стандартной

Я пытаюсь написать таблицу в схеме, отличной от схемы по умолчанию, в SQL Server 2017. Я использую документацию RStudio, чтобы узнать, как лучше всего это сделать: https://db.rstudio.com/best-practices/schema/#write-non-temporary-tables.

Однако, когда я следую их рекомендациям, я получаю следующую ошибку: Error: Can't unquote EXISTING_SCHEMA.newTbleIris

РЕДАКТИРОВАТЬ

После некоторого копания я добился некоторого прогресса. Но проблема не решена полностью. Я обнаружил, что функция Id() позволяет мне читать, но не писать. Пример ниже. Ошибка, которую я получаю при попытке написать:

Error in connection_sql_tables(conn@ptr, catalog_name = if ("catalog" %in% : nanodbc/nanodbc.cpp:2525: 24000: [Microsoft][ODBC SQL Server Driver]Invalid cursor state

Новый воспроизводимый пример

library(odbc)
library(dbplyr)
library(dplyr)
library(DBI)

con <- dbConnect(odbc(),
                 Driver = "SQL SERVER",
                 Server = "SERVER_NAME",
                 Database = "DB_NAME",
                 UID = "USER_NAME",
                 PWD = "PASSWORD")

# Works assuming you already have iris table in EXISTING SCHEMA.
# I did this not in R because I cannot currently write to a non-default schema in R.
dbReadTable(con, Id(schema = "EXISTING_SCHEMA", name = "iris"))

# Still cannot write to non-default schema Throws an error.
dbWriteTable(con, Id(schema = "nycDoe", name = "iris"), iris)

Воспроизводимый пример

library(odbc)
library(dbplyr)
library(dplyr)
library(DBI)

con <- dbConnect(odbc(),
                 Driver = "SQL SERVER",
                 Server = "SERVER_NAME",
                 Database = "DB_NAME",
                 UID = "USER_NAME",
                 PWD = "PASSWORD")

# this works, writing to default schema
dbWriteTable(con, SQL("newTbleIris"), iris)

# this does NOT work and gives error mentioned above
dbWriteTable(con, SQL("EXISTING_SCHEMA.newTbleIris"), iris)

Информация о сеансе

- Session info --------------------------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.5.2 (2018-12-20)
 os       Windows Server >= 2012 x64  
 system   x86_64, mingw32             
 ui       RStudio                     
 language (EN)                        
 collate  English_United States.1252  
 ctype    English_United States.1252  
 tz       America/New_York            
 date     2019-03-07                  

- Packages ------------------------------------------------------------------------------------------------------------------------
 package     * version date       lib source        
 assertthat    0.2.0   2017-04-11 [1] CRAN (R 3.5.2)
 backports     1.1.3   2018-12-14 [1] CRAN (R 3.5.2)
 bit           1.1-14  2018-05-29 [1] CRAN (R 3.5.2)
 bit64         0.9-7   2017-05-08 [1] CRAN (R 3.5.2)
 blob          1.1.1   2018-03-25 [1] CRAN (R 3.5.2)
 callr         3.1.1   2018-12-21 [1] CRAN (R 3.5.2)
 cli           1.0.1   2018-09-25 [1] CRAN (R 3.5.2)
 crayon        1.3.4   2017-09-16 [1] CRAN (R 3.5.2)
 DBI         * 1.0.0   2018-05-02 [1] CRAN (R 3.5.2)
 dbplyr      * 1.3.0   2019-01-09 [1] CRAN (R 3.5.2)
 desc          1.2.0   2018-05-01 [1] CRAN (R 3.5.2)
 devtools      2.0.1   2018-10-26 [1] CRAN (R 3.5.2)
 digest        0.6.18  2018-10-10 [1] CRAN (R 3.5.2)
 dplyr       * 0.8.0.1 2019-02-15 [1] CRAN (R 3.5.2)
 fs            1.2.6   2018-08-23 [1] CRAN (R 3.5.2)
 glue          1.3.0   2018-07-17 [1] CRAN (R 3.5.2)
 hms           0.4.2   2018-03-10 [1] CRAN (R 3.5.2)
 htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.5.2)
 httpuv        1.4.5.1 2018-12-18 [1] CRAN (R 3.5.2)
 jsonlite      1.6     2018-12-07 [1] CRAN (R 3.5.2)
 later         0.8.0   2019-02-11 [1] CRAN (R 3.5.2)
 magrittr      1.5     2014-11-22 [1] CRAN (R 3.5.2)
 memoise       1.1.0   2017-04-21 [1] CRAN (R 3.5.2)
 mime          0.6     2018-10-05 [1] CRAN (R 3.5.2)
 odbc        * 1.1.6   2018-06-09 [1] CRAN (R 3.5.2)
 pillar        1.3.1   2018-12-15 [1] CRAN (R 3.5.2)
 pkgbuild      1.0.2   2018-10-16 [1] CRAN (R 3.5.2)
 pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.5.2)
 pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.5.2)
 prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.5.2)
 processx      3.2.1   2018-12-05 [1] CRAN (R 3.5.2)
 promises      1.0.1   2018-04-13 [1] CRAN (R 3.5.2)
 ps            1.3.0   2018-12-21 [1] CRAN (R 3.5.2)
 purrr       * 0.3.0   2019-01-27 [1] CRAN (R 3.5.2)
 R6            2.4.0   2019-02-14 [1] CRAN (R 3.5.2)
 Rcpp          1.0.0   2018-11-07 [1] CRAN (R 3.5.2)
 remotes       2.0.2   2018-10-30 [1] CRAN (R 3.5.2)
 rlang         0.3.1   2019-01-08 [1] CRAN (R 3.5.2)
 rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.5.2)
 rstudioapi    0.9.0   2019-01-09 [1] CRAN (R 3.5.2)
 sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.5.2)
 shiny       * 1.2.0   2018-11-02 [1] CRAN (R 3.5.2)
 tibble        2.0.1   2019-01-12 [1] CRAN (R 3.5.2)
 tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.5.2)
 usethis       1.4.0   2018-08-14 [1] CRAN (R 3.5.2)
 withr         2.1.2   2018-03-15 [1] CRAN (R 3.5.2)
 xtable        1.8-3   2018-08-29 [1] CRAN (R 3.5.2)

person drizzle123    schedule 11.03.2019    source источник
comment
Проверьте это: github.com/r-dbi/odbc/issues/197   -  person Alex    schedule 12.03.2019
comment
Так что я видел это, и это вроде как работает. Например, работает dbReadTable(con, Id(schema = "EXISTING_SCHEMA", name = "iris")) (при условии, что у вас уже есть таблица в этой схеме). Однако dbWriteTable(con, Id(schema = "EXISTING_SCHEMA", name = "iris"), iris) не работает и выдает ошибку Error in connection_sql_tables(conn@ptr, catalog_name = if ("catalog" %in% : nanodbc/nanodbc.cpp:2525: 24000: [Microsoft][ODBC SQL Server Driver]Invalid cursor state   -  person drizzle123    schedule 12.03.2019
comment
Можете ли вы попробовать более новые дженерики dbCreateTable() и dbAppendTable()?   -  person krlmlr    schedule 13.03.2019
comment
Использовал dbCreateTable() и dbAppendTable(), чтобы попытаться записать таблицу в схему, отличную от стандартной. Но это не удалось. ##### Tables are created, but they are all empty dbCreateTable(con, SQL("EXISTING_SCHEMA.iris3"), iris) dbAppendTable(con, SQL("EXISTING_SCHEMA.iris3"), iris) iris3 <- dbReadTable(con, SQL("EXISTING_SCHEMA.iris3")) queryIris3 <- dbGetQuery(con, "SELECT * FROM EXISTING_SCHEMA.iris3")   -  person drizzle123    schedule 19.03.2019
comment
Аналогичным образом я пытался использовать Id(), а не SQL(), но результат тот же. Стол пуст. dbAppendTable() на самом деле не добавляется. dbCreateTable(con, Id(schema = "EXISTING_SCHEMA", table = "iris4"), iris) dbAppendTable(con, Id(schema = "EXISTING_SCHEMA", table = "iris4"), iris) iris4 <- dbReadTable(con, Id(schema = "EXISTING_SCHEMA", table = "iris4"), iris) queryIris4 <- dbGetQuery(con, "SELECT * FROM EXISTING_SCHEMA.iris4")   -  person drizzle123    schedule 19.03.2019
comment
Как ни странно, у меня возникает похожая проблема, даже когда я пытаюсь работать с таблицами в схеме по умолчанию. dbAppendTable() по-прежнему не добавляется. dbCreateTable(con, "iris2", iris) dbAppendTable(con, "iris2", iris) iris2 <- dbReadTable(con, "iris2") queryIris2 <- dbGetQuery(con, "SELECT * FROM iris2")   -  person drizzle123    schedule 19.03.2019


Ответы (3)


Я нашел простой обходной путь для этого. Просто выполните следующие действия:

Сначала напишите таблицу со схемой по умолчанию: dbWriteTable(con, "newTbleIris", iris)

И вставляем его в новый со схемой не по умолчанию, но на этот раз с помощью функции dbGetQuery:

dbGetQuery(con, "SELECT * INTO [schema].newTbleIris FROM newTbleIris")

Вот и все! Теперь ваша таблица будет отображаться со схемой, отличной от стандартной.

Теперь вы можете удалить первую таблицу, которую вы впервые создали со схемой по умолчанию, выполнив dbGetQuery(con, "DROP TABLE newTbleIris")

person Walt Peralta    schedule 03.04.2019
comment
Это очень полезный обходной путь! Надеюсь, в будущем разработчики пакета исправят эту проблему. - person drizzle123; 17.04.2019
comment
Итак, я действительно столкнулся с проблемой, используя ваш метод, и мне интересно, есть ли у вас такая же проблема. Сначала я пишу таблицу dbWriteTable(con, "iris", iris). Затем я копирую таблицу dbExecute(con, "SELECT * INTO [schema].iris FROM iris"). Finally, I drop the table I initially added into the default schema dbExecute(con, DROP TABLE iris). Однако, когда я запускаю `dbExistsTable(con, iris), я получаю возвращаемое значение TRUE. - person drizzle123; 18.06.2019
comment
Это означает, что таблица существует на вашем сервере sql с новой схемой. - person Walt Peralta; 24.06.2019
comment
Верно. Но dbExistsTable() должен возвращать true только для [schema].iris. В моем вызове функции я не указываю схему, и я бы подумал, что она будет проверять только схему по умолчанию. Однако это не так, поэтому он возвращает true. Однако это приводит к проблемному поведению в будущем, потому что, если я попытаюсь записать в схему по умолчанию, используя имя таблицы iris, это не позволит мне. Потому что он думает, что таблица уже существует. Надеюсь, это понятно. - person drizzle123; 27.06.2019

В моем случае выполнение dbWriteTable(con, "[schema].newTbleIris", iris) без переноса какой-либо функции сработало.

person Jas    schedule 14.05.2019
comment
Да, это не работает для меня. Можете ли вы опубликовать более подробную информацию о том, как ваша среда? Я пробовал с символами [ ] и без этих символов. - person drizzle123; 11.06.2019
comment
Эй, дождь, точный синтаксис, который я использую, без [] вокруг имени схемы. Вы тоже пробовали это? dbWriteTable(con, "schema.tablename", dt) - person Jas; 13.06.2019
comment
Ага. Я пробовал с символами [] и без них, и ничего не работает. В результате таблица записывается в схему по умолчанию как schema.tablename. - person drizzle123; 14.06.2019

DBI 1.1.0 решает эту проблему.

dbWriteTable(con, SQL("schema.newTbleIris"), iris)
person Zaki    schedule 13.11.2020
comment
Мне пришлось обновить DBI до 1.1.0, а также odbc до 1.3.0, а затем использовать функцию SQL, например. dbWriteTable(con, SQL(SCHEMA.TABLE), значение = таблица, row.names = FALSE, перезаписать = FALSE, добавить = TRUE). Это сработало. - person Chris; 08.12.2020