2017-08-08 5 views
0

先日、この記事を見つけました:http://deanattali.com/blog/shiny-persistent-data-storage/#sqlite、私はそれを試してみました。RODBCを使用したShiny Appのデータストレージ

しかし、私はRODBCを使用しなければならず、それは記事では話されていません。

現在、私はこれを試してみました:

table <- "[shinydatabase].[dbo].[response]" 

fieldsMandatory <- c("name", "favourite_pkg") 

labelMandatory <- function(label) { 
    tagList(
    label, 
    span("*", class = "mandatory_star") 
) 
} 

appCSS <- 
    ".mandatory_star { color: red; }" 


fieldsAll <- c("Name", "favpkg", "used_shiny", "num_years", "os_type") 

shinyApp(
    ui = fluidPage(
    shinyjs::useShinyjs(), 
    shinyjs::inlineCSS(appCSS), 
    titlePanel("Mimicking a Google Form with a Shiny app"), 

    div(
     id = "form", 

     textInput("name", labelMandatory("Name"), ""), 
     textInput("favourite_pkg", labelMandatory("Favourite R package")), 
     checkboxInput("used_shiny", "I've built a Shiny app in R before", FALSE), 
     sliderInput("r_num_years", "Number of years using R", 0, 25, 2, ticks = FALSE), 
     selectInput("os_type", "Operating system used most frequently", 
        c("", "Windows", "Mac", "Linux")), 
     actionButton("submit", "Submit", class = "btn-primary") 
    ) 

), 

    server = function(input, output, session) { 
    observe({ 
     mandatoryFilled <- 
     vapply(fieldsMandatory, 
       function(x) { 
       !is.null(input[[x]]) && input[[x]] != "" 
       }, 
       logical(1)) 
     mandatoryFilled <- all(mandatoryFilled) 
     shinyjs::toggleState(id = "submit", condition = mandatoryFilled) 

    }) 

    formData <- reactive({ 
     data <- sapply(fieldsAll, function(x) input[[x]]) 
    }) 

    saveData <- function(data) { 
     # Connect to the database 
     db<- odbcConnect(".", uid = "uid", pwd = "pwd") 
     # Construct the update query by looping over the data fields 
     query <- sprintf(
     "INSERT INTO [shinydatabase].[dbo].[response] (Name, favpkg, used_shiny, num_years, os_type) VALUES ('%s')", 
     paste(data, collapse = "', '") 
    ) 
     # Submit the update query and disconnect 
     sqlQuery(db, query) 
     odbcClose(db) 
    } 

    loadData <- function() { 
     # Connect to the database 
     odbcChannel<- odbcConnect(".", uid = "uid", pwd = "pwd") 
     # Construct the fetching query 
     query <- sprintf("SELECT * FROM [shinydatabase].[dbo].[response]") 
     # Submit the fetch query and disconnect 
     data <- sqlQuery(db, query) 
     odbcClose(db) 
     data 
    } 

    # action to take when submit button is pressed 
    observeEvent(input$submit, { 
     saveData(formData()) 
    }) 

    } 
) 

これは基本的に記事や、アプリケーションの実行と同じであり、そしてエラーがしかし、何も情報が私のデータベーステーブルにリードバックされていない、表示されません。

このような文に通常のインサートを行う場合:

sqlQuery(db, "INSERT INTO [shinydatabase].[dbo].[response] (Name, favpkg, used_shiny, num_years, os_type) VALUES ('a', 'b', 'yes', '2','mac') 

をそれはので、私はそれは問題ではありません知って動作します。

答えて

1

saveData関数をRODBCextに書き換えることをおすすめします。クエリをパラメータ化すると、最終的なクエリの外観を明確にし、SQLインジェクションから保護します。

saveData <- function(data) { 
     # Connect to the database 
     db<- odbcConnect(".", uid = "uid", pwd = "pwd") 
     # make sure the connection is closed even if an error occurs. 
     on.exit(odbcClose(db)) 

     sqlExecute(
     channel = db, 
     query = "INSERT INTO [shinydatabase].[dbo].[response] 
       (Name, favpkg, used_shiny, num_years, os_type) 
       VALUES 
       (?, ?, ?, ?, ?)", 
     data = data 
    ) 
    } 
0

Iは、各列の文字列リテラルとすべての値が埋め込まれたカンマで1つの行の文字列として連結されて記憶されるようにRのc関数がクエリにブリードとしてブログ法の収量が結果を所望の驚いています。また

vals <- paste(apply(data, 1, function(d) paste0("('", paste(d, collapse = "', '"), "')")), collapse = ", ") 

query <- sprintf("INSERT INTO [shinydatabase].[dbo].[response] ([Name], favpkg, used_shiny, num_years, os_type) VALUES %s", vals)  
query 
# [1] "INSERT INTO [shinydatabase].[dbo].[response] (Name, favpkg, used_shiny, num_years, os_type) 
# VALUES ('E', 'F', 'Q', 'Y', 'A'), ('C', 'W', 'V', 'V', 'V'), ('I', 'R', 'M', 'C', 'U'), 
# ('U', 'O', 'T', 'M', 'I'), ('B', 'L', 'I', 'O', 'D')" 

:あなたの特定のSQL Serverの方言に整列する必要がありますため

sample.seed(111) 
data <- data.frame(col1 = sample(LETTERS, 5), 
        col2 = sample(LETTERS, 5), 
        col3 = sample(LETTERS, 5), 
        col4 = sample(LETTERS, 5), 
        col5 = sample(LETTERS, 5), stringsAsFactors = FALSE) 

query <- sprintf(
    "INSERT INTO [shinydatabase].[dbo].[response] (Name, favpkg, used_shiny, num_years, os_type) VALUES ('%s')", 
    paste(data, collapse = "', '") 
) 

query 
# [1] "INSERT INTO [shinydatabase].[dbo].[response] (Name, favpkg, used_shiny, 
# num_years, os_type) VALUES ('c(\"E\", \"C\", \"I\", \"U\", \"B\")', 
# 'c(\"F\", \"W\", \"R\", \"O\", \"L\")', 'c(\"Q\", \"V\", \"M\", \"T\", \"I\")', 
# 'c(\"Y\", \"V\", \"C\", \"M\", \"O\")', 'c(\"A\", \"V\", \"U\", \"I\", \"D\")')" 

しかし、大きなクエリ文字列に連結し、その後、建物の価値を考えるapplyループを設定し、:ランダムな文字データで実証するために、 RODBCのsqlSaveをデータベース全体にデータベースに追加することを検討してください。

sqlSave(db, data, tablename = "response", append = TRUE, rownames = FALSE) 
関連する問題