R中的ODBC / DBI不会写入R中具有非默认架构的表

时间:2017-07-27 16:05:42

标签: sql sql-server r odbc r-dbi

问题

尝试写入包DBI中的非默认架构dbWriteTable的表时,写入default.non-default.tablename而不是写入non-default.tablename。我知道non-default.tablename存在,因为它出现在我的SSMS数据库中。

可重复的示例/我尝试过的内容

使用非默认架构“guest”在SQL Server中创建此表。我将它放在一个名为“SAM”的数据库中:

CREATE TABLE guest.MikeTestTable(
[a] [float] NULL,
[b] [float] NULL,
[c] [varchar](255) NULL)

#Create a df to insert into guest.MikeTestTable
df <- data.frame(a = c(10, 20, 30),
                 b = c(20, 40, 60),
                 c = c("oneT", "twoT", "threeT"))

#Create a connection:
con <- DBI::dbConnect(odbc::odbc(),
             .connection_string = "Driver={SQL Server};
                                   server=localhost;
                                   database=SAM;
                                   trustedConnection=true;")

#Try to write contents of df to the table using `dbWriteTable`
DBI::dbWriteTable(conn = con,
                  name = "guest.MikeTestTable",
                  value = df,
                  append = TRUE)

#Create a query to read the data from `"guest.MikeTestTable"`:
q <- "SELECT [a]
  ,[b]
  ,[c]
  FROM guest.MikeTestTable"

##Read the table into R to show that nothing actually got written to the 
##table but that it recognizes `guest.MikeTestTable` does exist:
DBI::dbGetQuery(con, q)

[1] a b c
<0 rows> (or 0-length row.names)

我认为这是一个奇怪的结果,所以我打开了我的SSMS并且看到了,dbo.guest.MikeTestTable表被创建了。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

请参阅here了解答案

答案 1 :(得分:1)

上周发布的CRAN(与@ user111417链接的问题相关)使用新的DBI::Id()函数解决了这个问题,其中模式和表名是独立且明确的。这是一个例子。

library(magrittr)
table_id <- DBI::Id(
  schema  = "schema_1",
  table   = "car"
)

ds <- mtcars %>% 
  tibble::rownames_to_column("car")

# Create the Table
channel <- DBI::dbConnect(
  drv   = odbc::odbc(),
  dsn   = "cdw_cache"
)
result <- DBI::dbWriteTable(
  conn        = channel,
  name        = table_id,
  value       = ds,
  overwrite   = T,
  append      = F
)

DBI::dbGetQuery(channel, "SELECT COUNT(*) FROM schema_1.car")
# Produces `1 32`

DBI::dbExistsTable(channel, table_id)
# Produces: [1] TRUE

DBI::dbDisconnect(channel)

(感谢Daniel Wood在https://github.com/r-dbi/odbc/issues/191寻求帮助。)