我想在 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)
非常感谢任何帮助!非常感谢。
最佳答案
在此之前,您需要进行一些更改。需要指出的一些关键概念:
- 您没有
output$tbTable
对象。这意味着您的myData
react 永远不会被调用,因此您永远不会查询数据库。 - 您正在使用
RODBC
数据库连接,然后在sqlQuery
中使用DBI
样式参数。您应该使用DBI
(也许通过RSQLServer
——我从未使用过它)或RODBC
(我经常使用它)。 - 您将在第一次调用
dbhandle
后关闭它。这是预期的行为吗?用户应该只有一次访问数据库的机会?
一些小注意事项:
- 我建议使用
RODBCext
,以便您可以使用参数化查询。 Table
是 SQL 中的保留字。我不确定这是否是占位符,但将表组件括在括号中会很有帮助,例如 [schema].[table_name].[column_name]- 您没有将查询定向到架构。这可能会或可能不会出现问题。由于您的查询从未被调用,因此您没有机会查看它是否引发错误。
我对您的代码的建议是:
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 关闭时关闭数据库连接,但我无法让它按我预期的方式工作 session$onSessionEnded(odbcClose(dbhandle))
,所以其他人也许能够填补那里的空白。
如果您不想每次单击按钮时都创建新连接,则可以在 react 之外创建连接,而不是关闭它。不过,这会留下一个悬而未决的连接,我不喜欢这样做。
关于sql - R Shiny SQL Server 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42120389/