Im Zusammenhang mit https://stackoverflow.com/a/33284035/3358272, finde ich inkonsistente Verhalten beim Ziehen von Daten aus SQL Server (2014).RODBC: Chars und Numerik aggressiv konvertiert (mit/ohne as.is)
library(RODBC)
sqlQuery(.conn, "CREATE TABLE r2test ([mychar] [NVARCHAR](16), [mynum] [FLOAT])")
# character(0)
sqlQuery(.conn, "INSERT INTO r2test (mychar,mynum) VALUES ('1',3.141593),('2',6.283185)")
character(0)
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE))
# 'data.frame': 2 obs. of 2 variables:
# $ mychar: int 1 2
# $ mynum : num 3.14 6.28
In diesem Beispiel sehen wir das unerwünschte Verhalten: Die Zeichen von mychar
werden intern auf ganze Zahlen umgewandelt werden. Per die zuvor erwähnte SO beantworten, die as.is
Option besiegt dies, hat aber den unglücklichen Nebeneffekt auch dezimal repräsentiert Schwimmer in Strings zu zwingen:
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE, as.is = TRUE))
# 'data.frame': 2 obs. of 2 variables:
# $ mychar: chr "1" "2"
# $ mynum : chr "3.1415929999999999" "6.2831849999999996"
Wenn mindestens einer der mychar
eigentlich nicht integer-izable ist , sind die Dinge in Ordnung:
sqlQuery(.conn, "INSERT INTO r2test (mychar,mynum) VALUES ('a',9.424778)")
# character(0)
str(sqlQuery(.conn, "SELECT * FROM r2test", stringsAsFactors = FALSE))
# 'data.frame': 3 obs. of 2 variables:
# $ mychar: chr "1" "2" "a"
# $ mynum : num 3.14 6.28 9.42
Leider ist das Datenmodell nicht willkürlich etwas unterstützt das Hinzufügen dieses Verhalten zu fördern (oder ich habe einfach nicht daran gedacht, eine ausreichend gute Art und Weise, es zu tun). Das Datenmodell ist derart, dass Werte von mychar
01
und 1
umfassen, die zeichenweise verschieden sind. Die einzige Problemumgehung, die ich gefunden habe, ist, as.is = TRUE
zu verwenden, die mich zu as.numeric
alle verwandten Spalten benötigen wird, etwas, das sowohl langweilige als auch (theoretisch) unnötige Arbeit ist.
Da die Dokumente zu setzen DBMSencoding
empfehlen benötigen, überprüfte ich die aktuelle Codierung (unterstützt von https://stackoverflow.com/a/5182469/3358272):
sqlQuery(.conn, "SELECT SERVERPROPERTY('Collation')")
# 1 SQL_Latin1_General_CP1_CI_AS
Ich habe versucht, mit (für Kicks): DBMSencoding="latin1"
, DBMSencoding="UTF-8"
und explizit obwohl der Standard DBMSencoding=""
ohne Verhaltensänderung.
Wie kann ich das Verhalten ermutigen, die Datentypen nicht zu übersteuern?
Derzeit mit R-3.2.5 und RODBC-1.3.13 auf Ubuntu.
Ich hatte nicht in Betracht gezogen, einen logischen * Vektor * zu verwenden, der die Dinge ein wenig verbessert und einen direkteren Ausweg bietet, danke! Einverstanden auf das "sehe nicht warum", aber andererseits biete ich (noch) nicht an, Code zu schreiben (und eine PR einzureichen), um die Dinge anders zu behandeln. – r2evans
Ja, es ist etwas verwirrend, wenn Funktionsargumente einen Standardwert von 'TRUE' oder 'FALSE' haben, aber auch einen logischen * Vektor * akzeptieren. Und außerdem, ich habe eine langjährige Knochen zu wählen mit diesem Paket über 'sqlUpdate' funktioniert nicht wie angekündigt, aber ich habe noch nicht zu arbeiten auf einem Patch, so dass ich nicht zu laut beschweren kann ... – nrussell
nrussell , außer * R-sigs-db *, kennst du noch ein anderes RODBC-spezifisches Diskussionsforum? Quellcode für Probleme und PRs? Ich würde gerne Dinge wie parametrisierte Abfragen, Partialtabellen 'sqlSave' und andere Dinge diskutieren, die meine Verwendung von RODBC unnötig einschränken. – r2evans