2017-04-04 53 views
0

我使用RJDBC在RStudio拉一组从Oracle数据库数据的成R.
加载RJDBC包后我有以下行:把dbSendQuery成一个函数中的R

drv = JDBC("oracle.jdbc.OracleDriver", classPath="C:/R/ojdbc7.jar", identifier.quote = " ") 

conn = dbConnect(drv,"jdbc:oracle:thin:@private_server_info", "804301", "password") 

rs = dbSendQuery(conn, statement= paste("LONG SQL QUERY TO SELECT REQUIRED DATA INCLUDING REQUEST FOR VARIABLE x")) 

masterdata = fetch(rs, n = -1) # extract all rows 

通过通常的脚本运行,它们始终执行而不会失败;有时可能需要几分钟依赖于变量x,例如,可能导致100K行或1M行被拉。 masterdata将返回数据帧中的所有内容。

我现在试图把所有上述内容放入一个函数中,用一个必需的参数,变量x,它是一个TEXT参数(城市名称);但此输入也是LONG SQL QUERY的一部分。

我编写的名为Data_Grab的功能如下:

Data_Grab = function(x) { 
    drv = JDBC("oracle.jdbc.OracleDriver", classPath="C:/R/ojdbc7.jar", identifier.quote = " ") 

    conn = dbConnect(drv,"jdbc:oracle:thin:@private_server_info", "804301", "password") 

    rs = dbSendQuery(conn, statement= paste("LONG SQL QUERY TO SELECT REQUIRED DATA, 
     INCLUDING REQUEST FOR VARIABLE x")) 

    masterdata = fetch(rs, n = -1) # extract all rows 

    return (masterdata) 
} 

我的功能出现在几秒钟​​内执行(产生任何错误),但是我得到的只是数据框和行21个标题

<0 rows> (or 0-length row.names)

不确定这里有什么问题;显然期望的功能仍然需要几分钟才能执行,因为被拉的数据很大,但不会返回任何实际的数据帧。

帮助表示赞赏!

+1

只是要清楚,它听起来像你打算在'dbSendQuery'中传递给Oracle的sql中使用它的参数'x'的函数?那是对的吗?因为如果是这样,你还没有表明你已经试图在你的代码中实际实现这种行为。 – joran

+0

@joran是的,这是正确的。在正常脚本中,我会为每次运行手动更改“x”,但是我打算在函数中为该参数进行操作。 – Qaribbean

+1

然后,您需要一些将参数插入到查询中的代码;下面的答案是一个选项,但您始终可以使用'paste'或'gsub'。如果你徘徊,有一些选择,我相信这将保护你免受SQL注入问题,如果这是一个问题。 – joran

回答

0

如果您想将查询参数化为JDBC数据库,请尝试使用gsubfn软件包。代码可能是这样的:

library(gsubfn) 
library(RJDBC) 
Data_Grab = function(x) { 
rd1 = x 
df <- fn$dbGetQuery(conn,"SELECT BLAH1, BLAH2 
    FROM TABLENAME 
    WHERE BLAH1 = '$rd1') 
return(df) 

基本上,你需要存储你要传递的参数变量名的前面放一个$

+0

试过这种方法(函数中使用的参数是一个目标名称),但是它返回错误Data_Grab(伦敦):对象'伦敦'找不到' – Qaribbean

+1

你需要伦敦附近的报价吗?像这样:''伦敦'' – simitpatel

+0

是的!双引号工作,谢谢。我一直在tweeking并尝试单引号没有奏效。 – Qaribbean