简体   繁体   English

从 Snowflake SQL 程序返回表格数据

[英]Returning tabular data from Snowflake SQL procedure

I'm trying to write a stored procedure that will return the results of a complex query:我正在尝试编写一个将返回复杂查询结果的存储过程:

CREATE OR REPLACE PROCEDURE sp_partition_ohlc(symbol VARCHAR(10), 
                                              from_time NUMERIC(20, 0), 
                                              til_time NUMERIC(20, 0),  
                                              step_time NUMERIC(20, 0))
    RETURNS TABLE()
    LANGUAGE SQL
    AS
    $$
    BEGIN
        SELECT 
            :step_time * bucket AS t,
            SUM(T.volume) AS v,
            MAX(T.open) AS o,
            MAX(T.close) AS c,
            MAX(T.highlow) AS h,
            MIN(T.highlow) AS l,
            v * (h + l + c) / 3 AS wv,
            COUNT(*) AS n
        FROM (
            SELECT
                FLOOR(T.sip_timestamp / :step_time) AS bucket,
                cta_calc(T.size, T.conditions, 'VOLUME') AS volume,
                cta_calc(T.price, T.conditions, 'HIGHLOW') AS highlow,
                IFF(ROW_NUMBER() OVER (PARTITION BY bucket ORDER BY T.sip_timestamp) = 1, T.price, NULL) AS open,
                LAST_VALUE(cta_calc(T.price, T.conditions, 'LAST')) 
                    IGNORE NULLS OVER (PARTITION BY bucket ORDER BY T.sip_timestamp) AS close
            FROM trades AS T
            WHERE 
                T.symbol = :symbol AND 
                T.sip_timestamp >= :from_time AND
                T.sip_timestamp < :til_time) AS T
        GROUP BY bucket
        ORDER BY bucket;
    END
    $$

This compiles properly but, if I try to run it:这编译正确但是,如果我尝试运行它:

CALL sp_partition_ohlc('NTAP', 1640995200000000000, 1672531200000000000, 3600000000000)

I get the following error:我收到以下错误:

092222 (P0000): SQL compilation error: stored procedure is missing a return statement 092222 (P0000): SQL 编译错误:存储过程缺少返回语句

From this, I understand that I should have a RETURN in front of my outer SELECT statement.由此,我明白我应该在我的外部SELECT语句前面有一个RETURN However, when I modify the procedure thus, it fails to compile with this error:但是,当我这样修改程序时,它无法编译并出现以下错误:

Syntax error: unexpected 'SELECT'.语法错误:意外的“SELECT”。 (line 7) syntax error line 4 at position 23 unexpected '*'. (第 7 行)语法错误第 4 行位于 position 23 意外的“*”。 (line 7) (第 7 行)

I'm not sure what this error is telling me as, when I run the query by itself, it returns results.我不确定这个错误告诉我什么,因为当我自己运行查询时,它会返回结果。 I assume I'm doing something wrong in setting up the procedure but I'm not sure what it is from the associated documentation, here .我假设我在设置程序时做错了什么,但我不确定它来自此处的相关文档是什么。 Any help would be appreciated.任何帮助,将不胜感激。

It is not a matter of just putting a return in there:这不仅仅是把回报放在那里的问题:

you more want to follow a pattern like:您更想遵循以下模式:

create or replace procedure get_top_sales()
returns table (sales_date date, quantity number)
language sql
as
declare
  res resultset default (select sales_date, quantity from sales order by quantity desc limit 10);
begin
  return table(res);
end;

here the res is a declared as the result set, which is the SQL to run, so you can access those, and then it is returned as a table via table(res) and the type of the res matches the return type of the function returns table (sales_date date, quantity number) , so for your function you would need to alter this also.这里res被声明为结果集,即要运行的 SQL,因此您可以访问它们,然后通过table(res)作为表返回,并且 res 的类型与 function 的返回类型匹配returns table (sales_date date, quantity number) ,因此对于您的 function 您还需要更改它。

so something like (I have not run):所以像(我没有跑):

CREATE OR REPLACE PROCEDURE sp_partition_ohlc(symbol VARCHAR(10), 
                                              from_time NUMERIC(20, 0), 
                                              til_time NUMERIC(20, 0),  
                                              step_time NUMERIC(20, 0))
    RETURNS TABLE(t int, v float, o float, c float, h float, l float, wv float, n int) /* guessed types */
    LANGUAGE SQL
    AS
    $$
    DECLARE
        res resultset;
    BEGIN
    
        let res := (
            SELECT 
                :step_time * bucket AS t,
                SUM(T.volume) AS v,
                MAX(T.open) AS o,
                MAX(T.close) AS c,
                MAX(T.highlow) AS h,
                MIN(T.highlow) AS l,
                v * (h + l + c) / 3 AS wv,
                COUNT(*) AS n
            FROM (
                SELECT
                    FLOOR(T.sip_timestamp / :step_time) AS bucket,
                    cta_calc(T.size, T.conditions, 'VOLUME') AS volume,
                    cta_calc(T.price, T.conditions, 'HIGHLOW') AS highlow,
                    IFF(ROW_NUMBER() OVER (PARTITION BY bucket ORDER BY T.sip_timestamp) = 1, T.price, NULL) AS open,
                    LAST_VALUE(cta_calc(T.price, T.conditions, 'LAST')) 
                        IGNORE NULLS OVER (PARTITION BY bucket ORDER BY T.sip_timestamp) AS close
                FROM trades AS T
                WHERE 
                    T.symbol = :symbol AND 
                    T.sip_timestamp >= :from_time AND
                    T.sip_timestamp < :til_time) AS T
            GROUP BY bucket
            ORDER BY bucket
        );
        
        return table(res);
    END
    $$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM