2016-08-04 13 views
1

のクエリに渡す私は光沢のある光沢のあるダッシュボードを使い、データベースから直接データを取り出そうとしているSQLデータベースSQL-SERVERを使って作業する方法を学んでいます。基本的には、日付範囲の開始点と終了点を持つ表の列にマージし、それらを集計してからダイアグラムを作成します。SQL入力の日付範囲をSHINY

私はピカピカにSQL入力文を渡す方法については、次の投稿を見つけた: How to pass input variable to SQL statement in R shiny?

私がしようとすると、これを適用する際残念ながら、私はエラー「添字が範囲外にある取得します。それはクエリが引き込まれていないように見えます。私は別にそれをテストし、データを引き出し、問題なく各ステップを実行することができました。私はこれが問題かどうか疑問に思うRODBCパッケージを使用しています。以下は私のコードです:

  library(stringr) 
     library(RODBC) 
      library(circlize) 
     library(shinydashboard) 
     library(shiny) 

       ui <- dashboardPage(skin = "blue", 
       dashboardHeader(title = "sample"), 
       dashboardSidebar(disable = TRUE), 
       dashboardBody(
        # Boxes need to be put in a row (or column) 
        fluidRow(
        box(title = "Route Volume", background = "green", solidHeader = TRUE, 
         plotOutput(outputId= 'plot2'))), 
        fluidRow( 
         box(background= "green", dateRangeInput("dates", label = h3("Date Range"),start = '2016-06-01', 
                   end = '2016-06-05')), width = 4 

        )))) 

       server <- function(input, output) { 
      database = odbcConnect("datatbase") 
      output$plot2 = renderPlot({ 

      d = paste0("SELECT 
       top 30 
      convert(char(10),datetime,121) as date, 
      cast(start_destination as varchar(3)) 
      + (',') + cast(final_destination as varchar(3)) as combo, 
      count(cast(start_destination as varchar(3)) 
      + (',') + cast(final_destination as varchar(3))) as volume 
      FROM 
      trips 
      WHERE datetime >= ",input$dates[1]," AND 
      datetime < ",input$dates[2]," 
      GROUP BY 
      cast(start_destination as varchar(3)) 
      + (',') + cast(final_destination as varchar(3)), 
      convert(char(10),datetime,121);") 

     sql = sqlQuery(database, d) 

      sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ','))) 
     colnames(sql)[colnames(sql)=="X1"] <- "From" 
     colnames(sql)[colnames(sql)=="X2"] <- "To" 
     sql = sql[,c(4,5,3)] 
     sql = sql[order(sql$volume, decreasing = T),] 
      chordDiagram(sql) 
      circos.clear() 

      }) 

      } 


      shinyApp(ui, server) 

私は、これはいくつかの愚かな間違い、不足している引用符またはこれらの技術を適用する方法の私の一部に誤解であると確信しています。ヘルプをよろしく!

NJburgo によって提案次のサーバーへの編集を置く
   ##adding edits by Dean to test 



       database = odbcConnect("database") 
      output$plot2 = renderPlot({ 
       if(input$dates[1]!= "") { 
       d = paste0("SELECT 
      top 30 
      convert(char(10),datetime,121) as date, 
      cast(start_destination as varchar(3)) 
      + (',') + cast(final_destination as varchar(3)) as combo, 
      count(cast(start_destination as varchar(3)) 
      + (',') + cast(final_destination as varchar(3))) as volume 
      FROM 
      trips 
      WHERE 
      datetime >= ",input$dates[1]," AND 
      datetime < ",input$dates[2]," 
      GROUP BY 
      cast(start_destination as varchar(3)) 
      + (',') + cast(final_destination as varchar(3)), 
      convert(char(10),datetime,121);") 
     sql = sqlQuery(database, d) 

     #i assumed the if statement ended here so I put the 
     #bracket below 
      sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ','))) 
     colnames(sql)[colnames(sql)=="X1"] <- "From" 
     colnames(sql)[colnames(sql)=="X2"] <- "To" 
     sql = sql[,c(4,5,3)] 
     sql = sql[order(sql$volume, decreasing = T),] 
      chordDiagram(sql) 
      circos.clear() 

} 
    }) 

    } 

################################ ## NJburgo提案################ #Iは、エラーを取得する:

     database = odbcConnect("database") 
          output$plot2 = renderPlot({ 
          dates = as.Date(input$dates) 
          d = paste0("SELECT 
         top 30 
         convert(char(10),datetime,121) as date, 
        cast(start_destination as varchar(3)) 
         + (',') + cast(final_destination as varchar(3)) as combo, 
         count(cast(start_destination as varchar(3)) 
        + (',') + cast(final_destination as varchar(3))) as volume 
        FROM 
        trips 
         WHERE 
         datetime >= {d '",input$dates[1],"'} AND 
         datetime < {d '",input$dates[2],"'} 
         GROUP BY 
         cast(start_destination as varchar(3)) 
         + (',') + cast(final_destination as varchar(3)), 
         convert(char(10),datetime,121);") 
        sql = sqlQuery(database, d) 


        sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ','))) 
       colnames(sql)[colnames(sql)=="X1"] <- "From" 
       colnames(sql)[colnames(sql)=="X2"] <- "To" 
       sql = sql[,c(4,5,3)] 
       sql = sql[order(sql$volume, decreasing = T),] 
       chordDiagram(sql) 
        circos.clear() 

       }) 

      } 
+2

SQLクエリを構築するために文字列連結を使用すること自体はバグです。予期しない日付と数値の変換は、それが引き起こす可能性のある問題の1つに過ぎません。すべての引用、書式、セキュリティの問題を避けるには、適切な[パラメータ化されたクエリ](https://cran.r-project.org/web/packages/RODBCext/vignettes/Parameterized_SQL_queries.html)を使用してください –

+0

shinyがSQLを実行していると推測されます'入力$ dates'の中に値がある前に。私はSQLクエリが発生する前に 'print(dates $ dates [1])'と 'print $ date [2] 'を入力してからアプリケーションを実行します。これは、Rstudioから実行していることを前提としており、Rstudioウィンドウで何が印刷されているかを見ることができます。 –

+0

ねえディーン。入力$ dateを印刷しようとしましたが、違いはありませんでした。日付がハードコーディングされている場合、データが問題なく引き出されるため、問題がここにあることを確認してください。 – LoF10

答えて

-1

クラスの日付に入力$日付を変換する方法がわからない、私はしないでくださいこれはRのものと考えています.Sqlは、特にクエリがShiny外の通常の日付で動作する場合(ヒント:これをテストして、報告してください)。ようにSQLの日付比較のため

は常に日付を変換しなければならなかった:

...WHERE col_name >= {d '2016-08-04'}... 

だからあなたはR.でこれを行うための最も簡単な方法は、日付をフォーマットする必要がフォーマットである:

format(Sys.Date(), "{d '%Y-%m-%d'}") 
+2

文字列の連結を避け、パラメータ化されたクエリを使用する場合、日付を変換する必要はありません。もしあなたが*使用する*を持っていれば、あいまいな日付フォーマットは分離されていないフォーマット、すなわち '20160804'です。どちらの場合でも、[パラメータ化されたクエリ]をサポートするRODBCextを使用する方がずっと簡単で安全です(https://cran.r-project.org/web/packages/RODBCext/vignettes/Parameterized_SQL_queries.html) –

+0

ヒント!ありがとう。ヒントの人のために – NJBurgo

+0

ありがとう。 Panagiotos、私はパラメータ化されたクエリは、私がこの後に移動する必要がある場所は間違いないと思うが、私はそれがここで問題であるとは確信していない。クエリは光沢の外にあるのでうまく動作し、光沢の中で停止します。データが日付形式に変換され、まだ成功していないように、col_name> = {d '"、入力$ dates [1]、"}}(これは外部で動作しましたしかし光っている)。私はハードコードの日付がクエリにうまくいくと気づきました。ですから、問題は入力$日付であると思います。わからない。何か案は? – LoF10

0
##########答えを見つけました。それは、皆さんからの両方の提案を組み合わせて、日付を印刷して変換したものでなければなりませんでした。以下は作業コードです
   server <- function(input, output) { 

      output$plot2 = renderPlot({ 
      database = odbcConnect("database") 
       start_date = print(input$dates[1]) 
       end_date = print(input$dates[2]) 
       my_query="SELECT 
       top 30 
         convert(char(10),datetime,121) as date, 
         cast(start_destination as varchar(3)) 
         + (',') + cast(final_destination as varchar(3)) as combo, 
          count(cast(start_destination as varchar(3)) 
          + (',') + cast(final_destination as varchar(3))) as volume 
          FROM 
          trips 
           WHERE 
          datetime >= DATE1 AND 
          datetime < DATE2 
          GROUP BY 
          cast(start_destination as varchar(3)) 
          + (',') + cast(final_destination as varchar(3)), 
          convert(char(10),datetime,121);" 

       my_query <- sub("DATE1",as.Date(start_date),my_query); 
       my_query <- sub("DATE2",as.Date(end_date),my_query) 
      sql = sqlQuery(database, paste(my_query)) 
      sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ','))) 
      colnames(sql)[colnames(sql)=="X1"] <- "From" 
      colnames(sql)[colnames(sql)=="X2"] <- "To" 
      sql = sql[,c(4,5,3)] 
      sql = sql[order(sql$volume, decreasing = T),] 
      chordDiagram(sql) 
      circos.clear() 
       }) 


      } 


      shinyApp(ui, server)