そのため、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
...そうですか?
何か不足していますか?