R Shiny SQL Server查询

时间:2017-02-08 18:00:19

标签: sql r shiny

我想在Shiny中查询ODBC数据库。我所需要的只是让用户能够输入某人的ID号,然后打印出位于数据库中的表中的整行。到目前为止我所拥有的输入允许输入,但似乎不是在查询数据库并打印该信息。

这就是我所拥有的:

library(RSQLite)
library(RODBC)
library(RODBCext)
library(sqldf)

#connect to database
dbhandle = odbcDriverConnect(...)


library(shiny)

ui <- shinyUI(

 pageWithSidebar(

   headerPanel("Hide Side Bar example"),
   sidebarPanel(
     textInput("Id", "Enter Account Number below"),
     submitButton(text="Submit")
   ),
   mainPanel(
   tabsetPanel(
    tabPanel("Data", tableOutput("tbTable"))
    )
  )
  )
)

server <- function(input, output) {
  myData <- reactive({

  #build query
  query = paste0("SELECT Fullname FROM Table WHERE ID= ", input$Id)

  #store results
  res <- sqlQuery(conn = dbhandle, query = query) 

  #close database
  databaseClose(dbhandle)

  #return results
  res
  })
}

shinyApp(ui = ui, server = server)

非常感谢任何帮助!非常感谢你。

2 个答案:

答案 0 :(得分:3)

在此工作之前,您需要进行一些更改。需要指出的一些关键概念:

  1. 您没有output$tbTable个对象。这意味着永远不会调用myData被动,因此您永远不会查询数据库。
  2. 您正在使用RODBC数据库连接,然后在DBI中使用sqlQuery样式参数。您应该使用DBI(通过RSQLServer,也许 - 我从未使用过它)或RODBC(我经常使用它)。
  3. 您第一次打电话后正在关闭dbhandle。这是预期的行为吗?用户应该只有一次机会点击数据库吗?
  4. 一些小调:

    1. 我建议使用RODBCext,以便您可以使用参数化查询。
    2. Table是SQL中的保留字。我不确定这是否是占位符,但将表组件包装在括号中可能会有所帮助,例如[schema]。[table_name]。[column_name]
    3. 您没有将查询定向到架构。这可能会也可能不会出现问题。由于您的查询从未被调用,因此您没有机会查看是否发生了错误。
    4. 我对您的代码的建议是:

      library(RODBCext) # Also loads RODBC
      library(shiny)
      
      ui <- shinyUI(
      
        pageWithSidebar(
      
          headerPanel("Hide Side Bar example"),
          sidebarPanel(
            textInput("Id", "Enter Account Number below"),
            submitButton(text="Submit")
          ),
          mainPanel(
            tabsetPanel(
              tabPanel("Data", tableOutput("tbTable"))
            )
          )
        )
      )
      
      server <- function(input, output, session) {      
        myData <- reactive({
          req(input$Id)
      
          #connect to database 
          dbhandle = odbcDriverConnect(...)
      
          #build query
          query = "SELECT [Fullname] FROM [schema].[table_name] WHERE [ID] = ?"
      
          #store results
          res <- sqlExecute(channel = dbhandle, 
                            query = query,
                            data = list(input$Id),
                            fetch = TRUE,
                            stringsAsFactors = FALSE) 
      
          #close the connection
          odbcClose(dbhandle)
          #return results
          res
        })
      
        output$tbTable <- 
          renderTable(
            myData()
          )
      }
      
      shinyApp(ui = ui, server = server)
      

      我似乎记得有一种方法可以在会话结束时关闭数据库连接,但是我无法按照我期望的session$onSessionEnded(odbcClose(dbhandle))方式工作,所以其他人也可以填写那里的差距。

      如果您不想在每次单击按钮时创建新连接,则可以在响应之外创建连接,而不是关闭它。然而,这将留下悬挂的连接,我不喜欢这样做。

答案 1 :(得分:0)

reactive是一项功能:只要您不打电话,就不会对其进行评估。

要在表格中填入查询结果,您只需在reactive的右括号后将此代码添加到服务器函数中:

output$tbTable<- renderTable(mydata())