Как использовать dbWriteTable в соединении без базы данных по умолчанию

Я видел много сообщений на SO и DBI Github о проблемах с использованием DBI::dbWriteTable (т.е. [1], [2]). В основном это связано с использованием схем не по умолчанию или чего-то еще.

Это не мой случай.

У меня есть сервер с SQL Server 2014. Этот сервер содержит несколько баз данных.

Я разрабатываю программу, которая одновременно взаимодействует со многими из этих баз данных. Поэтому я определил свое соединение, используя DBI::dbConnect() без аргумента Database=.

До сих пор мне приходилось делать только SELECT для баз данных, и это соединение прекрасно работает с dbGetQuery(). Мне просто нужно назвать свои таблицы, включая имена баз данных: DatabaseFoo.dbo.TableBar, что более чем нормально, поскольку делает вещи прозрачными и преднамеренными. Это также мешает мне быть ленивым и делать некоторые вызовы, опуская имя базы данных в той БД, которую я назвал в соединении.

Теперь мне нужно добавить данные в таблицу, и я не могу заставить ее работать. Звонок в

DBI::dbWriteTable(conn, "DatabaseFoo.dbo.TableBar", myData, append = TRUE)

работает, но создает таблицу с именем DatabaseFoo.dbo.TableBar в базе данных master, что я не имел в виду (я даже не знал, что существует база данных master).

На справочной странице DBI::dbWriteTable указано, что имя должно быть

Строка символов, определяющая имя таблицы СУБД без кавычек или результат вызова dbQuoteIdentifier().

Итак, я попробовал dbQuoteIdentifier() (и несколько других вариантов):

DBI::dbWriteTable(conn,
                  DBI::dbQuoteIdentifier(conn,
                                         "DatabaseFoo.dbo.TableBar"),
                  myData)
# no error, same problem as above

DBI::dbWriteTable(conn,
                  DBI::dbQuoteIdentifier(conn,
                                         DBI::SQL("DatabaseFoo.dbo.TableBar")),
                  myData)
# Error: Can't unquote DatabaseFoo.dbo.TableBar

DBI::dbWriteTable(conn,
                  DBI::SQL("DatabaseFoo.dbo.TableBar"),
                  myData)
# Error: Can't unquote DatabaseFoo.dbo.TableBar

DBI::dbWriteTable(conn,
                  DBI::dbQuoteIdentifier(conn,
                                         DBI::Id(catalog = "DatabaseFoo",
                                                 schema = "dbo",
                                                 table = "TableBar")),
                  myData)
# Error: Can't unquote "DatabaseFoo"."dbo"."TableBar"

DBI::dbWriteTable(conn,
                  DBI::Id(catalog = "DatabaseFoo",
                          schema = "dbo",
                          table = "TableBar"),
                  myData)
# Error: Can't unquote "DatabaseFoo"."dbo"."TableBar"

В попытках DBI::Id() я также пытался использовать cluster вместо catalog. Никакого эффекта, та же ошибка.

Однако если я изменю свой вызов dbConnect(), чтобы добавить аргумент Database="DatabaseFoo", я могу просто использовать dbWriteTable(conn, "TableBar", myData), и это сработает.

Отсюда вопрос, я что-то не так делаю? Связано ли это с проблемами в других вопросах?


person Wasabi    schedule 02.09.2019    source источник
comment
Похоже, проблема исправлена ​​в версии DBI для разработчиков. Не могли бы вы попробовать установить с GitHub и перепроверить?   -  person krlmlr    schedule 03.09.2019
comment
@krlmlr Действительно, установка версии для разработчиков работает. Не стесняйтесь писать ответ для бесплатной галочки.   -  person Wasabi    schedule 05.09.2019


Ответы (1)


Это недостаток пакета DBI. Версия для разработчиков DBI >= 1.0.0.9002 больше не страдает от этой проблемы, скоро она появится в CRAN как DBI 1.1.0.

person Community    schedule 05.09.2019
comment
@MartinSchmelzer: Вы видите точно такие же симптомы? - person krlmlr; 13.05.2020
comment
DBI не использует схему по умолчанию и добавляет новую таблицу перед моим доменным именем и именем пользователя. В итоге я использовал DBI::Id. - person Martin Schmelzer; 13.05.2020