将多行SQL查询导入单个字符串

17

R中,我该如何将一个多行文本文件(包含SQL)的内容导入到单个字符串中?

sql.txt文件看起来像这样:

SELECT TOP 100 
 setpoint, 
 tph 
FROM rates

我需要将文本文件导入到R字符串中,使其看起来像这样:
> sqlString
[1] "SELECT TOP 100 setpoint, tph FROM rates"

这样我就可以像这样将其馈送给RODBC

> library(RODBC)
> myconn<-odbcConnect("RPM")
> results<-sqlQuery(myconn,sqlString)

我已经尝试使用以下readLines命令,但它没有提供RODBC所需的字符串格式。

> filecon<-file("sql.txt","r")
> sqlString<-readLines(filecon, warn=FALSE)
> sqlString
[1] "SELECT TOP 100 "                              "\t[Reclaim Setpoint Mean (tph)] as setpoint, "
[3] "\t[Reclaim Rate Mean (tph)] as tphmean "       "FROM [Dampier_RC1P].[dbo].[Rates]"           
> 
7个回答

17

多才多艺的 paste() 命令可以使用参数 collapse="" 来实现此操作:

lines <- readLines("/tmp/sql.txt")
lines
[1] "SELECT TOP 100 " " setpoint, "     " tph "           "FROM rates"     

sqlcmd <- paste(lines, collapse="")
sqlcmd
[1] "SELECT TOP 100  setpoint,  tph FROM rates"

1
谢谢Dirk - 那行得通,除了字符串看起来像这样 "SELECT TOP 100\t setpoint,\t tph\t FROM rates\t"。只需要添加 gsub("\t","", sqlcmd)。 - Tommy O'Dell
我复制的内容没有制表符,不过无论如何,SQL解析器可能会忽略制表符,而你已经找到了gsub()函数 -- 一切都很好。 - Dirk Eddelbuettel
6
如果你的查询语句中有任何 -- 注释,这可能会破坏它,对吧?我建议使用 paste(readLines('pathto/query.sql'), collapse = "\n") - Serban Tanasa
删除制表符可能会破坏SQL查询,因为制表符可能是术语之间唯一的空格。最好将它们保留下来,因为数据库无论如何都会忽略它们。 - user1919238

9
以下是一个R函数,它可以读取多行SQL查询(从文本文件中)并将其转换为单行字符串。该函数会删除格式和整行注释。
使用方法:运行代码以定义函数,然后通过ONELINEQ(“querytextfile.sql”,“~/path/to/thefile”)运行结果即可获得单行字符串。
工作原理:内联注释对此进行了详细说明;它读取查询的每一行并删除(用空白替换)不需要编写单行版本查询的任何内容(如问题所要求)。结果是一系列行,其中有些是空白的并被过滤掉;最后一步是将这个(未列出的)列表粘贴在一起并返回单行。
# This set of functions allows us to read in formatted, commented SQL queries
# Comments must be entire-line comments, not on same line as SQL code, and begun with "--"
# The parsing function, to be applied to each line:
LINECLEAN <- function(x) {
  x = gsub("\t+", "", x, perl=TRUE); # remove all tabs
  x = gsub("^\\s+", "", x, perl=TRUE); # remove leading whitespace
  x = gsub("\\s+$", "", x, perl=TRUE); # remove trailing whitespace
  x = gsub("[ ]+", " ", x, perl=TRUE); # collapse multiple spaces to a single space
  x = gsub("^[--]+.*$", "", x, perl=TRUE); # destroy any comments
  return(x)
}
# PRETTYQUERY is the filename of your formatted query in quotes, eg "myquery.sql"
# DIRPATH is the path to that file, eg "~/Documents/queries"
ONELINEQ <- function(PRETTYQUERY,DIRPATH) { 
  A <- readLines(paste0(DIRPATH,"/",PRETTYQUERY)) # read in the query to a list of lines
  B <- lapply(A,LINECLEAN) # process each line
  C <- Filter(function(x) x != "",B) # remove blank and/or comment lines
  D <- paste(unlist(C),collapse=" ") # paste lines together into one-line string, spaces between.
  return(D)
}
# TODO: add eof newline automatically to remove warning
#############################################################################################

1
你知道吗,这可能是我见过的最好的自我推广答案。您能否在您的答案中添加一个简短的解释它是如何工作的呢?(我的意思是编辑您的答案 - anon
一定要喜欢干净而简单的基本 R 方法!感谢分享这个宝石! - philiporlando

4

以下是我使用的最终版本。感谢Dirk。

fileconn<-file("sql.txt","r")           
sqlString<-readLines(fileconn)          
sqlString<-paste(sqlString,collapse="")
gsub("\t","", sqlString)
library(RODBC)
sqlconn<-odbcConnect("RPM")
results<-sqlQuery(sqlconn,sqlString)
library(qcc)
tph <- qcc(results$tphmean[1:50], type="xbar.one", ylim=c(4000,12000), std.dev=600)
close(fileconn)
close(sqlconn)

2

这是我使用的:

# Set Filename
fileName <- 'Input File.txt'

doSub <- function(src, dest_var_name, src_pattern, dest_pattern) {
    assign(
            x       = dest_var_name
        ,   value   = gsub(
                            pattern     = src_pattern
                        ,   replacement = dest_pattern
                        ,   x = src
                    )
        ,   envir   = .GlobalEnv
    )
}


# Read File Contents
original_text <- readChar(fileName, file.info(fileName)$size)

# Convert to UNIX line ending for ease of use
doSub(src = original_text, dest_var_name = 'unix_text', src_pattern = '\r\n', dest_pattern = '\n')

# Remove Block Comments
doSub(src = unix_text, dest_var_name = 'wo_bc_text', src_pattern = '/\\*.*?\\*/', dest_pattern = '')

# Remove Line Comments
doSub(src = wo_bc_text, dest_var_name = 'wo_bc_lc_text', src_pattern = '--.*?\n', dest_pattern = '')

# Remove Line Endings to get Flat Text
doSub(src = wo_bc_lc_text, dest_var_name = 'flat_text', src_pattern = '\n', dest_pattern = ' ')

# Remove Contiguous Spaces
doSub(src = flat_text, dest_var_name = 'clean_flat_text', src_pattern = ' +', dest_pattern = ' ')

1
尝试使用paste(sqlString, collapse=" ")函数。

1

可以使用readChar()代替readLines()。我曾经遇到过注释混合(--/* */)的问题,而这个方法一直对我很有效。

sql <- readChar(path.to.file, file.size(path.to.file))
query <- sqlQuery(con, sql, stringsAsFactors = TRUE)

0

我同时使用 sql <- gsub("\n","",sql)sql <- gsub("\t","",sql)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接