在数据浏览器查询中使用参数

参数(Parameters)是一种强大的工具,可用于 Data Explorer 中的查询。参数允许进行更动态和可定制的查询,您无需在查询中硬编码值,而是可以声明变量,这些变量会在运行查询时提示输入。

声明参数

要声明一个参数,您可以使用以下语法:

-- [params]
-- int :parameter_name = 10

查询中的参数部分始终以 -- [params] 开头,随后每一行定义一个参数类型,其中 parameter_name 应替换为您参数的名称。

这将创建一个字段,允许您在每次运行查询时输入不同的值。

参数类型

在您的 Data Explorer 查询中声明参数时,您可以指定不同的输入类型。以下是可用的参数类型及其描述:

数值参数

  • int:显示数字输入框,转换为数值。int 限制为 32 位数字。
  • bigint:类似于 int,但可以更大。
  • double:允许小数。

数值参数的正确性将在前端进行验证。

字符串参数

  • string:自由格式文本框,转换为文本值。

列表参数

  • int_list:输入逗号分隔的整数,在查询中变为逗号分隔的整数。
  • string_list:类似于 int_list,但用于字符串。

特定 ID 参数

  • post_id:数字输入;在运行查询前确保指定的帖子存在于论坛上。
  • topic_id:类似于 post_id,但用于主题。
  • badge_id:确保指定的徽章存在。

布尔参数

  • boolean:显示复选框。
  • null boolean:显示下拉菜单,允许空输入。

时间参数

  • time:显示时间选择器输入。
  • date:显示日期选择器输入。
  • datetime:显示包含日期和时间的输入框。

选择器参数

  • user_id:显示 Discourse 用户选择框,并转换为数字用户 ID。
  • user_list:类似于 user_id,但允许多个用户,变为逗号分隔的数字用户 ID 列表。
  • group_id:类似于 user_id,但用于群组。
  • group_list:类似于 user_list,但用于群组。
  • category_id:类似于 user_id,但用于分类。

内部参数

  • current_user_id:无输入界面;自动将变量设置为运行查询的用户的用户 ID

使用列表参数

使用列表参数(int_liststring_listuser_list)时,必须特别注意以避免语法错误。以下是正确使用列表参数的示例:

-- [params]
-- user_list :the_user_ids
SELECT SUM(length(bio_raw))
FROM user_profiles
WHERE user_id IN (:the_user_ids)

空值参数

您可以通过在参数类型前加上 null 前缀来允许空输入。这意味着在运行查询时,该参数不需要提供值。

以下是如何声明此类参数的一些示例:

-- [params]
-- null int :null_int
-- null boolean :null_boolean
-- null string :null_string
-- null current_user_id :me

在上述 SQL 中,null_intnull_booleannull_string 是在运行查询时可以留空的参数。

让我们看看如何在查询中使用这些类型的参数:

-- [params]
-- null int :post_id
-- null string :username
SELECT *
FROM users
WHERE (id = :post_id OR :post_id IS NULL)
AND (username = :username OR :username IS NULL)

在此查询中,如果未提供 post_idusername(即保持为 null),查询将忽略 WHERE 子句中的那部分。这允许更灵活的查询,其中某些条件是可选的。

前端验证

大多数类型的参数将在前端进行验证。这些验证包括必填但未填写的输入、无效的数字输入、不存在的分类或群组、格式错误的时间等。对于无效输入,错误原因将显示在表单中,并且运行查询的操作将被拒绝。

选择类型和使用转换

通常,参数在您的查询中应该“直接生效”。对于更高级的情况,您可能需要添加显式的 ::type 转换。

例如,对于间隔(intervals),您需要声明一个字符串参数并将其转换为 interval。值可以包含单位,例如 2 day 或 3 hours:

-- [params]
-- string :lookback = 2 day

SELECT id AS topic_id, created_at
FROM topics
WHERE created_at >= NOW() - :lookback::interval

某些函数也需要显式的参数类型:

round(amount::numeric, :decimal_places::integer)
date_trunc('day', :start_date::timestamp)

更多示例

以下是声明不同类型参数的一些额外示例:

-- [params]
-- int             :int = 3
-- bigint          :bigint = 12345678912345
-- boolean         :boolean
-- null boolean    :boolean_three = #null
-- string          :string = little bunny foo foo
-- date            :date = 14 jul 2015
-- time            :time = 5:02 pm
-- datetime        :datetime = 14 jul 2015 5:02 pm
-- double          :double = 3.1415
-- string          :inet = 127.0.0.1/8
-- user_id         :user_id = system
-- post_id         :post_id = http://localhost:3000/t/adsfdsfajadsdafdsds-sf-awerjkldfdwe/21/1?u=system
-- topic_id        :topic_id = /t/-/21
-- int_list        :int_list = 1,2,3
-- string_list     :string_list = a,b,c
-- category_id     :category_id = meta
-- group_id        :group_id = admins
-- user_list       :mul_users = system,discobot
-- current_user_id :me 

本系列中的更多主题

这些指南很棒,谢谢你发布它们 @SaraDev :slight_smile: :拥抱:

@AlexDev
where 子句中的字段名可以是参数吗?谢谢
或者整个 SQL 语句可以作为参数从 REST 端点 /admin/plugin/explorer/queries/id/run 传入吗?

PSA:参数名称不能使用数字,例如“foo123”将失败。

-- [params]
-- string       :foo123 = a

SELECT :foo123

导致

PG::SyntaxError: ERROR:  syntax error at or near ":"
LINE 10: SELECT :foo123
                ^

我尝试使用 JSON 负载中的参数对 run 端点进行 POST 调用,如下所示:

payload = {
    "params": {
        "request_post_id": "45"
    },
    "explain": False
}

我从 Chrome 开发者工具的负载中逆向工程了该负载。
不知何故,我一直收到 500 服务器错误。

有人能帮帮我吗?

公告:这是最近由

FEATURE: Add current_user_id parameter type to Data Explorer by ZogStriP · Pull Request #36655 · discourse/discourse · GitHub 添加的

功能请求: 是否可以添加 tag_group 作为参数类型,它将注入所选标签组的整数 ID?