QueryDatabase¶
对当前用户的 Macro 数据库运行 SQL——这是读取或修改其中行的唯一方式。用 SELECT 回答问题,用 INSERT/UPDATE/DELETE 修改数据,用 CREATE/ALTER/DROP 编辑架构。每次调用一条语句。
用户能看到的每个表都已经在作用域内,跨其所有数据库。 语句以该用户身份运行,并且只针对他们被允许读取的内容:看不到的表就相当于不存在,只有查看权限的表是只读的。始终为语句所涉及的数据库传递 databaseId,以便其表在名称冲突中胜出。
除非你已经知道确切的表和列名,否则请先调用 DescribeDatabase。 名称是用户输入的显示名称,因此对含空格的名称要加引号。如果语句失败,错误会指出问题所在并建议最接近的名称——阅读它、修正它、重试。
SQL 方言¶
一个由 Macro 编译的小型 SQL 子集。行查询通过共享 SQL 引擎运行;架构命令在服务器上通过与 UI 相同的数据库服务和原子操作运行。
- 读取:
SELECT [DISTINCT] items FROM [database.]table [alias] {[LEFT] JOIN [database.]table [alias] ON a.col = b.col [AND ...]} [WHERE cond] [GROUP BY col] [ORDER BY col|alias|position [ASC|DESC], ...] [LIMIT n [OFFSET m]]。items 可以是*、列,或COUNT(*)、COUNT(col)、SUM(col)、AVG(col)、MIN(col)、MAX(col),每一项都可用AS name命名;该别名命名结果列,并可用于 ORDER BY。GROUP BY 只接受一个列,分组的 SELECT 只能在该列旁边列出它的聚合函数。不支持其他表达式或函数,不支持 HAVING,WHERE 中列只能与字面量比较。 - 联接(Joins) 是组合表的方式:
- 可联接的方式: 每个
ON通过=(HAS表示同样的意思)把新联接的表中的一列与查询中已有表的一列配对,多个配对用 AND 连接。两侧必须是同一种类型:文本与文本(精确且区分大小写)、数字与数字、日期与日期;关系列、人员列或其他实体列与row_id或另一个实体列配对,例如macro.people.id。选项(Select)列只有在共享选项时才匹配。表可以来自不同的数据库,一个表可以在另一个别名下联接自身,联接还可以链式进行:SELECT t."Name", d."Name", p.email FROM "Ops"."Tasks" t JOIN "Sales"."Deals" d ON t."Deal" = d.row_id JOIN macro.people p ON d."Owner" = p.id。 - 返回什么: JOIN 只保留有匹配项的行;LEFT JOIN 保留前序表中的所有行,在没有匹配的联接表列中以 NULL 填充。多值的关系或人员单元格按每个值匹配一次,因此一个有两个负责人(assignees)的任务会返回两行,空单元格则什么也不匹配。聚合会对联接后的行计数:
SELECT p.name AS person, COUNT(*) AS tasks FROM "Tasks" t JOIN macro.people p ON t."Assignees" = p.id GROUP BY p.name ORDER BY tasks DESC。若要基于联接表的列进行过滤,请使用 JOIN 而不是 LEFT JOIN。 - 被拒绝的用法: 除
=或HAS之外的任何ON测试、ON中的 OR、同一张表内的ON、RIGHT、FULL 以及逗号联接。 - 行数上限: 查询读取的每个表最多 20,000 行,之后该表会被列入
truncatedTables,因此任何超过该总数的统计都是不完整的。只有对 select、人员、实体和关系列(而非row_id)进行的=、IN 和 HAS 测试才会缩小表的读取范围;其他条件只作用于已读取的行。被联接的表只读取与先前行的联接值匹配的行,最多 100 个不同的值;超过这个数量则读取整张表。 - 不支持子查询(
IN (SELECT ...)):先用 SELECT 查出 id,再把它们用作字面量(WHERE row_id IN ('<id>', '<id>')),或者使用 JOIN。 - 条件:
col = | != | < | <= | > | >= literal,col [NOT] IN ('a', 'b'),col [NOT] LIKE '%pat%'(不区分大小写),col IS [NOT] NULL,col [NOT] HAS 'x'(多值列中的成员判断),可用 AND、OR 和括号组合。 - 字面量:
'text'(内部引号要双写:'Wolf''s place')、数字、TRUE/FALSE、NULL;日期是'2026-08-13'或 ISO 日期时间。 - 日期范围: date_range 单元格写作 ISO 区间
'2026-08-13/2026-08-20'(单个日期是一天的区间),并与日期比较:=表示包含该日期,!=表示不包含,<表示在该日期之前结束,>表示在该日期之后开始,<=表示在该日期或之前开始,>=表示在该日期或之后结束。覆盖八月的区间:WHERE "Span" >= '2026-08-01' AND "Span" <= '2026-08-31'。排序按开始时间,然后按结束时间。 - 写入:
INSERT INTO table (col, ...) VALUES (...), (...)或INSERT INTO table DEFAULT VALUES;UPDATE table SET col = value, ... WHERE cond;DELETE FROM table WHERE cond。WHERE 是必需的,并且可以接受任意条件;WHERE row_id = '<id>'或row_id IN ('<id>', ...)指定行,且每个被指定的 id 都必须存在:要先读取 id。SET col = other_col会从同类型的列中复制每行自身的值。多值单元格写作列表['Urgent', 'Backend'];NULL清除单元格。 row_id是每一行的 id。返回行形状的 SELECT 会在rowIds中返回每个结果行的 id,INSERT 则会在insertedRowIds中返回新行的 id;绝不要编造一个。行的标题是第一列;应用中显示为“Unnamed”的行的标题是 NULL:用WHERE "Name" IS NULL查找它。- 名称就是显示名称。 对含空格或标点的表名或列名使用双引号(
FROM "Guest List" WHERE "Due Date" < '2026-09-01');名称匹配不区分大小写,不匹配时会提示最接近的名称。表可以用所属数据库的名称来限定(FROM "Offsite"."Guests")。 - Select 列和标签列接受选项标签(
"Status" = 'Going'),绝不接受选项 id。只有该列自带的标签会被接受;可以用ALTER TABLE table ALTER COLUMN col ADD OPTIONS ('New label')添加新选项。 - 关系列保存另一张表的行 id。 写入一组行 id(
"Guests" = ['<row id>']),用HAS '<row id>'测试,并通过ON i."Guest" = g.row_id联接:SELECT p."Name" AS party, COUNT(*) AS invites FROM "Invites" i JOIN "Parties" p ON i."Party" = p.row_id GROUP BY p."Name"。绝不要将关系列与名称进行比较。 - 人员和其他实体列保存的是 Macro id, 绝不是名称:人员用
'macro|sam@example.com',多值列用列表。请遵守每个列的specificEntityType。 - 人员:
macro.people是用户认识的所有人(联系人和队友),包含id、name和email,也包括查看者本人:“我(me)”是指 email 与当前登录用户一致的那一行。它是只读的。在那里面查找人员,然后写入他们的 id:SELECT id, name, email FROM macro.people WHERE name LIKE '%julia%' OR email LIKE '%julia%',然后UPDATE "Parties" SET "Host" = 'macro|julia@example.com' WHERE row_id = '<id>'。通过联接来读取姓名或 email:JOIN macro.people p ON t."Owner" = p.id。绝不要编造一个人或一个 id;当一个姓名匹配多个人或没有任何匹配时,请询问。 - 更改列的类型:
ALTER TABLE table ALTER COLUMN col TYPE type,其中 type 为 text、number、boolean、date、date_range、link、select、select_number、tag 或 entity(USER)、entity(DOCUMENT)、entity(TASK)…,用[]表示多个值(select[])。请调用 DescribeDatabase 并传入includeEditingMetadata: true以获取该列的safeTypes和checkedTypes。不合适的值,或会被单值类型截断的多值单元格,会导致语句被拒绝并附上计数和示例:用 UPDATE 修复这些值,或新增一列。 - 架构命令(Schema commands)(每次调用一条语句;需要编辑权限):
CREATE DATABASE "Sales CRM"会创建它的起始表,其中带一个 Name 列。在编辑它之前,请使用返回的数据库 ID 调用 DescribeDatabase;请复用那个起始表。ALTER DATABASE "Sales CRM" RENAME TO "Sales"和ALTER DATABASE "Sales" REORDER TABLES (Deals, Companies)。CREATE TABLE "Sales".Deals (Name text, Value number, Stage select OPTIONS ('Lead', 'Won'), Owner entity(USER), Company relation(Companies))。限定数据库或传入 databaseId。至少需要一个列;第一个列是行标题。所有列和选项都是原子创建的。ALTER TABLE Deals RENAME TO Opportunities;DROP TABLE Deals会删除其行、列和视图,但受领域的“最后一张表”保护和依赖保护的限制。ALTER TABLE Deals ADD COLUMN "Close Date" date;ALTER TABLE Deals RENAME COLUMN Value TO Amount;ALTER TABLE Deals DROP COLUMN Amount(删除其值)。ALTER TABLE Deals ALTER COLUMN Stage ADD OPTIONS ('Review', 'Lost');ALTER TABLE Deals REORDER COLUMNS (Name, Value, Stage)(需要列出所有列)。relation([database.]table)是对该表行的多值引用,在添加或更改列类型时被接受。- 架构写入会返回一个已提交的摘要和数据库 ID。请阅读 DescribeDatabase 以获取新的 ID 和名称。不要因为后续架构读取失败就重复执行 CREATE。不支持 DROP DATABASE、IF EXISTS、约束或批量多语句。
- 已保存视图: SaveDatabaseView 和 DeleteDatabaseView 用于管理表格/看板的呈现。看板按单选列或单人列分组;SaveDatabaseQuery 保存实时的 SQL 结果和图表。
- 你只有查看权限的表是只读的。
要更改记录,请先用 SELECT 选中您所指的行(其 ID 位于 rowIds 中),然后仅对 WHERE row_id IN (...) 指定的那些行执行 UPDATE 或 DELETE。更改行之后,请 SELECT 受影响的记录以验证实际结果。如果连接失败,请在重试 INSERT 之前先检查。
要一次性创建行并建立关联,请在 INSERT 时设置关系列为目标行 ID(INSERT INTO invites (guest, status) VALUES (['<guest row id>'], 'Sent'));新行的 ID 位于 insertedRowIds 中。
结果以类型化单元格的列和行形式返回({"type": "text", "value": "Sam"};null 表示空单元格),同时带有 rowIds,即每个行形 SELECT 结果行背后的行 ID。每列都标明其 kind。select 列会列出其 options,其单元格保存选项 ID:请在那里读取它们的标签。实体列标明其 target,应用据此将其 ID 渲染为可点击的标签——优先选择实体列,而不是将其字符串化。row_id 列的 kind 为 row:其单元格为 {"type": "row", "value": "<row id>"},是它作为 relatedTable 所命名的表的行,而不是 Macro 实体。写入操作会报告 changesApplied,对于插入操作,还会报告服务器生成的 insertedRowIds。
要回答关于数据的问题或为用户绘制图表,请先在此处检查 SELECT,然后使用 SaveDatabaseQuery 保存它,并粘贴它返回的代码块:它会保持实时,而粘贴的结果会失效。
参数¶
| 参数 | 类型 | 是否必需 | 说明 |
|---|---|---|---|
sql |
string | 是 | 要运行的语句,作为一个字符串。使用 DescribeDatabase 报告的表名和列名,若名称含空格则加引号。 |
databaseId |
string | 否 | 该语句所指数据库的 ID,来自 ListDatabases 或 DescribeDatabase。只要知道就请传入:当另一个数据库有同名表时,此数据库的表优先。其他数据库的表仍可用于 JOIN。 |
baseVersions |
ToolTableVersion[] | 否 | 可选版本,来自之前 QueryDatabase 读取操作。如果列出的某个表在写入时已被更改,则拒绝此次写入。只读依赖不受保护;如果是读取或有意的盲编辑,请省略。 |
display |
"table" | "scalar" | "bar" | "line" | "area" | "scatter" | "pie" |
否 | 首选的原生结果展示方式。对于明确的图表请求,请选择 bar、line、area、scatter 或 pie,并返回一个标签列加数值列。如果数据无法支持该展示方式,应用将回退到表格。 |
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 macro3/macro