"TRUNCATE" 处或附近的语法错误 - Aurora Postgres 10.12

Syntax error at or near "TRUNCATE" - Aurora Postgres 10.12

我正在尝试重构查询并删除一组 window 函数,而不是按原样捕获所有记录。当我去粘贴查询来替换我的函数时,pgAdmin 在 'Truncate' 语句附近指示语法错误。我只是无法弄清楚它是什么,并且可能是非常明显的东西,但会欣赏另一组(或许多)眼睛。

我正在使用 Postgres 10.12。

这是我要插入的代码(最后包含 'before' 代码。任何建议将不胜感激。尝试了括号、逗号和半-的所有类型和组合结肠关闭和无能为力...

我要插入的代码

预期结果: 从分段中取出行并插入到目标中。 T运行完成后分期

  WITH ins_agent AS (
     INSERT INTO agents (
        currentagentsnapshot,
        previousagentsnapshot,
        agentarn,
        eventid,
        eventtimestamp,
        eventtype,
        instancearn)
     SELECT 
        agent_stg.currentagentsnapshot::jsonb AS currentagentsnapshot,
        agent_stg.previousagentsnapshot::jsonb AS previousagentsnapshot,
        agent_stg.agentarn::text AS agentarn,
        agent_stg.eventid::text AS eventid,
        agent_stg.eventtimestamp::timestamptz AS eventtimestamp,
        agent_stg.eventtype::text AS eventtype,
        agent_stg.instancearn::text AS instancearn
    FROM agents_staging AS agent_stg
    WHERE agent_stg.agentarn IS NOT NULL)
    TRUNCATE agents_staging;

我正在尝试更改的代码

预期结果:Select 不同的代理并捕获他们的最新快照。将 agent_id 插入另一个 table。考虑更新。

更改原因: 除了作为对数百万条记录的 运行 查询的负担之外,它提供的价值很小,因为它丢弃了所有代理快照,除了它们的最新的,因为不同。不是我们想要的。

WITH ins_agent AS (INSERT INTO agents (currentagentsnapshot,
                                       previousagentsnapshot,
                                       agentarn,
                                       eventid,
                                       eventtimestamp,
                                       eventtype,
                                       instancearn)
    SELECT DISTINCT LAST_VALUE(currentagentsnapshot::jsonb)
                    OVER (PARTITION BY agentarn ORDER BY lat.eventtimestamp DESC ) AS previousagentsnapshot,
                    LAST_VALUE(previousagentsnapshot::jsonb)
                    OVER (PARTITION BY agentarn ORDER BY lat.eventtimestamp DESC ) AS previousagentsnapshot,
                    agentarn,
                    LAST_VALUE(eventid)
                    OVER (PARTITION BY agentarn ORDER BY lat.eventtimestamp DESC)  AS eventid,
                    LAST_VALUE(lat.eventtimestamp)
                    OVER (PARTITION BY agentarn ORDER BY lat.eventtimestamp DESC)  AS eventtimestamp,
                    LAST_VALUE(eventtype)
                    OVER (PARTITION BY agentarn ORDER BY lat.eventtimestamp DESC)  AS eventtype,
                    LAST_VALUE(instancearn)
                    OVER (PARTITION BY agentarn ORDER BY lat.eventtimestamp DESC)  AS instancearn
    FROM agents_staging AS agent
             CROSS JOIN LATERAL (SELECT agent.eventtimestamp::timestamp AS eventtimestamp) AS lat
    WHERE NOT (
            agent.agentarn IS NULL
            OR agent.currentagentsnapshot IS NULL
            OR agent.currentagentsnapshot = '{}')
    ON CONFLICT (agentarn)
        DO NOTHING
    RETURNING agentarn, agent_id)
UPDATE contact_trace_records
SET agent_id=ins_agent.agent_id
FROM ins_agent
WHERE contact_trace_records.agent_id IS NULL
  AND ins_agent.agentarn = contact_trace_records.agent ->> 'ARN';

TRUNCATE agents_staging;

语法错误是无法将 CTE 附加到 TRUNCATE 命令。仅限 INSERTUPDATEDELETESELECT。 (好吧,技术上也是 TABLE,但这只是 SELECT * FROM 的简短语法。)

删除 WITH 子句和 运行 两个单独的命令。

INSERT INTO agents (
    currentagentsnapshot,
    previousagentsnapshot,
    agentarn,
    eventid,
    eventtimestamp,
    eventtype,
    instancearn)
SELECT 
    agent_stg.currentagentsnapshot::jsonb AS currentagentsnapshot,
    agent_stg.previousagentsnapshot::jsonb AS previousagentsnapshot,
    agent_stg.agentarn::text AS agentarn,
    agent_stg.eventid::text AS eventid,
    agent_stg.eventtimestamp::timestamptz AS eventtimestamp,
    agent_stg.eventtype::text AS eventtype,
    agent_stg.instancearn::text AS instancearn
FROM agents_staging AS agent_stg
WHERE agent_stg.agentarn IS NOT NULL;

TRUNCATE agents_staging;

如果你需要防止竞争条件,将整个操作包装在一个事务中并首先在 table 上获取写锁:

BEGIN;
LOCK TABLE agents_staging;
INSERT ...;
TRUNCATE agents_staging;
COMMIT;

旁白:table 外 SELECT 中的别名在 INSERT 命令中 什么都不做 。这些充其量只是文档。但是由于所有列都已经有了最终的名称,所以它实际上只是噪音。

如果源列具有兼容的数据类型(隐式或赋值转换为目标类型,而不是显式转换),您可能不需要 table 限定或显式转换。看起来两个 table 都具有相同的数据类型?然后你可以在很大程度上简化为:

INSERT INTO agents
      (currentagentsnapshot, previousagentsnapshot, agentarn, eventid, eventtimestamp, eventtype, instancearn)
SELECT currentagentsnapshot, previousagentsnapshot, agentarn, eventid, eventtimestamp, eventtype, instancearn
FROM   agents_staging
WHERE  agentarn IS NOT NULL;