简体   繁体   English

R Shiny SQL Server查询

[英]R Shiny SQL Server Query

I would like to query an ODBC database within Shiny. 我想在Shiny中查询ODBC数据库。 All I need is for the user to be able to type in someone's ID number, for example, and then to print out the entire row in the table, which is located in the database. 我所需要做的就是让用户能够输入某人的ID号,例如,然后打印出表中位于数据库中的整行。 What I have so far allows for inputs, but does not seem to be querying the database and printing that information. 到目前为止,我所能提供的只是输入信息,但似乎并不能查询数据库并打印该信息。

This is what I have: 这就是我所拥有的:

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)

Any help is greatly appreciated! 任何帮助是极大的赞赏! Thank you very much. 非常感谢你。

There are a handful of changes you'll need to make before this works. 在此之前,您需要进行一些更改。 Some of the key concepts that need to be pointed out: 需要指出的一些关键概念:

  1. You have no output$tbTable object. 您没有output$tbTable对象。 This means that your myData reactive is never being called, so you're never querying your database. 这意味着您的myData反应式不会被调用,因此您永远不会查询数据库。
  2. You are using an RODBC database connection, and then using DBI style arguments in sqlQuery . 您正在使用RODBC数据库连接,然后在sqlQuery使用DBI样式参数。 You should use either DBI (via RSQLServer , perhaps--I've never used it) or RODBC (I use this a lot). 您应该使用DBI (也许是通过RSQLServer ,也许我从未使用过)或RODBC (我经常使用它)。
  3. You are closing dbhandle after the first time you call it. 第一次调用它后,您将关闭dbhandle Is this the intended behavior? 这是预期的行为吗? That the user should only get one chance at hitting the database? 用户应该只有一次机会访问数据库吗?

Some minor notes: 一些小注意事项:

  1. I recommend using RODBCext so that you can use parameterized queries. 我建议使用RODBCext以便可以使用参数化查询。
  2. Table is a reserved word in SQL. Table是SQL中的保留字。 I'm not sure if this is a placeholder or not, but it can be helpful to wrap your table components in brackets, such as [schema].[table_name].[column_name] 我不确定这是否是占位符,但是将表组件包装在方括号中会很有帮助,例如[schema]。[table_name]。[column_name]
  3. You didn't direct the query to a schema. 您没有将查询定向到架构。 This may or may not present an issue. 这可能会或可能不会出现问题。 Since your query was never called, you didn't have a chance to see if it threw an error. 由于从未调用过查询,因此您没有机会查看它是否引发了错误。

My recommendation for your code would be: 我对您的代码的建议是:

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)

I seem to recall there is a way to close the database connection when the session closes, but I can't get it to work the way I expected with session$onSessionEnded(odbcClose(dbhandle)) , so someone else may be able to fill in the gap there. 我似乎记得有一种方法可以在会话关闭时关闭数据库连接,但是我无法通过session$onSessionEnded(odbcClose(dbhandle))使其按预期的方式工作,因此其他人也可以填充在那里的差距。

If you don't want to create a new connection everytime you click the button, you can create the connection outside of the reactive, and just not close it. 如果不想每次单击按钮都创建新连接,则可以在反应式外部创建连接,而不必关闭它。 This will leave a hanging connection, though, which I'm not fond of doing. 但是,这将导致挂起的连接,我不喜欢这样做。

A reactive is a function : as long as you don't call it, it's not evaluated. reactive是一种功能:只要您不调用它,就不会对其进行评估。

To fill in the table with the result of the query, you just have to add this code to your server function after the closing parenthesis of the reactive : 为了填补与查询结果表,你就必须在闭幕括号后将此代码添加到您的服务器的功能reactive

output$tbTable<- renderTable(mydata())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM