RODBC:在存储过程中传递空值

时间:2016-06-25 08:57:41

标签: r stored-procedures rodbc

我有一个存储过程,它返回阿姆斯特丹某个区的子区域。要连接我的sql server并从数据库获取数据,我使用RODBC。

这是我用来获取所有子区域的代码:

#stored procedure: all subdistricts
subdistricts_amsterdam <-function(Region = "G4", State = "NH", City = "Amsterdam", District = NULL){
  dbhandle <- connect()
  data <- sqlQuery(channel = dbhandle, 
                   query = paste("exec dbo.SP_AllSubDistricts @Region='", Region, "', @State='", State, "', @City='", City, "', @District='", District,"';", sep = ""), errors = TRUE)
  odbcClose(dbhandle)
  return(data)
}

我期望这个函数返回阿姆斯特丹的所有子区域。但显然这种方式不起作用。但是当我用某个区域调用该函数时,我将得到相应区域的所有子区域。

请帮忙

1 个答案:

答案 0 :(得分:1)

R中SQL的NULL的等价物是NA(缺失值)而不是NULL(未定义的值)。正如this R bloggers post indicates从文档中提取的那样:

  

NULL表示R中的空对象:它是保留字。 NULL是   通常由值为的表达式和函数返回   未定义。

     

NA是长度为1的逻辑常量,包含缺失值   指示器。

因此,请考虑在函数中传递NA。如果这样做,则不应引用NA,因此请添加ifelse()进行有条件调整。

#stored procedure: all subdistricts
subdistricts_amsterdam <-function(Region = "G4", State = "NH", 
                                  City = "Amsterdam", District = NA){
  dbhandle <- connect()
  data <- sqlQuery(channel = dbhandle, 
                   query = paste("exec dbo.SP_AllSubDistricts @Region='", Region, "', 
                                  @State='", State, "', @City='", City, "', @District=", 
                                  ifelse(is.na(District), District, 
                                         paste0("'", District, "'")), ";", sep=""), 
                   errors = TRUE)
  odbcClose(dbhandle)
  return(data)
}

顺便说一下,确保存储过程在接收端处理NULL值,而不是简单地将其替换为WHERE子句中的字符串文字,因为结果可能不返回任何内容。例如:

SELECT * FROM TableName WHERE City = 'Amsterdam' AND District = 'Some District'

显着不同
SELECT * FROM TableName WHERE City = 'Amsterdam' AND District IS NULL

在TSQL中使用条件省略区过滤器

IF @District IS NULL
    BEGIN
        SELECT * FROM TableName WHERE City = @City
    END
ELSE
    BEGIN
        SELECT * FROM TableName WHERE City = @City AND District = @District
    END