使用Perl DBI从Snowflake获取存储过程时如何获取含本地声明的完整内容
Perl调用Snowflake GET_DDL获取存储过程时丢失代码内容的解决办法
我们在Snowflake里有大量存储过程,在工作表中执行GET_DDL能获取完整的存储过程代码,但用Perl的DBI执行相同查询时,通过fetchrow方法只能拿到存储过程的头部,本地函数声明及后续代码全部缺失。相关代码与返回结果对比如下:
Perl代码片段
while (my @row = $sth->fetchrow_array) { print "row is @row\n"; }
Snowflake返回的完整内容
CREATE OR REPLACE PROCEDURE "SP_LOAD_AMT"("MASTER_ID" FLOAT, "TARGETING_PROFILES" VARCHAR(16777216), "DELIMITER" VARCHAR(1), "DEBUG" BOOLEAN) RETURNS VARIANT LANGUAGE JAVASCRIPT EXECUTE AS OWNER AS ' // Local function declarations -------------------------------------------------------- function createLogger(masterId, processType, functionName, debug) { var loggingContext, log; function LoggingContext(masterId, processType, functionName, debug) { var stmt, resultSet; if(Number.isInteger(masterId)) { stmt = snowflake.createStatement({ sqlText: `SELECT CNTXT:CNTRL_STEP:MASTER_ID AS MASTER_ID, CNTXT:CNTRL_STEP:BATCH_ID AS BATCH_ID FROM (SELECT METAPROC.GET_RUNTIME_CONTEXT(?) AS CNTXT);`, binds: [masterId] });
Perl脚本返回的内容
CREATE OR REPLACE PROCEDURE "SP_LOAD_AMT"("MASTER_ID" FLOAT, "TARGETING_PROFILES" VARCHAR(16777216), "DELIMITER" VARCHAR(1), "DEBUG" BOOLEAN) RETURNS VARIANT LANGUAGE JAVASCRIPT EXECUTE AS OWNER AS
解决办法
- 配置DBI连接的长字符串参数
Perl DBI默认的长文本读取长度不足以容纳完整的存储过程代码,建立连接时需设置足够大的LongReadLen值,并禁用截断:
my $dbh = DBI->connect( "dbi:Snowflake:account=$account;db=$db;schema=$schema;", $user, $password, { LongReadLen => 10 * 1024 * 1024, # 设置为10MB,可根据实际存储过程大小调整 LongTruncOk => 0 # 禁止截断长文本内容 } );
- 更换结果获取方法
fetchrow_array在处理超长文本时可能存在截断问题,改用fetchrow_arrayref直接读取字段原始内容:
while (my $row_ref = $sth->fetchrow_arrayref) { print $row_ref->[0], "\n"; # 直接输出第一个字段的完整内容 }
- 确认GET_DDL的调用格式
调用GET_DDL时需精准指定存储过程的完整签名(包括参数类型),避免返回不完整结果:
SELECT GET_DDL('PROCEDURE', 'SP_LOAD_AMT(FLOAT, VARCHAR(16777216), VARCHAR(1), BOOLEAN)');
内容的提问来源于stack exchange,提问作者James Finnegan
相关产品推荐
相关产品推荐

