Прямой ответ на ваш вопрос , предоставленный документами , и заключается в простом использовании метода String()
:
rows, err := db.Query(buffer.String())
Сказав это, буфер, вероятно, нездесь нет смысла.Для построения строк тип strings.Builder
более эффективен.
Но для вашего конкретного случая использования SQL-запросы таким способом опасны и подвержены ошибкам.Несколько предложений:
- НИКОГДА, НИКОГДА НИКОГДА не используйте конкатенацию строк или Sprintf / Fprintf для вставки значений в запросы SQL.Вы будете открыты для атак с использованием SQL-инъекций.Вместо этого всегда используйте параметризованные запросы.
- Большие блоки if / else подвержены ошибкам и их трудно читать.Вместо этого используйте правильный оператор switch.
- Вы можете использовать построитель SQL-запросов, но в вашем случае у вас есть только одна необязательная часть запроса.Для этого просто используйте стандартную конкатенацию строк.
Я переписал ваш код с учетом вышеуказанных проблем, и теперь он выглядит так:
var paidCondition string
args := []interface{}{masterID}
switch (
case e.Type == "today":
paidCondition = `AND ts.paid_on = CURDATE()`
case e.Type == "weekly":
paidCondition = `AND ts.paid_on > DATE_SUB(NOW(), INTERVAL 1 WEEK)`
case e.Type == "monthly":
paidCondition = `AND ts.paid_on > DATE_SUB(NOW(), INTERVAL 1 MONTH)`
case e.StartDate != "" && e.EndDate != "" && e.StartDate == e.EndDate:
paidCondition = `AND ts.paid_on = ?`
args = append(args, e.StartDate)
case e.StartDate != "" && e.EndDate != "":
paidCondition = `AND ts.paid_on >= ? AND ts.paid_on <= ?`
args = append(args, e.StartDate, e.EndDate)
)
query := `SELECT c.id, c.company_name, ss.start_date, ss.shift_length, ss.bill_rate, ss.ot_hrs, ss.dt_hrs, ts.pay_rate, ts.wc_rate, ts.paid, td.wc
FROM company c
JOIN users u1 ON c.id = u1.company_id
JOIN schedule s ON u1.id = s.user_id
JOIN schedule_shifts ss ON s.id = ss.schedule_id
JOIN technician_shifts ts ON ss.id = ts.shift_id
JOIN users u ON u.id = ts.technician_id
JOIN technician_details td ON td.user_id = u.id
JOIN master_technicians mt ON mt.id = u.master_technician_id
WHERE mt.id = ? AND ts.confirmed = 'yes' AND ts.paid = 'yes' ` + paidCondition
rows, err := db.Query(query, args...)
if err != nil {
log.Panic(err.Error())
}
И, наконец, пара другихулучшения, которые не связаны напрямую с вашим вопросом или предложенным мной кодом выше:
buffer.WriteString(fmt.Sprintf(
... ))
слишком многословно.Более короткая версия: fmt.Fprintf(buffer,
... )
. - Вы используете
fmt.Sprintf()
в нескольких местах, где форматирование не выполняется.Просто удалите это полностью.Например, замените fmt.Sprintf("AND ts.paid_on = CURDATE()")
просто "AND ts.paid_on = CURDATE()"
.