gpt4 book ai didi

sql - 如何使用 RODBC 将数据帧保存到数据库生成的主键表

转载 作者:行者123 更新时间:2023-12-03 00:18:47 26 4
gpt4 key购买 nike

我想使用 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 函数时,我收到一条错误消息:

Error in dimnames(x) <- dn : length of 'dimnames' [2] not equal to array extent

但是,如果我从数据库中删除主键,则该表的一切正常:

CREATE TABLE [dbo].[results] (
[FirstName] VARCHAR (255) NULL,
[LastName] VARCHAR (255) NULL,
[Birthday] DATETIME NULL,
[CreateDate] DATETIME NULL
);

显然主键是问题所在。通常,使用 Entity Framework 或其他框架(据我了解),当您输入数据时,主键是在数据库中创建的。

我想要一种仅使用 R 脚本将数据附加到具有主键的表的方法。那可能吗?我要添加到的表中可能已经有数据,因此在尝试附加到表之前,我确实没有找到在 R 中创建键的方法。

最佳答案

问题出在 http://github.com/cran/RODBC/blob/master/R/sql.R 中的第 361 行- data.frame 和数据库表必须具有完全相同的列数,否则您会在堆栈跟踪中收到此错误:

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 列添加到 data.frame 中,您将无法再使用 autoinc ID 列,因此这不是解决方案(或解决方法)。

解决 RODBC::sqlSave 的“相同列”限制的“简单”解决方法是:

  1. 使用sqlSave将新行保存到另一个表名中
  2. 通过 RODBC::sqlQuery 发送insert into ... select from ...,将新行附加到包含 autoinc ID 的原始表中栏目
  3. 再次删除包含新行的表格(删除表格...)

更好的选择是使用新的 odbc 包,该包还通过批量插入提供更好的性能,而不是像 RODBC< 那样发送单个 insert 语句 的作用:

https://github.com/r-dbi/odbc

查找函数dbWriteTable(它是接口(interface)DBI::dbWriteTable的实现)。

关于sql - 如何使用 RODBC 将数据帧保存到数据库生成的主键表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50308125/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com