2016-10-05 2 views
2

Ich erstelle eine Anwendung in Golang, die Postgres mit dem pq-Treiber verwendet. Ich möchte eine Funktion machen, die einen vom Benutzer bestimmten Bereich aus meiner Datenbank auswählen können, aber ich erhalte eine Fehlermeldung:

pq: could not determine data type of parameter $1

Unten ist der Code, der diesen Fehler generiert:

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 
} 

Warum kann ich nicht das Feld, das ich möchte SELECT mit $1? Gibt es einen anderen Weg, dies zu tun?

+0

Zugehöriges/mögliches Duplikat von [Golang ORDER BY-Problem mit MySql] (http://stackoverflow.com/questions/30867337/golang-order-by-issue-with-mysql). – icza

Antwort

0

Sie können keine Platzhalter für Feldnamen verwenden. Sie verlassen nun die Abfrage direkt bauen müssen, wie in:

"SELECT `" + field + "` FROM " 

Um SQL-Injektionen zu vermeiden, stellen Sie sicher, dass das Feld vorher Teil einer Liste der erlaubten Felder ist.

+0

Ich dachte mir, dass dies eine Methode ist, aber das würde bedeuten, dass ich eine Liste von Feldnamen in der Datenbank erstellen müsste, was jedes Mal, wenn ich ein Feld in der Datenbank aktualisiere, mühsam zu aktualisieren ist. Gibt es keine andere Möglichkeit, stattdessen einen Platzhalter zu verwenden? – Excl

+0

Sie können eine Regex anwenden und sicherstellen, dass nur gültige Zeichen zulässig sind. – Kul

+1

Sie können auch die Liste der gültigen Felder mit etwas wie diesem erhalten: http://dba.stackexchange.com/a/22368/37012 Dann Cache möglicherweise das Ergebnis dieser Abfrage, so dass Sie nach Bedarf verweisen können. –

-3

IMHO ein einfacher Weg, aber nicht sicher, SQL-Abfragen zu erstellen, ist fmt.Sprintf zu verwenden:

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

} 

Sie auch ein Argument Index angeben:

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

Um zu erleichtern die Entwicklung, ich empfehle, ein Paket für die postgresql Kommunikation zu verwenden, versuchte ich this one und arbeitete großartig.

+2

_Easiest_ impliziert nicht _safest_. Das Paket 'fmt' kennt keine SQL-Injection-Angriffe und versucht nicht, diese zu verhindern. – icza

+0

Ich meinte es nicht sicher, beantwortete nur die Frage "Gibt es einen anderen Weg, dies zu tun?". – jnmoal

+1

@ Jean-NicolasMoal und wahrscheinlich hast du jemanden seinen Job verloren, lol: D –

Verwandte Themen