【问题标题】:How to insert a dataframe into a SQL Server table?如何将数据框插入到 SQL Server 表中?
【发布时间】:2012-12-29 09:08:12
【问题描述】:

我正在尝试将数据框上传到 SQL Server 表,我尝试将其分解为一个简单的 SQL 查询字符串..

library(RODBC)
con <- odbcDriverConnect("driver=SQL Server; server=database")

df <- data.frame(a=1:10, b=10:1, c=11:20)

values <- paste("(",df$a,",", df$b,",",df$c,")", sep="", collapse=",")

cmd <- paste("insert into MyTable values ", values)

result <- sqlQuery(con, cmd, as.is=TRUE)

..这似乎工作但不能很好地扩展。有没有更简单的方法?

【问题讨论】:

  • 如果表存在,那么“追加”需要为 TRUE,或者使用 sqlUpdate。如果它不存在,我会坚持使用 sqlSave 中的默认值 (FALSE)。我读到 SQL Server 有一些奇怪的命名约定,但我没有副本,因此无法测试。

标签: r rodbc


【解决方案1】:

这对我有用,我发现它更简单。

library(sqldf)
library(odbc)
con <- dbConnect(odbc(),
                 Driver = "SQL Server",
                 Server = "ServerName",
                 Database = "DBName",
                 UID = "UserName",
                 PWD = "Password")
dbWriteTable(conn = con, 
             name = "TableName", 
             value = x)  ## x is any data frame

【讨论】:

  • dbWriteTable 比 RODBC::sqlSave 快得多
【解决方案2】:

由于insert INTO 限制为1000 行,您可以从rsqlserver 打包dbBulkCopy

dbBulkCopy 是一个 DBI 扩展,它与名为 bcp 的 Microsoft SQL Server 流行的命令行实用程序接口,以快速将大文件批量复制到表中。例如:

url = "Server=localhost;Database=TEST_RSQLSERVER;Trusted_Connection=True;"
conn <- dbConnect('SqlServer',url=url)
## I assume the table already exist
dbBulkCopy(conn,name='T_BULKCOPY',value=df,overwrite=TRUE)
dbDisconnect(conn)

【讨论】:

  • 我无法让 dbBulkCopy 工作...它会产生这样的奇怪错误...clrCallStatic("rsqlserver.net.misc",...中的错误,...然后继续...类型: System.Data.SqlClient.SqlException...我什至不知道是 dbBulkCopy 错误还是 rClr 包错误...您知道它可能是什么吗?
  • @MihaTrošt 您是否设法使用rsqlserver' 的其他功能?最好在rsqlserver issue 中创建问题,我会仔细研究。
  • 我可以使用其他功能,而且,按照这个主题stackoverflow.com/questions/19190744/…,我认为这不是 dbBulkCopy 问题...首先,我没有批量插入权限(我现在有),其次,我尝试 dbBulkCopy 的文件不在安装了 sql server 的机器上,它找不到它。所以...现在,请不要介意我的 cmets,感谢您的宝贵时间。
  • @MihaTrošt 您的文件必须位于数据库服务器可以看到能够进行批量加载的驱动器上。
【解决方案3】:

[已编辑] 也许粘贴 names(df) 可以解决缩放问题:

   values <- paste( " df[  , c(", 
                     paste( names(df),collapse=",") ,
                                   ")] ", collapse="" ) 
      values
      #[1] " df[  , c( a,b,c )] "

您说您的代码正在“工作”。我还认为如果想“上传”,我会使用 sqlSave 而不是 sqlQuery。

我猜这更有可能按照您的描述进行:

 sqlSave(con, df, tablename = "MyTable")

【讨论】:

  • 不确定你想用values 变量做什么,这只会创建一个看起来很奇怪的字符串?!您对尾随逗号的看法是正确的,那将是一个问题。 “额外的引号”是我原来的代码留下的。
  • 这只是为了说明 names(df) 和 "[" 可以用于按列访问 data.frame 比您所做的更抽象。它需要collapse=""collapse="," 才能生效。
  • 假设dataframe和SQL表的列名相同,这是否像在dataframe中一样将数据插入到表的相应列中?还是我需要保持数据框列的顺序与表相同?
  • 粘贴结果中没有目标表列的命名,所以顺序必须正确。
猜你喜欢
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
相关资源
最近更新 更多