使用SQL参数化查询
InfluxDB集群中的参数化查询允许动态且安全地更改查询中的值。如果您的应用程序代码允许用户输入自定义查询中的值或表达式,请使用参数化查询以确保不受信任的输入被严格作为数据处理,而不是作为代码执行。
参数化查询
- 帮助预防注入攻击,如果输入被作为代码执行可能会发生此类攻击
- 帮助使查询更具重用性
预防注入攻击
有关安全和查询参数化的更多信息,请参阅OWASP SQL注入预防备忘单。
InfluxDB v3中的参数化查询是包含一个或多个命名参数占位符的InfluxQL或SQL查询 - 代表输入数据的变量。
参数仅在WHERE表达式中受支持
InfluxDB v3支持WHERE子句中的谓词表达式中的参数。参数值必须是允许的参数数据类型之一。
如果在其他表达式或子句中使用参数,例如函数参数、SELECT
或 GROUP BY
,则查询可能无法按预期工作。
在WHERE表达式中使用参数
您可以在 WHERE
子句的 谓词表达式 中使用参数——例如,以下查询包含一个 $temp
参数
SELECT * FROM measurement WHERE temp > $temp
在执行查询时,您指定参数名-值对。分配给参数的值必须是 参数数据类型 之一。
{"temp": 22.0}
InfluxDB 查询器使用参数占位符解析查询文本,然后生成查询计划,将占位符替换为提供的值。这种将查询结构与输入数据分离的做法确保输入被视为允许的 数据类型 之一,而不是可执行代码。
参数数据类型
参数值可以是以下数据类型之一
- 空值
- 布尔值
- 无符号整数(
u_int64
) - 整数(
int64
) - 双精度浮点数(
float64
) - 字符串
数据类型示例
{
"string": "Living Room",
"double": 3.14,
"unsigned_integer": 1234,
"integer": -1234,
"boolean": false,
"null": Null,
}
时间表达式
要参数化时间范围,用参数替换时间戳文字——例如
SELECT *
FROM home
WHERE time >= $min_time
对于参数值,将时间戳文字指定为字符串——例如
InfluxDB 按以下方式执行查询
与参数不兼容
如果您为以下内容使用参数,则查询可能无法按预期工作
- 除
WHERE
子句之外的其他子句中,例如SELECT
或GROUP BY
- 作为函数参数,例如
avg($temp)
- 在标识符的位置,例如列名或表名
- 在持续时间文字的位置,例如
INTERVAL $minutes
参数化一个SQL查询
示例数据
以下示例使用 入门家居传感器数据。要运行示例查询并返回结果,请在运行示例查询之前将示例数据写入您的 InfluxDB 集群数据库。
要使用参数化查询,请执行以下操作
在查询文本中,使用
$parameter
语法引用参数名——例如,以下查询包含$room
和$min_temp
参数占位符SELECT * FROM home WHERE time > now() - INTERVAL '7 days' AND temp >= $min_temp AND room = $room
为每个参数名提供值。如果您未为参数分配值,InfluxDB 将返回错误。提供参数值的语法取决于您使用的客户端——例如
// Define a QueryParameters struct--a map of parameters to input values. parameters := influxdb3.QueryParameters{ "room": "Kitchen", "min_temp": 20.0, }
InfluxDB 收到您的请求并解析查询后,将按以下方式执行查询
SELECT *
FROM home
WHERE time > now() - INTERVAL '7 days'
AND temp >= 20.0
AND room = 'Kitchen'
执行参数化SQL查询
示例数据
以下示例使用 入门家居传感器数据。要运行示例查询并返回结果,请在运行示例查询之前将示例数据写入您的 InfluxDB 集群数据库。
使用InfluxDB Flight RPC客户端
使用 InfluxDB v3 原生 Flight RPC 协议和受支持的客户端,您可以发送参数化查询和参数名-值对列表。支持参数化查询的 InfluxDB Flight 客户端将参数名-值对传递到 Flight 机票的 params
字段。
以下示例显示了如何使用客户端库执行参数化 SQL 查询
import (
"context"
"fmt"
"io"
"os"
"text/tabwriter"
"time"
"github.com/apache/arrow/go/v14/arrow"
"github.com/InfluxCommunity/influxdb3-go/influxdb3"
)
func Query(query string, parameters influxdb3.QueryParameters) error {
url := os.Getenv("INFLUX_HOST")
token := os.Getenv("INFLUX_TOKEN")
database := os.Getenv("INFLUX_DATABASE")
// Instantiate the influxdb3 client.
client, err := influxdb3.New(influxdb3.ClientConfig{
Host: url,
Token: token,
Database: database,
})
if err != nil {
panic(err)
}
// Ensure the client is closed after the Query function finishes.
defer func(client *influxdb3.Client) {
err := client.Close()
if err != nil {
panic(err)
}
}(client)
// Call the client's QueryWithParameters function.
// Provide the query and parameters. The default QueryType is SQL.
iterator, err := client.QueryWithParameters(context.Background(), query,
parameters)
// Create a buffer for storing rows as you process them.
w := tabwriter.NewWriter(io.Discard, 4, 4, 1, ' ', 0)
w.Init(os.Stdout, 0, 8, 0, '\t', 0)
fmt.Fprintf(w, "time\troom\tco\thum\ttemp\n")
// Format and write each row to the buffer.
// Process each row as key-value pairs.
for iterator.Next() {
row := iterator.Value()
// Use Go arrow and time packages to format unix timestamp
// as a time with timezone layout (RFC3339 format)
time := (row["time"].(arrow.Timestamp)).
ToTime(arrow.Nanosecond).Format(time.RFC3339)
fmt.Fprintf(w, "%s\t%s\t%d\t%.1f\t%.1f\n",
time, row["room"], row["co"], row["hum"], row["temp"])
}
w.Flush()
return nil
}
func main() {
// Use the $placeholder syntax in a query to reference parameter placeholders
// for input data.
// The following SQL query contains the placeholders $room and $min_temp.
query := `
SELECT *
FROM home
WHERE time > now() - INTERVAL '7 days'
AND temp >= $min_temp
AND room = $room`
// Define a QueryParameters struct--a map of placeholder names to input values.
parameters := influxdb3.QueryParameters{
"room": "Kitchen",
"min_temp": 20.0,
}
}
客户端对参数化查询的支持
- 并非所有 InfluxDB v3 Flight 客户端 都支持参数化查询。
- InfluxDB 目前不支持 Flight SQL 或 Flight SQL 客户端的参数化查询或 DataFusion 预编译语句。
- InfluxDB v3 SQL 和 InfluxQL 参数化查询在 InfluxDB v1 和 v2 客户端中不受支持。
不支持
目前,InfluxDB 集群中的参数化查询不提供以下功能
- 支持 DataFusion 预编译语句
- 查询缓存、优化或性能优势
这个页面有帮助吗?
感谢您的反馈!