2016-10-05 34 views
2

pq 드라이버를 사용하여 Postgres를 사용하는 Golang 응용 프로그램을 만들고 있습니다. 내 데이터베이스에서 사용자가 결정 필드를 선택할 수있는 기능을 만들고 싶어하지만 오류 얻을 :

var ifc interface{} 

if err := conn.QueryRow("SELECT $1 FROM "+db+" WHERE uuid=$3 OR uri=$4 LIMIT 1", field, UUIDOrURI, UUIDOrURI).Scan(&ifc); err != nil { 
    if err == sql.ErrNoRows { 
     return http.StatusNotFound 
    } 

    log.Println(err) 

    return http.StatusInternalServerError 
} 

왜 내가 할 수있는 : 아래

pq: could not determine data type of parameter $1

이 오류를 생성 한 코드를 원하는 필드를 SELECT에 삽입하지 말고 $1을 사용 하시겠습니까? 이것을 할 또 다른 방법이 있습니까?

+0

[Golang ORDER BY issue with MySql]의 관련/가능한 복제본 (http://stackoverflow.com/questions/30867337/golang-order-by-issue-with-mysql). – icza

답변

0

필드 이름에 자리 표시자를 사용할 수 없습니다. 당신은 같이 직접 쿼리를 작성해야합니다 :

"SELECT `" + field + "` FROM " 

필드가 사전에 허용 필드 목록의 일부임을 확인, SQL 주입을 방지하기 위해. SQL 쿼리를 작성하는

+0

이 방법이 그 하나의 방법이라고 생각했지만 데이터베이스의 필드 이름 목록을 만들어야합니다. 데이터베이스의 필드를 업데이트 할 때마다 업데이트하는 번거 로움이 있습니다. 대신 자리 표시자를 사용하여 다른 방법을 사용할 수 있습니까? – Excl

+0

정규식을 적용하고 유효한 문자 만 허용 할 수 있습니다. – Kul

+1

다음과 같은 방법으로 올바른 필드 목록을 얻을 수도 있습니다. http://dba.stackexchange.com/a/22368/37012 그러면이 쿼리의 결과를 캐시하여 필요할 때 참조 할 수 있습니다. –

-3

이럴 쉬운 방법,하지만 안전하지가 사용하는 fmt.Sprintf입니다 :

query := fmt.Sprintf("SELECT %s FROM %s WHERE uuid=%s", field, db, UUIDOrURI) 
if err := conn.QueryRow(query).scan(&ifc); err != nil { 

} 
심지어 인수 인덱스를 지정할 수 있습니다

: 완화하기 위해

query := fmt.Sprintf("SELECT %[2]s FROM %[1]s", db, field) 

개발, postgresql 통신을위한 패키지를 사용하는 것이 좋습니다, 내가 시도 this one 좋은 일했다.

+2

_Easiest_는 _safest_를 의미하지 않습니다. 패키지'fmt'는 SQL 주입 공격에 대한 지식이 없으며 SQL 주입 공격을 막으려하지 않습니다. – icza

+0

나는 그것이 안전하다는 것을 의미하지 않았으며 단지 "다른 방법으로 이것을 할 수 있습니까?"라고 대답했습니다. – jnmoal

+1

@ Jean-NicolasMoal 그리고 어쩌면 누군가가 직장을 잃어 버렸을 것입니다. LOL : D –