Go: SQL
Теория: Передача параметров и защита от SQL-инъекций
Плейсхолдеры и передача параметров
Когда программе нужно передать значения в SQL-запрос, вместо прямой вставки текста используются плейсхолдеры. Приложение отправляет в базу текст запроса отдельно, а значения — отдельным списком аргументов. Драйвер сам подставляет значения в обозначенные позиции и не смешивает их с SQL-кодом. Формат плейсхолдеров зависит от СУБД: PostgreSQL использует $1, $2, $3, а MySQL и SQLite — ?.
Конкатенирование SQL-строки
Когда значение попадает в SQL через конкатенацию строк, программа перестаёт различать, где заканчиваются данные и начинается код. Любой ввод превращается в часть SQL-команды, и база исполняет его как полноценный фрагмент запроса. При использовании плейсхолдеров такого смешивания не происходит: текст запроса остаётся неизменным, а значения передаются отдельно.
Безопасные шаблоны при работе с SQL в Go чаще всего сводятся к повторяющемуся «каркасу» функции доступа к данным. Такой каркас использует текст запроса с плейсхолдерами, context.Context для управления временем выполнения, методы ExecContext() или QueryRowContext()/QueryContext() и явную проверку ошибки. Значения всегда передаются отдельными аргументами, а не через сборку строки. Один и тот же шаблон можно применять для чтения, вставки и обновления данных, меняется только запрос и список параметров.
IN и несколько значений
Когда запрос использует IN, значения тоже нужно передавать отдельно от SQL. Программа не вставляет список чисел прямо в строку, потому что длина списка и его содержимое меняются по ходу работы. В PostgreSQL для таких случаев удобно использовать конструкцию = ANY($1) и передавать срез как один параметр. В MySQL и SQLite список плейсхолдеров формируется программно, но сами значения всё равно передаются отдельным набором параметров.
имена колонок и параметры сортировки
В отличие от значений, имена колонок, направления сортировки и другие элементы синтаксиса нельзя передавать как параметры. Плейсхолдеры работают только для данных, а не для структурных частей SQL. Чтобы выбрать безопасный вариант, программа использует заранее определённый список доступных колонок или вариантов сортировки. Пользовательский ввод сравнивается с этим списком, и в запрос подставляется только разрешённая строка.


