Postgresql COALESCE返回的是文本类型,而不是Postgres中的时间戳类型

Postgresql COALESCE返回的是文本类型,而不是Postgres中的时间戳类型,postgresql,go,Postgresql,Go,我正在尝试使用COALESCE来处理Go中的sql注入 query := `SELECT mc.company_name_full, msc.company_id, msc.cdate, %s FROM %s AS mc INNER JOIN %s AS msc ON (mc.id = msc.company_id) WHERE %s AND msc.company_id = COALESCE($1, msc.com

我正在尝试使用COALESCE来处理Go中的sql注入

query := `SELECT mc.company_name_full, msc.company_id, msc.cdate, %s
          FROM %s AS mc INNER JOIN %s AS msc
          ON (mc.id = msc.company_id)
          WHERE %s AND
          msc.company_id = COALESCE($1, msc.company_id) AND
          mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND
          msc.cdate >= '2017-07-01' AND
          msc.cdate <= '%s'`
query = fmt.Sprintf(query, selectParam, companyTable, statsTable, whereParam, time.Now().Local().Format("2006-01-02"))

如何确保COALESCE返回时间戳类型?

您可以
文本
字符串转换为
时间戳
,如下所示:

`SELECT mc.company_name_full, msc.company_id, msc.cdate, %s
      FROM %s AS mc INNER JOIN %s AS msc
      ON (mc.id = msc.company_id)
      WHERE %s AND
      msc.company_id = COALESCE($1, msc.company_id) AND
      mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND
      msc.cdate >= COALESCE($3, '2017-07-01'::timestamp) AND
      msc.cdate <= COALESCE($4, '%s'::timestamp)`
$1
$2
是绑定。也就是说,库处理转义它们(Go的
pq
package是纯postgreslibpq库的Go包装器),并且应该防止SQL注入。它们绑定(即连接)随后传递的参数

e、 g.
$1
映射到
“橙色”
$2
映射到
64

相反,原始查询中对
%s
的引用是直接格式化的——这意味着没有基于Postgres(libpq)的转义,因此也没有针对SQL注入的保护。这些值只需直接传递


有关的更多详细信息。

您可以
文本
字符串转换为
时间戳
,如下所示:

`SELECT mc.company_name_full, msc.company_id, msc.cdate, %s
      FROM %s AS mc INNER JOIN %s AS msc
      ON (mc.id = msc.company_id)
      WHERE %s AND
      msc.company_id = COALESCE($1, msc.company_id) AND
      mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND
      msc.cdate >= COALESCE($3, '2017-07-01'::timestamp) AND
      msc.cdate <= COALESCE($4, '%s'::timestamp)`
$1
$2
是绑定。也就是说,库处理转义它们(Go的
pq
package是纯postgreslibpq库的Go包装器),并且应该防止SQL注入。它们绑定(即连接)随后传递的参数

e、 g.
$1
映射到
“橙色”
$2
映射到
64

相反,原始查询中对
%s
的引用是直接格式化的——这意味着没有基于Postgres(libpq)的转义,因此也没有针对SQL注入的保护。这些值只需直接传递


更多详细信息。

除了@khampson的答案外,CAST(表达式为类型)还可以转换类型

还同意sql注入的风险;联合本身并不是防止它的有效方法


使用准备好的查询和绑定参数进行常规参数替换。要替换表名变量,go sql包还没有提供标准接口(),所以请使用数据库库特定的quote函数,例如:。另请参见示例。

除了@khampson的答案外,CAST(表达式为类型)还可以转换类型

还同意sql注入的风险;联合本身并不是防止它的有效方法


使用准备好的查询和绑定参数进行常规参数替换。要替换表名变量,go sql包还没有提供标准接口(),所以请使用数据库库特定的quote函数,例如:。另请参见示例。

我不太熟悉术语interpole和binding,您介意提供一个示例吗?@richard\u sim:添加到我的原始答案中。我不太熟悉术语interpole和binding,您介意提供一个示例吗?@richard\u sim:添加到我的原始答案中。
`SELECT mc.company_name_full, msc.company_id, msc.cdate, %s
      FROM %s AS mc INNER JOIN %s AS msc
      ON (mc.id = msc.company_id)
      WHERE %s AND
      msc.company_id = COALESCE($1, msc.company_id) AND
      mc.company_name_full ~* COALESCE($2, mc.company_name_full) AND
      msc.cdate >= COALESCE($3, '2017-07-01'::timestamp) AND
      msc.cdate <= COALESCE($4, '%s'::timestamp)`
rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1
    OR age BETWEEN $2 AND $2 + 3`, "orange", 64)