将数据从 R 存储到 DB2 不起作用

Posted

技术标签:

【中文标题】将数据从 R 存储到 DB2 不起作用【英文标题】:Storing data from R to DB2 doesn't work 【发布时间】:2017-08-21 14:16:53 【问题描述】:

我有一个关于 DB2 和 R 连接的奇怪问题。我可以访问数据库,可以查询数据,但我不能从 R 中存储它。我使用 R 的 RODBC 包。我按照这里写的指南https://www.ibm.com/developerworks/data/library/techarticle/dm-1402db2andr/index.html 技术上这个包从 R 中创建了一个“INSERT INTO”语句对象并在 DB2 上执行它以存储来自 R 的数据。(我拥有在数据库上执行这些操作所需的凭据。)

我尝试的是以下(我使用 R 和 SQuirreL - http://squirrel-sql.sourceforge.net/ - 一起测试不止一种方式):

使用 SQuirreL 创建一个包含 3 列和 25 条记录的测试表。 然后我从 R 查询这个表。 我尝试将结果数据集(来自 2)中的第一条记录保存到同一个表中。 然后我从 R 查询表 - 带有附加的行。 然后我从 SQuirreL 查询。 问题发生在这里,当我连接到 R 和插入之后。在 (4) 我看到添加的记录,但我无法从 SQuirreL (5) 查询它。似乎 R 已经锁定了整个表。当我使用 R 与数据库断开连接时,它没有得到解决,我还收到 2 条错误消息(我怀疑这些是相关的)。当我退出 R 然后它就解决了,我可以从 SQuirreL 查询我的表,但是附加的记录消失了。

我尝试从 R 发送的 SQuirreL 运行相同的 SQL 语句。我没有收到错误消息,并且记录被附加。因此,R 使用的方法应该有效。我不知道它会横向到哪里。

我附上了表格中的示例数据和使用的 R 脚本(包括运行时消息)。下面是 CREATE TABLE 语句。该表还没有任何索引或键,因此不禁止添加重复记录。

     create table dm_quant.test (
         r_date         date, 
         cid             varchar(255),
         priv_person     varchar(255)
     );

有没有人遇到过同样的困难?如果是这样,我该如何解决?

提前致谢!

    #connect-to-db2
    rm(list=ls(all=TRUE))
    gc(reset = TRUE)

    require(RODBC)

    dsn_name <- "DB2_DB"
    user <- "user"
    pwd <- "pass"


    channel <- odbcConnect(dsn = dsn_name, uid = user, pwd)

    table_list <- sqlTables(channel, tableType = "TABLE", schema = "DM_QUANT")
    cat("There are", nrow(table_list), "tables in the DM_QUANT schema.\n")
    # There are 4 tables in the DM_QUANT schema.

    table_name <- "DM_QUANT.TEST"
    col_list <- sqlColumns(channel, table_name)
    cat("There are", nrow(col_list), "columns defined in", table_name,"\n")
    # There are 3 columns defined in DM_QUANT.TEST 

    ## Fetch test table (25 records)
    test_tbl <- sqlQuery(channel, paste("SELECT * FROM ", table_name, sep = ""),
                         as.is = TRUE, na.strings = "")

    ## Determine varTypes parameter for sqlSave
    db2_var_types <- data.frame(var = col_list$COLUMN_NAME, 
                                var_type = col_list$TYPE_NAME, 
                                var_type_ext = paste(col_list$TYPE_NAME, "(", col_list$COLUMN_SIZE, ")", sep = ""),
                                stringsAsFactors = F)

    db2_var_types$final_var_type <- db2_var_types$var_type

    ## Adding size for VARCHAR variable type.
    db2_var_types$final_var_type[db2_var_types$var_type == "VARCHAR"] <- db2_var_types$var_type_ext[db2_var_types$var_type == "VARCHAR"]


    ## Append - append 1st record of the current table again.
    sqlSave(channel, test_tbl[1,], tablename = table_name, append = T, verbose = T, 
            fast = F, rownames = F, colnames = F, varTypes = db2_var_types$final_var_type)
    # Query: INSERT INTO DM_QUANT.TEST ( "R_DATE", "CID", "PRIV_PERSON" ) VALUES ( '2016-06-30', '193303', 'N' )

    ## After I use sqlSave I cannot query from the database from SQuirreL SQL Client.
    ## Seems like I'm locking the whole table by R.

    ## Test append
    ## customer_test <- sqlFetch(channel, table_name)
    test_append <- sqlQuery(channel, paste("SELECT * FROM ", table_name, sep = ""),
                              as.is = TRUE, na.strings = "")

    nrow(test_append)
    # [1] 26
    nrow(test_append) == nrow(test_tbl) + 1
    # [1] TRUE

    ## Append seems successfull
    cat("Record appended successfully.\n")


    ## Close connections
    odbcCloseAll()
    cat("Database connections are closed.\n")

    ## Always closes with 2 error message
    # 1: [RODBC] Error in SQLDisconnect 
    # 2: [RODBC] Error in SQLFreeconnect 

    ## I still cannot query from SQuirreL SQL Client untill I close R completely
    ## After I close and test query from SQuirreL, I cannot see the appended record.

我用于测试的 Excel 文件。

        **sample-data** 
    R_DATE      CID    PRIV_PERSON
    2016.06.30  193303  N
    2016.06.30  808739  N
    2016.06.30  585008  N
    2016.06.30  479872  N
    2016.06.30  350290  N
    2016.06.30  895961  N
    2016.06.30  822839  N
    2016.06.30  746603  N
    2016.06.30  174107  N
    2016.06.30  858942  N
    2016.06.30  710500  N
    2016.06.30  513533  N
    2016.06.30  303993  N
    2016.06.30  14983   N
    2016.06.30  91401   N
    2016.06.30  364451  N
    2016.06.30  147311  N
    2016.06.30  165897  N
    2016.06.30  988524  N
    2016.06.30  445691  N
    2016.06.30  119082  N
    2016.06.30  4668    N
    2016.06.30  8910    N
    2017.12.31  377879  
    2016.06.30  531661  N

【问题讨论】:

【参考方案1】:

禁用的自动提交可以解释这种行为。更新或插入的行在提交之前保持独占锁定。当您强制关闭连接时,更改可能会被回滚。

在建立连接后立即尝试odbcSetAutoCommit(channel, autoCommit = TRUE)。或者,您可以在sqlSave() 之后发出odbcEndTran(channel, commit = TRUE)

【讨论】:

以上是关于将数据从 R 存储到 DB2 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

从本地存储中检索数据不起作用

将图像从隔离存储加载到可观察集合不起作用

将图像从 rest 端点保存到 firebase 存储不起作用,但可以从前端工作

从 jquery 将数据发布到 rails 控制器不起作用

数据库项目:数据库引用不起作用

使用毕加索从 Firebase 向 CardView 显示用户图像不起作用