首页 > 解决方案 > RODBC 使用 EXEC @variable 查询

问题描述

我使用一组数据库,每个数据库上都有几个结构相同的项目。我的目标是查询每台服务器上的主数据库,并从所有项目中提取相同的信息来汇总和执行分析。在 SQL Server 中,我整理了一个工作查询(下面的示例),它遍历所有返回相同信息的项目:

Declare @DBNames Table (RN int, Name varchar(max))
Insert Into @DBNames (RN, Name)
Select Row_Number() Over (Order By Name Desc) as RN, 
        Name 
From sys.databases 
Where  (Name = 'proj1' or
        Name = 'proj2' or
        Name = 'proj3')
    and state_desc = 'Online'

-- sql part 1a
DECLARE @sql1 varchar(max) = 
                                 '
select  ''a.colA
        ,b.colB
        ,c.colC

from '

-- sql2 part 
Declare @SQL2 varchar(max) = '.dbo.tableA as a
    inner join '

-- sql3 part 
Declare @SQL3 varchar(max) = '.dbo.tableB as b on b.x = a.x
    inner join '

-- sql4 part 
Declare @SQL4 varchar(max) = '.dbo.tableC as c on c.y = b.y
where col1 is not null' 

Declare @SQL varchar(max)
Select @SQL = (
                                 Select Stuff((@SQL1 + Name + @SQL2 +  NAME + @SQL3 + Name + @SQL4 + Case When RN = 1 Then '' Else ' Union ' End), 1, 0, '') as SQL
                                 From @DBNames Order By RN Desc
                                 for XML Path(''), TYPE).value('.','varchar(max)')

                               exec(@sql)

当我尝试在 RODBC 中使用上述查询加载数据时,它似乎不起作用。RODBC 是否支持这种类型的查询?如果没有,什么可能是一个好的选择?

提前感谢您的时间和耐心!

标签: rsql-serverrodbc

解决方案


本质上,您正在使用过程语义在 TSQL 中构建动态查询。但是 R 是一种过程语言。因此,考虑循环访问数据库以构建连接的数据框(对应的UNION)。

library(RODBC) 

sql <- "select a.colA, b.colB, c.colC 
        from dbo.tableA as a 
        inner join dbo.tableB as b on b.x = a.x 
        inner join dbo.tableC as c on c.y = b.y 
        where col1 is not null"

get_db_data <- function(db) {
     # DYNAMICAL DATABASE CONNECTION
     conn <- odbcDriverConnect(paste0("Driver={SQL Server};",
                                      "Server=myserver;Database=", db,
                                      ";Trusted_connection=Yes"))

     df <- sqlQuery(conn, sql)

     odbcClose(conn)

     return(df)
}

# BUILD LIST OF DFs FROM DIFFERENT DBs
df_list <- lapply(c("proj1", "proj2", "proj3"), get_db_data)

# EQUIVALENT TO UNION QUERY
final_df <- unique(do.call(rbind, df_list))

推荐阅读