我开发了一项在线调查,将我的数据存储在Microsoft SQL 2005数据库中。我已经在R中对我的数据写了一组离群值检查。这些脚本的一般工作流程是:
我写回的表格有以下结构:
CREATE TABLE outliers2(
modelid int
, password varchar(50)
, reason varchar(50),
Constraint PK_outliers2 PRIMARY KEY(modelid, reason)
)
GO
如您所见,我将主键设置为modelid和reason。同一受访者可能是多次检查的异常值,但我不想为任何受访者插入相同的modelid和reason组合。
由于我们仍在收集数据,因此我希望能够每天/每周更新这些脚本,因为我开发了我估算的数据模型。以下是我正在使用的sqlSave()
命令的一般形式:
sqlSave(db, db.insert, "outliers2", append = TRUE, fast = FALSE, rownames = FALSE)
其中db
是有效的ODBC连接,db.insert
的格式为
> head(db.insert)
modelid password reason
1 873 abkd WRONG DIRECTION
2 875 ab9d WRONG DIRECTION
3 890 akdw WRONG DIRECTION
4 905 pqjd WRONG DIRECTION
5 941 ymne WRONG DIRECTION
6 944 okyt WRONG DIRECTION
sqlSave()
在尝试插入违反主键约束但未继续插入其他记录的行时会发生阻塞。我原以为设置fast = FALSE
会缓解这个问题,但事实并非如此。
有关如何解决此问题的任何想法?我可以在第一个脚本的开头drop
表,但这看起来非常沉重,无疑会导致问题。
答案 0 :(得分:2)
在这种情况下,一切都按预期工作。您将所有内容作为批处理上载,SQL Server在发现错误时立即停止批处理。不幸的是,我不知道一个优雅的内置解决方案。但是,我认为可以在数据库中构建一个系统来更有效地处理这个问题。我喜欢在数据库中而不是在R中进行数据存储/管理,所以我的解决方案非常重要。其他人可能会为您提供更加面向R的解决方案。
首先,创建一个没有约束的简单表来保存新行并相应地调整sqlSave语句。这是R将信息上传到的地方。
CREATE TABLE tblTemp(
modelid int
, password varchar(50)
, reason varchar(50)
, duplicate int()
)
GO
将信息放入此表的查询应该对“重复”列假定为“否”。我使用的模式是1 = Y& 5 = N。你也可以只标记那些异常值,但我倾向于明确我的逻辑。
您还需要一个地方来转储违反PK的所有行,包括异常值2。
CREATE TABLE tblDuplicates(
modelid int
, password varchar(50)
, reason varchar(50)
)
GO
行。现在您需要做的就是创建一个触发器,将新行从tblTemp移动到outliers2。此触发器将所有重复的行移动到tblDuplicates,以便以后处理,删除等等。
CREATE TRIGGER FindDups
ON tblOutliersTemp
AFTER INSERT
AS
我不打算通过编写整个触发器。我没有SQL Server 2005来测试它,我可能会出现语法错误,我不想给你错误的代码,但这是触发器需要做的事情:
关于这样做的好处是sqlSave()不会因为你违反PK而错误,你可以在以后处理比赛,比如明天。 : - )