2016-07-18 1 views
3

https://stackoverflow.com/a/33284035/3358272과 관련하여 SQL Server (2014)에서 데이터를 가져 오는 것과 일관성없는 동작이 나타납니다. mychar의 문자가 내부적으로 정수로 변환되고 : 그 예에서 RODBC : 공격적으로 변환 된 문자와 숫자

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 

우리는 원하지 않는 동작을 참조하십시오. 대답 SO 이전에 언급 한의 as.is 옵션은이 패배뿐만 아니라 문자열로 소수점 표현 된 수레를 강제 불행한 부작용이 당 : mychar 중 적어도 하나가 실제로없는 정수 izable 경우

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" 

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 

불행하게도, 데이터 모델이 동작을 장려하기 위해 뭔가를 추가 임의적으로 지원하지 않습니다 (또는 난 그냥 그 일을하는 좋은 충분한 방법을 생각하지 않은) : 일이 잘됩니다. 데이터 모델은 mychar의 값이 문자로 구분되는 011을 포함합니다. 내가 발견 한 유일한 해결 방법은 as.numeric 관련된 모든 열을 필요로하는 as.is = TRUE을 사용하는 것입니다.이 작업은 지루하고 이론적으로 불필요한 작업입니다.

sqlQuery(.conn, "SELECT SERVERPROPERTY('Collation')") 
# 1 SQL_Latin1_General_CP1_CI_AS 

내가 (차기를 위해)를 사용하여 시도했다 : : 워드 프로세서가 DBMSencoding을 설정할 필요가 제안 이후

, 나는 (https://stackoverflow.com/a/5182469/3358272의 도움) 현재의 인코딩 확인 DBMSencoding="latin1", DBMSencoding="UTF-8"을 명시 적으로 기본 생각 DBMSencoding="" 동작이 변경되지 않았습니다.

데이터 형식을 지나치게 강요하지 않는 것을 어떻게 권장 할 수 있습니까?

현재 우분투에서는 R-3.2.5 및 RODBC-1.3.13을 사용하고 있습니다. 만약 내가 제대로 이해하고 당신이 찾고있는 경우

답변

4

, 나는이 as.is 논리 벡터로 지정

str(sqlQuery(
    .conn, 
    "SELECT * FROM r2test", 
    stringsAsFactors = FALSE, 
    as.is = c(TRUE, FALSE) 
)) 
#'data.frame': 2 obs. of 2 variables: 
# $ mychar: chr "1" "2" 
# $ mynum : num 3.14 6.28 

이 (결과 집합의 열 수와 같은 길이가 있어야합니다) 생각 . 공정하게 말하면, 이것은 정말로 잘 설명되어 있지 않습니다. sqlQuery에 대한 man 페이지는 상태 read.tableas.is 인수를 참조하라는 : as.is

참고 열별로 지정 (안 변수 당) 등 은 행 이름의 열 (있는 경우 포함) 및 어떤 열도 이 건너 뜁니다.

이 방법의 단점은 변환하려는 열과 그렇지 않은 열을 미리 알아야한다는 것입니다. 개인적으로 내가 볼 수 없다 의 기본 동작은 SQL 문자 유형을 R 문자 유형, SQL 숫자 유형을 R 숫자 유형 등으로 매핑하는 것이 아니라 백엔드에서 이러한 이유가있을 수 있습니다. '1', '2', ...을 정수로 자동 변환하면 이 아닌은 나에게 많은 "기능"처럼 보입니다.

+1

논리적 인 * vector *를 사용하지 않았다면, 좀 더 개선 된 방법을 제공합니다. 감사합니다! "왜 보이지 않는가"에 동의했지만, 다시 한번 말하지만 (나는) 코드를 작성하고 (PR을 제출하여) 상황을 다르게 처리 할 수있는 제안이 아닙니다. – r2evans

+0

그렇습니다. 함수 인수의 기본값이 'TRUE' 또는'FALSE '일 때 논리적 * 벡터 *를 사용할 때 다소 혼란 스럽습니다. 그리고 저는 광고 패키지처럼'sqlUpdate'에 관해서이 패키지를 골라야 할 오래된 뼈가 있습니다. 그러나 너무 큰 소리로 불평 할 수 없기 때문에 나는 아직 패치 작업을하지 않았습니다 ... – nrussell

+1

nrussell * R-sigs-db * 외에도 다른 RODBC 관련 토론 포럼에 대해 알고 있습니까? 문제점 및 홍보를위한 소스 코드? 매개 변수화 된 쿼리, 부분 테이블'sqlSave' 및 불필요하게 RODBC 사용을 제한하는 기타 사항에 대해 논의하고 싶습니다. – r2evans