我想使用R脚本在数据库的现有表中输入数据帧,并且希望数据库中的表具有顺序的主键。我的问题是RODBC似乎不允许主键约束。
这是用于创建我想要的表的SQL:
CREATE TABLE [dbo].[results] ( [ID] INT IDENTITY (1, 1) NOT NULL, [FirstName] VARCHAR (255) NULL, [LastName] VARCHAR (255) NULL, [Birthday] DATETIME NULL, [CreateDate] DATETIME NULL, CONSTRAINT [PK_dbo.results] PRIMARY KEY CLUSTERED ([ID] ASC) );
以及带有一些R代码的测试:
ConnectionString1="Driver=ODBC Driver 11 for SQL Server;Server=myserver; Database=TestDb; trusted_connection=yes" ConnectionString2="Driver=ODBC Driver 11 for SQL Server;Server=notmyserver; Database=TestDb; trusted_connection=yes" db1=odbcDriverConnect(ConnectionString1) query="SELECT a.[firstname] as FirstName , a.[lastname] as LastName , Cast(a.[dob] as datetime) as Birthday , cast(a.createDate as datetime) as CreateDate FROM [dbo].[People] a" results=NULL results=sqlQuery(db1,query,stringsAsFactors=FALSE) close(db1) db2=odbcDriverConnect(ConnectionString) sqlSave(db2, results, append = TRUE, varTypes=c(Birthday="datetime", CreateDate="datetime"), colnames = FALSE, rownames = FALSE,fast=FALSE) close(db2)
R代码的第一部分只是将一些测试数据放入一个数据帧中- 正常工作,这不是我的问题的一部分(我只是在此处包括它,以便您可以看到测试数据的格式)。当我运行该sqlSave函数时,我收到一条错误消息:
sqlSave
dimnames(x)<-dn中的错误:’dimnames’[2]的长度不等于数组范围
但是,如果我从数据库中删除了主键,则该表的所有功能都可以正常工作:
CREATE TABLE [dbo].[results] ( [FirstName] VARCHAR (255) NULL, [LastName] VARCHAR (255) NULL, [Birthday] DATETIME NULL, [CreateDate] DATETIME NULL );
显然,主键是问题。通常使用实体框架或其他任何形式(据我所知),当您输入数据时,主键是在数据库中创建的。
我想要一种仅使用R脚本使用主键将数据附加到表的方法。那可能吗?我要添加到表中的数据可能已经存在,因此在尝试追加到表之前,我真的没有看到在R中创建键的方法。
问题是http://github.com/cran/RODBC/blob/master/R/sql.R中的361行-data.frame和DB表必须具有完全相同的列数,否则将出现此错误此堆栈跟踪:
Error in dimnames(x) <- dn : length of 'dimnames' [2] not equal to array extent 3. `colnames<-`(`*tmp*`, value = c("ID", "FirstName", "LastName", "Birthday", "CreateDate")) at sql.R#361 2. sqlwrite(channel, tablename, dat, verbose = verbose, fast = fast, test = test, nastring = nastring) at sql.R#211 1. sqlSave(db2, results, append = TRUE, varTypes = c(Birthday = "datetime", CreateDate = "datetime"), colnames = FALSE, rownames = FALSE, fast = FALSE, verbose = TRUE)
如果将ID列添加到您的ID列中,data.frame则无法再使用autoincID列,因此这不是解决方案(或解决方法)。
data.frame
autoinc
对于“相同列”的限制,一种“简单”的解决方法RODBC::sqlSave是:
RODBC::sqlSave
insert into ... select from ...
RODBC::sqlQuery
drop table...
更好的选择是使用新的odbc程序包,该程序包也可以通过类似批量的插入来提供更好的性能,而不是insert像单行那样发送单个语句RODBC:
odbc
insert
RODBC
https://github.com/r-dbi/odbc
寻找功能dbWriteTable(这是interface的实现DBI::dbWriteTable)。
dbWriteTable
DBI::dbWriteTable