跳转至

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