1

そのため、RODBC の問題を伴う StackOverflow には多くの問題がありますが、AZURE SQL データベースに追加しようとするこの特定の変種は見たことがありません。KEY を識別できるようにするパラメーターが必要であり、そこにロードしないようにする必要があると本当に思います...プルリクエストを準備しますが、RODBC は github に dev ブランチを持っていませんか? とにかく、私の問題と私がやろうとしたこと、そして私の厄介な回避策を投稿します。

ActDF.newプロパティは次のとおりです。

str(ActDF.new)
'data.frame':   52 obs. of  10 variables:
 $ Date          : Date, format: "2016-03-23" "2016-03-23" "2016-03-23" "2016-03-23" ...
 $ Project       : Factor w/ 1 level "x": 1 1 1 1 1 1 1 1 1 1 ...
 $ IndName       : Factor w/ 26 levels "x x...etc",..: 2 17 1 4 11 12 8 3 25 6 ...
 $ IndNum        : num  1 2 3 4 5 6 7 8 9 10 ...
 $ ProjectYear   : Factor w/ 2 levels "bla","blabla": 1 1 1 1 1 1 1 1 1 1 ...
 $ Value         : num  NA NA NA NA 4883 ...
 $ NoteTitle     : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
 $ NoteAnnotation: Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
 $ ID            : num  1 1 1 1 1 1 1 1 1 1 ...
 $ CorpCode      : ch

と呼ばれる新しいテーブルを使用して、この情報をデータベースに追加したいと思いますActuals。そこで、これを実現するために RODBC::sqlSave を使用してみました。以下に一撃一撃を見つけます:

データベースに接続する

d <- "Actuals RW"
p <- "xx"
u <- "xx"
channel <- odbcConnect(d,u,p)

データベースの行数を取得します(キーの開始位置を知るため)

PresentNum <- sqlQuery(channel, 'SELECT count(*) FROM Actuals', rows_at_time = 5)
PresentNum <- PresentNum[1,1]

では、ID を DF に追加しましょう。また、Value にはたくさんの NA があります...そしてそれらは必要ないので、より良い DF に変換しましょう

## Initialize ID on this df
ActDF.new$ID <- 1

## Remove NAs from ActDF.new, and organize
toSave <- ActDF.new %>% filter(!is.na(Value)) %>%
  select (ID,Date,Project,FiscalYear=ProjectYear,IndNum,IndName,CorpCode,CurrentValue=Value,NoteTitle,NoteAnnotation)

## And now issue correct numbers to the ID
toSave$ID <- (PresentNum+1):(nrow(toSave)+PresentNum)

空白の値が多いので、NAに変換してみましょう(これは面倒な方法です...私は知っています)

toSave <- 
  apply(toSave, 2, function(x) gsub("^$|^ $", NA, x))  %>% as.data.frame()

## Now everything is a factor, convert to correct format
toSave$ID <- as.numeric(toSave$ID)
toSave$Date<- as.Date(toSave$Date)
toSave$Project<- as.character(toSave$Project)
toSave$FiscalYear<- as.character(toSave$FiscalYear)
toSave$IndNum<- as.character(toSave$IndNum)
toSave$IndName<- as.character(toSave$IndName)
toSave$CorpCode<- as.character(toSave$CorpCode)
toSave$CurrentValue<- as.numeric(toSave$CurrentValue)
toSave$NoteTitle<- as.character(toSave$NoteTitle)
toSave$NoteAnnotation <- as.character(toSave$NoteAnnotation)

### よし、準備完了!だから追加してみてください!###

################# Test 1 TRY APPENDING DATA AS IS
sqlSave(channel, toSave, tablename = 'Actuals', append = T,
        rownames = F, colnames = F, verbose = T,
        safer = T, addPK = F, 
        fast = T, test = F)
### RETURNS ERROR: Cannot insert explicit value for identity column in table 'Actuals' when IDENTITY_INSERT is set to OFF.

うーん...まあまあ...

################# Test 2 TRY TO CHANGE THE IDENTITY_INSERT PROPERTY  

sqlQuery(channel, "Set IDENTITY_INSERT Actuals ON", errors = TRUE)
### RETURNS ERROR: Cannot find the object \"Actuals\" because it does not exist or you do not have permissions."

あ…でも…待って、何?テーブルは確かに存在し、私は RW の権利を持っています。だから多分IDENTITY_INSERTはどういうわけか違う...とにかくステータスは何ですか?

sqlQuery(channel, "SELECT OBJECTPROPERTY(OBJECT_ID('Actuals'), 'TableHasIdentity')")
### RETURNS 1. 

は。addPK意味がわかりません...別の設定でもう一度試してみましょう

#################  Test 3, try to use addPK = TRUE to see if it makes difference.
sqlSave(channel, toSave, tablename = 'Actuals', append = T,
        rownames = F, colnames = F, verbose = T,
        safer = T, addPK = T, 
        fast = T, test = F)
### RETURNS ERROR: Cannot find the object \"Actuals\" because it does not exist or you do not have permissions."

それはまったく迷惑ではありません。OK FINE、まとめてIDを削除しましょう

################# Test 4, Try to remove the ID
NoID <- toSave[,-grep("ID",names(toSave))]

sqlSave(channel, NoID, tablename = 'Actuals', append = T,
        rownames = FALSE, colnames = FALSE, verbose = T,
        safer = TRUE, addPK = F, 
        fast = T, test = F)
### RETURNS ERROR: Error in odbcUpdate(channel, query, mydata, coldata[m, ], test = test,  : missing columns in 'data'

まあ、本当に?行方不明の列があります???????? 大丈夫

## So add back in a dummy column
NoID$dummy <- 0
sqlSave(channel, NoID, tablename = 'Actuals', append = T,
        rownames = FALSE, colnames = FALSE, verbose = T,
        safer = TRUE, addPK = F, 
        fast = T, test = F)
### RETURNS ERROR: Error in odbcUpdate(channel, query, mydata, coldata[m, ], test = test,  : missing columns in 'data'

設定fast=Fすると次のエラーが返されます。length of 'dimnames' [2] not equal to array extent

わかった。ggsqlSaveあなたが勝ち、私が負けます。ここで変更が必要だと思います...構築中のSQLクエリを確認すると、次のことがわかります。

Query: INSERT INTO "Actuals" ( "ID", "Date", "Project", "FiscalYear", "IndNum", "CorpCode", "CurrentValue", "NoteTitle", "NoteAnnotation", "IndName" ) VALUES ( ?,?,?,?,?,?,?,?,? )

列に追加しようとしないようにクエリを指定するだけのパラメータが必要だと思いますID...そうですか?

何か不足していますか?

4

1 に答える 1

1

これは私の回避策でした:

################# Test 5, Try issuing the append command manually:

Q <- "INSERT INTO \"Actuals\" ( \"Project\", \"FiscalYear\") VALUES ('test','hello');"
sqlQuery(channel, Q, errors = TRUE)

わかりました、それでうまくいきます!(だから私はそれが許可の問題ではないことを知っています)。ただし、正確にはこの形式です。テーブル/フィールド名には DOUBLE 引用符が必要で、データには SINGLE 引用符が必要です。では、このロジックを実際のデータに適用してみましょう。

## first drop the dummy again:
NoID <- NoID[,-grep("dummy",names(NoID))]

## Ensure field names are surrounded by a DOUBLE quote, values are surrounded by a SINGLE quote. 
## Separate out the Date field because `paste` converts it to character if it's in with the rest of the data.

Q <- paste(
  "INSERT INTO \"Actuals\"  ( \"Date\", \"Project\", \"FiscalYear\", \"IndNum\", \"IndName\", \"CorpCode\", \"CurrentValue\", \"NoteTitle\", \"NoteAnnotation\" )",
  " VALUES ( '", NoID[1,1], "','", paste(NoID[1,2:ncol(NoID)],collapse="','"),
  "')", sep="")

sqlQuery(channel, Q, errors = TRUE)

ついに!!わかりました、これは機能します。すべての DF に対して行うようになりましたが、2 つ以上の文字ベクトルをペアで結合するのは難しいので、次のようにします。

## first create a character vector for each row, with the quotation marks nicely blended.
crazyD <- ""
for(i in 1:ncol(NoID)){
  crazyD <- paste(crazyD,paste("'",NoID[,i],"'", sep=""),sep="")
} 
crazyD <- gsub("''","','",crazyD)

## And now combine that one with the titles
Q <- paste(
  "INSERT INTO \"Actuals\"  ( \"Date\", \"Project\", \"FiscalYear\", \"IndNum\", \"IndName\", \"CorpCode\", \"CurrentValue\", \"NoteTitle\", \"NoteAnnotation\" ) VALUES ( ",
  crazyD, ")", collapse="; ")

## And push that query into the server
sqlQuery(channel, Q, errors = TRUE)

そして、それが私がそれを行う方法です。誰かがそれをより良くする方法を教えてくれるまで、私は推測します。それまでは、SQL Server クエリの最大サイズについて教えてください。IN節?より良いアプローチはありますか

于 2016-03-24T14:32:00.823 に答える