2016-10-05 12 views
2

Я создаю приложение в Голанге, которое использует Postgres, используя драйвер pq. Я хочу сделать функцию, которая может выбрать пользователь определенного поле из моей базы данных, но я получаю сообщение об ошибке:

pq: could not determine data type of parameter $1

Ниже приведен код, который генерируется сообщение об ошибке:

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 
} 

Почему я не вставьте поле, которое я хочу SELECT, используя $1? Есть ли другой способ сделать это?

+0

Связанный/возможный дубликат [GOLAN ORDER BY issue with MySql] (http://stackoverflow.com/questions/30867337/golang-order-by-issue-with-mysql). – icza

ответ

0

Вы не можете использовать заполнители для имен полей. Вы должны построить запрос непосредственно, как в:

"SELECT `" + field + "` FROM " 

Чтобы избежать инъекции SQL, убедитесь, что поле является частью списка разрешенных полей заранее.

+0

Я понял, что это один из способов сделать это, но для этого мне потребуется составить список имен полей в базе данных, что является проблемой для обновления при каждом обновлении поля в базе данных. Нет ли другого способа сделать это, используя вместо этого местозаполнитель? – Excl

+0

Вы можете применить регулярное выражение и убедиться, что допустимы только допустимые символы. – Kul

+1

Вы также можете получить список допустимых полей, используя что-то вроде этого: http://dba.stackexchange.com/a/22368/37012 Затем, возможно, кешируйте результат этого запроса, чтобы вы могли ссылаться на него по мере необходимости. –

-3

ИМХО более простой способ, но не безопасно, для создания запросов SQL является использование 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-инъекций. – icza

+0

Я не хотел, чтобы это было безопасно, просто ответил на вопрос «Есть ли другой способ сделать это?». – jnmoal

+1

@ Jean-NicolasMoal и, возможно, вы заставили кого-то потерять работу, LOL: D –

 Смежные вопросы

  • Нет связанных вопросов^_^