小编典典

R Shiny SQL Server查询

sql

我想在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)

任何帮助是极大的赞赏!非常感谢你。


阅读 251

收藏
2021-04-22

共1个答案

小编典典

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

  1. 你没有output$tbTable对象。这意味着您的myData反应式永远不会被调用,因此您永远不会查询数据库。
  2. 您正在使用RODBC数据库连接,然后在中使用DBI样式参数sqlQuery。您应该使用DBIRSQLServer也许是,-我从未使用过)或RODBC(我经常使用)。
  3. dbhandle第一次调用后,您将关闭。这是预期的行为吗?用户应该只有一次机会访问数据库吗?

一些小注意事项:

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

我对您的代码的建议是:

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)),因此其他人也许可以填补那里的空白。

如果不想每次单击按钮都创建新连接,则可以在反应式外部创建连接,而不必关闭它。但是,这将留下一个挂起的连接,我不喜欢这样做。

2021-04-22