You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将每日Parquet数据合并到Synapse外部表失败,请求排查

问题描述

我每天从数据源提取数据并存储为Parquet格式,已经在Synapse中创建了外部表,想要把每日新提取的数据更新到这个外部表。我通过Notebook创建临时表插入新数据,再尝试合并到原有数据,但操作没成功,相关SQL代码如下:

CREATE TABLE #TempTable
(
    DATE DATE,
    SMD INT,
    ERK VARCHAR(50), 
    LK DATETIME,
    LDATE DATE,
    LG DATETIME,
    K DATETIME,
    G DATETIME,
    IZAR INT,
    BSL INT,
    PERS INT,
    WORK_TIME_HOURS DECIMAL(10, 2)
);

BULK INSERT #TempTable
FROM 'frr/ff_test/*.parquet'
WITH (
    DATA_SOURCE = 'PersData',
    FILE_FORMAT = 'ParquetFF'
);

MERGE INTO [Gf].[Gon_test] AS target
USING TempTable AS source
ON target.smand = source.smand 
WHEN MATCHED THEN
    UPDATE SET
        target.DATE = source.DATE,
        target.LK = source.LK,
        target.LD = source.LD,
        target.LG = source.LG,
        target.K = source.K,
        target.G = source.G,
        target.IZAR = source.IZAR,
        target.BSL = source.SBSL,
        target.PERS = source.SPERS,
        target.WORK_TIME_HOURS = source.WORK_TIME_HOURS
WHEN NOT MATCHED THEN
    INSERT (
        DATE, 
        SMAND,
        ERK,
        LK,
        LD,
        LG,
        KN,
        G,
        IZR,
        BSL,
        PERS,
        WORK_TIME
    )
    VALUES (
        source.DATE, 
        source.AND,
        source.ERK,
        source.LK,
        source.LD,
        source.LG,
        source.K,
        source.G,
        source.IZAR,
        source.BSL,
        source.PERS,
        source.WORK_TIME
    );

DROP TABLE #TempTable;

问题排查与修正建议

代码里存在几个明显错误,加上Synapse外部表本身的操作限制,导致MERGE失败,具体如下:

1. 临时表引用错误

MERGE语句里写的是TempTable,但实际创建的是带#的临时表#TempTable,引用必须完全一致,否则会提示找不到表。

2. 字段名大量不匹配

从代码能看到多处字段对应错误:

  • 临时表定义的是SMD,但MERGE关联条件用的是smand/source.smand,两边字段名对不上
  • UPDATE里target.LD = source.LD,但临时表里只有LDATE没有LD;target.BSL = source.SBSL,临时表里是BSL不是SBSL;target.PERS = source.SPERS,临时表里是PERS而非SPERS
  • INSERT里SMAND对应source.AND,临时表里根本没有AND字段,应该是SMD;KN对应source.K、IZR对应source.IZAR、WORK_TIME对应source.WORK_TIME这些都和临时表字段不匹配

3. Synapse外部表的MERGE限制

基于Parquet的外部表通常不支持MERGE操作(尤其是UPDATE),因为外部表本质是存储文件的映射,无法直接更新文件内容。替代方案:

  • 先把外部表数据导入Synapse内部表,对内部表执行MERGE后,再按需导回外部存储
  • 如果业务允许,采用「追加+定期去重」:先把新数据追加到外部表,再通过CTAS创建去重后的新外部表替换原有表

4. Parquet数据读取方式问题

Synapse中BULK INSERT对Parquet格式的支持有限,更可靠的方式是用OPENROWSET读取Parquet数据到临时表。

修正后的示例代码

-- 创建临时表
CREATE TABLE #TempTable
(
    DATE DATE,
    SMD INT,
    ERK VARCHAR(50), 
    LK DATETIME,
    LDATE DATE,
    LG DATETIME,
    K DATETIME,
    G DATETIME,
    IZAR INT,
    BSL INT,
    PERS INT,
    WORK_TIME_HOURS DECIMAL(10, 2)
);

-- 改用OPENROWSET读取Parquet数据到临时表
INSERT INTO #TempTable
SELECT *
FROM OPENROWSET(
    BULK 'frr/ff_test/*.parquet',
    DATA_SOURCE = 'PersData',
    FORMAT = 'PARQUET'
) AS [result];

-- 注意:如果Gon_test是外部表,MERGE不生效,此处假设已转为内部表
MERGE INTO [Gf].[Gon_test] AS target
USING #TempTable AS source
ON target.SMAND = source.SMD  -- 需确认两边关联字段的实际对应关系,此处为示例
WHEN MATCHED THEN
    UPDATE SET
        target.DATE = source.DATE,
        target.LK = source.LK,
        target.LD = source.LDATE,
        target.LG = source.LG,
        target.KN = source.K,
        target.G = source.G,
        target.IZR = source.IZAR,
        target.BSL = source.BSL,
        target.PERS = source.PERS,
        target.WORK_TIME = source.WORK_TIME_HOURS
WHEN NOT MATCHED THEN
    INSERT (
        DATE, 
        SMAND,
        ERK,
        LK,
        LD,
        LG,
        KN,
        G,
        IZR,
        BSL,
        PERS,
        WORK_TIME
    )
    VALUES (
        source.DATE, 
        source.SMD,
        source.ERK,
        source.LK,
        source.LDATE,
        source.LG,
        source.K,
        source.G,
        source.IZAR,
        source.BSL,
        source.PERS,
        source.WORK_TIME_HOURS
    );

DROP TABLE #TempTable;

内容的提问来源于stack exchange,提问作者Mr_Unchained

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 19:40:59