首页 > 解决方案 > 在上次数据加载查询中出现验证错误时出错

问题描述

我正在使用外部阶段将数据加载到雪花中。此操作在存储过程中执行,该过程是从雪花任务中调用的。该过程使用 COPY INTO 查询将数据加载到表中,然后检查验证错误。为了得到验证错误,我使用 _last 作为 job_id。

用于将数据复制/加载到雪花表中的查询

COPY INTO conference_created_tmp FROM @conference_created_src/year=2021/month=04/day=15/hour=01/ ON_ERROR = 'SKIP_FILE'

用于获取验证错误的查询:

SELECT FILE as fileName, ERROR as error
FROM table(validate(conference_created_tmp, job_id => '_last')

错误信息:

SQL 编译错误:表函数的参数无效 [我们找不到此会话期间发生的此表的副本]。表函数参数必须是常量。

如果我直接在 Snowflake 工作表中将副本运行到命令和验证查询中,它就可以工作!!!。但是当从过程中调用它时会出错。

程序代码:

CREATE OR REPLACE PROCEDURE TEST_ERROR_LOG()
    RETURNS STRING NOT NULL
    LANGUAGE JAVASCRIPT
AS
$$
    //Copying data from external stage to snowflake table
    const COPY_QUERY = `COPY INTO conference_created_tmp
                            FROM @conference_created_src/year=2021/month=04/day=15/hour=01/
                            ON_ERROR = 'SKIP_FILE'`;

    const LOAD_ERROR_INSERT_QUERY = `INSERT INTO error_log(eventTime, fileName, error)
                                                SELECT '%eventTime%', FILE as fileName, ERROR as error
                                                FROM table(validate(conference_created_tmp, job_id => '_last'))`;

    function log_load_error() {
        let params = {
            "%eventTime%": Date.now()
        };
        let insertQuery = LOAD_ERROR_INSERT_QUERY.replace(/%\w+%/g, function (all) {
            return params[all] || all;
        });
        try {
            snowflake.execute({sqlText: insertQuery});
        } catch (err) {
            throw err;
        }
    }

    function loadDataFromStageToTable() {
        try {
            let resultSet = snowflake.execute({sqlText: COPY_QUERY});
            resultSet.next();
        } catch (err) {
            throw err;
        }
    }

    try {
        loadDataFromStageToTable();
        log_load_error();
    } catch (err) {
        throw err;
    }

    return true;
$$

标签: snowflake-cloud-data-platform

解决方案


没有实际的存储过程代码很难确定,但我猜你想参数化表名:

SELECT FILE as fileName, ERROR as error
FROM table(validate(IDENTIFIER(:bind_variable), job_id => '_last');

如果是,那么您需要用IDENFITIER包装它。

将变量绑定为标识符

IDENTIFIER( { string_literal | session_variable | bind_variable } )

文字和变量(会话或绑定)可用于任何可以通过名称(查询、DML、DDL 等)标识对象的地方。


推荐阅读