2

いくつかの特殊文字を含むテーブル名でテーブルを作成する必要があります。RSQLiteパッケージを使用しています。作成する必要があるテーブル名は ですport.3.1。この名前でテーブルを作成することはできません。そこで、SQLite で有効なテーブル名は何ですか?[port.3.1]に基づいてテーブル名を変更しました。.

テーブルを作成できるようになりましたが、そのテーブルにデータフレームを挿入できません。私が使用したコードは次のとおりです。

createTable <- function(tableName){
    c <- c(portDate='varchar(20) not null' ,
         ticker='varchar(20)',
         quantities='double(20,10)')
  lite <- dbDriver("SQLite", max.con = 25)
  db <- dbConnect(lite, dbname="sql.db")

  if( length(which(strsplit(toString(tableName),'')[[1]]=='.') ) != 0){ tableName = paste("[",tableName,"]",sep="") } #check whether the portfolio contains special characters or not
  sql <- dbBuildTableDefinition(db, tableName, NULL, field.types = c, row.names = FALSE)
  print(sql)
  dbGetQuery(db, sql)
}
datedPf <- data.frame(date=c("2001-01-01","2001-01-01"), ticker=c("a","b"),quantity=c(12,13))
for(port in c("port1","port2","port.3.1")){
  createTable(port)
  lite <- dbDriver("SQLite", max.con = 25)
  db <- dbConnect(lite, dbname="sql.db")
  if( length(which(strsplit(toString(port),'')[[1]]=='.') ) != 0){ port = paste("[",port,"]",sep="") } #check whether the portfolio contains special characters or not
  dbWriteTable(db,port,datedPf ,append=TRUE,row.names=FALSE)
}

この例では、テーブルport1とテーブルにデータ フレームを挿入できますport2が、テーブルには挿入されません[port.3.1]。この背後にある理由は何ですか? どうすればこの問題を解決できますか?

4

1 に答える 1

3

sqliteWriteTableその名前を入力してEnterキーを押すだけで、実装を確認できます。次の 2 つのことがわかります。

[…]
foundTable <- dbExistsTable(con, name)
new.table <- !foundTable
createTable <- (new.table || foundTable && overwrite)
[…]
if (createTable) {
    […]

そして、出力を見ると、引用符で囲まれていないバージョンのテーブル名を返すためshowMethods("dbExistsTable", includeDefs=T)に使用していることがわかります。したがって、引用符で囲まれたテーブル名を に渡すと、テーブルが存在しないと誤って想定され、テーブルを作成しようとしてエラーが発生します。引用符で囲まれていないテーブル名を渡すと、作成ステートメントが正しくなくなります。dbListTables(conn)sqliteWriteTable

これは RSQLite のバグだと思います。私の意見では、ユーザーが渡す SQL ステートメントは正しく引用符で囲まれている必要がありますが、テーブル名を別の引数として関数に渡す場合、そのテーブル名はデフォルトで引用符を付けず、生成された SQL ステートメントで引用符で囲む必要があります。名前が引用符付きまたは引用符なしの形式で許可されていればさらに良いでしょうが、これは主に移植性を最大化するためです。気が向いたら、開発者に連絡してこの問題を報告してみてください。

この問題を回避できます。

setMethod(dbExistsTable, signature(conn="SQLiteConnection", name="character"),
  function(conn, name, ...) {
    lst <- dbListTables(conn)
    lst <- c(lst, paste("[", lst, "]", sep=""))
    match(tolower(name), tolower(lst), nomatch = 0) > 0
  }
)

これにより、SQLite 接続のデフォルトの実装がdbExistsTable、引用符で囲まれたテーブル名と引用されていないテーブル名の両方をチェックするバージョンで上書きされます。この変更の後"[port.3.1]"、テーブル名として渡すfoundTableと true になるため、RSQLite はそのテーブルを作成しようとしません。

于 2013-06-04T12:59:35.677 に答える