在R中使用RODBC创建循环SQL查询

在R中使用RODBC创建循环SQL查询,r,rodbc,R,Rodbc,首先也是最重要的一点——感谢您抽出时间来查看我的问题,无论您是否回答 我试图创建一个函数,使用R中的RODBC包循环通过我的df并查询来自SQL的必要数据。但是,我在设置查询时遇到了问题,因为查询的参数在每次迭代中都会发生变化(下面的示例) 因此,我的df如下所示: ID Start_Date End_Date 1 2/2/2008 2/9/2008 2 1/1/2006 1/1/2007

首先也是最重要的一点——感谢您抽出时间来查看我的问题,无论您是否回答

我试图创建一个函数,使用R中的RODBC包循环通过我的df并查询来自SQL的必要数据。但是,我在设置查询时遇到了问题,因为查询的参数在每次迭代中都会发生变化(下面的示例)

因此,我的df如下所示:

     ID     Start_Date    End_Date    
     1       2/2/2008      2/9/2008
     2       1/1/2006      1/1/2007
     1       5/7/2010      5/15/2010
     5       9/9/2009      10/1/2009
如何在sql程序中指定开始日期和结束日期

以下是我目前掌握的情况:

 data_pull <- function(df) {
    a <- data.frame()
    b <- data.frame()

    for (i in df$id)
{ 
    dbconnection <- odbcDriverConnect(".....")

    query <- paste("Select ID, Date, Account_Balance from Table where ID = (",i,") and Date > (",df$Start_Date,") and Date <= (",df$End_Date,")")

    a <- sqlQuery(dbconnection, paste(query))
    b <- rbind(b,a)
 }
  return(b)
 }

data\u pull当前设置中出现了几个语法问题:

  • 循环:不遍历数据帧的所有行,只遍历单个列中的原子ID值,
    df$ID
    。在同一循环中,您将
    df$Start\u Date
    df$End\u Date
    整个向量传递到查询连接中

  • 日期:您的日期格式与大多数“YYYY-MM-DD”数据库日期格式不一致。还有一些像Oracle这样的应用程序需要字符串到数据的转换:
    到_DATE(mydate,'YYYY-MM-DD')

  • 前面提到的几个性能/最佳实践问题:

  • 参数化:虽然出于安全原因不需要参数化,因为您的值不是由可能注入恶意SQL代码的用户输入生成的,但为了可维护性和可读性,建议使用参数化查询。因此,考虑这样做。

  • 不断增长的对象:根据Patrick Burn的圆圈2:不断增长的对象,R程序员应该避免在循环中增长多维对象,如数据帧,这可能会导致内存中的过度复制。相反,在循环外部构建一个数据帧列表,以
    rbind
    一次


  • 也就是说,通过将数据帧保存为数据库表,然后连接到最终表以进行过滤、连接查询导入,可以避免任何循环或列表需求。这假定数据库用户具有
    创建表
    删除表
    权限

    # CONVERT DATE FIELDS TO DATE TYPE
    df <- within(df, {
              Start_Date = as.Date(Start_Date, format="%m/%d/%Y")
              End_Date = as.Date(End_Date, format="%m/%d/%Y")
    })
    
    # SAVE DATA FRAME TO DATABASE
    sqlSave(dbconnection, df, "myRData", rownames = FALSE, append = FALSE)
    
    # IMPORT JOINED AND DATE FILTERED QUERY
    q <- "SELECT ID, Date, Account_Balance 
          FROM Table t
          INNER JOIN myRData r 
            ON r.ID = t.ID 
            AND t.Date BETWEEN r.Start_Date AND r.End_Date"
    
    final_df <- sqlQuery(dbconnection, q)
    
    #将日期字段转换为日期类型
    
    df从不对SQL查询使用
    paste
    连接,最好的情况是语法错误,最坏的情况是(无论有意与否)。相反,使用
    rodbext
    (相关问题:)(除非
    RODBC
    已经开始直接使用它,否则我真的很惊讶他们还没有实现它,因为它是良好数据库实践的基础)。谢谢@r2evans,我将学习并尝试实现这一点。其次,不要像那样重复使用
    rbind
    ,从长远来看,这会破坏性能(每次调用
    rbind
    都会完整复制前面和正在添加的所有数据)。由于
    rodbext::sqlExecute
    直接支持使用帧进行矢量化(请参见第2.3.2节),因此根本不需要循环。是的,
    rbind
    在循环内运行会导致二次复制。始终避免在回路中生长物体谢谢你们@Parfait我会尝试重新编写这篇文章非常感谢你们花时间来完成这篇文章。我真的很感激,没问题。新年快乐,编码快乐!