【问题标题】:Declare a variable in RedShift在 RedShift 中声明一个变量
【发布时间】:2015-08-29 14:11:45
【问题描述】:

SQL Server 可以声明一个变量,然后在查询中调用该变量,如下所示:

DECLARE @StartDate date;
SET @StartDate = '2015-01-01';

SELECT *
FROM Orders
WHERE OrderDate >= @StartDate;

此功能在 Amazon 的 RedShift 中有效吗?从documentation 看来,DECLARE 仅用于游标。 SET 看起来是我正在寻找的功能,但是当我尝试使用它时,出现错误。

set session StartDate = '2015-01-01';
 [Error Code: 500310, SQL State: 42704]  [Amazon](500310) Invalid operation: unrecognized configuration parameter "startdate";

是否可以在RedShift 中做到这一点?

【问题讨论】:

    标签: amazon-redshift


    【解决方案1】:

    Slavik Meltser 的回答很棒。作为此主题的变体,您还可以使用 WITH 构造:

    WITH tmp_variables AS (
    SELECT 
       '2015-01-01'::DATE AS StartDate, 
       'some string'      AS some_value,
       5556::BIGINT       AS some_id
    )
    
    SELECT *
    FROM Orders
    WHERE OrderDate >= (SELECT StartDate FROM tmp_variables);
    

    【讨论】:

    • 这在我的用例中更好:一个自定义 ETLM 系统,它不会在创建 tempe 表后的第二条语句explain
    • 你是对的,它也会起作用。但是,这只是美学方法,因为 Redshift 中的 WITH 语句在查询运行期间无论如何都会转换为 TEMP TABLE
    【解决方案2】:

    实际上,您可以使用临时表模拟变量,创建一个,设置数据,一切顺利。

    类似这样的:

    CREATE TEMP TABLE tmp_variables AS SELECT 
       '2015-01-01'::DATE AS StartDate, 
       'some string'      AS some_value,
       5556::BIGINT       AS some_id;
    
    SELECT *
    FROM Orders
    WHERE OrderDate >= (SELECT StartDate FROM tmp_variables);
    

    事务执行后临时表将被删除。
    临时表是每个会话绑定的(连接),因此不能跨会话共享。

    【讨论】:

      【解决方案3】:

      不,Amazon Redshift 没有变量的概念。 Redshift 将自己呈现为 PostgreSQL,但经过高度修改。

      在 2014 年 AWS re:Invent 大会上提到了用户定义函数,它可能会满足您的一些需求。

      2016 年更新: Scalar User Defined Functions 可以执行计算,但不能用作存储变量。

      【讨论】:

        【解决方案4】:

        请注意,如果您使用 psql 客户端进行查询,psql 变量仍然可以与 Redshift 一样使用:

        $ psql --host=my_cluster_name.clusterid.us-east-1.redshift.amazonaws.com \
             --dbname=your_db   --port=5432 --username=your_login -v dt_format=DD-MM-YYYY
        
        # select current_date;     
            date    
        ------------
         2015-06-15
        (1 row)
        
        # select to_char(current_date,:'dt_format');
          to_char   
        ------------
         15-06-2015
        (1 row)
        
        # \set
        AUTOCOMMIT = 'on'
        ...
        dt_format = 'DD-MM-YYYY'
        ...
        # \set dt_format 'MM/DD/YYYY'
        # select to_char(current_date,:'dt_format');
          to_char   
        ------------
         06/15/2015
        (1 row)
        

        【讨论】:

          【解决方案5】:

          您现在可以使用用户定义的函数 (UDF) 来做您想做的事:

          CREATE FUNCTION my_const()
              RETURNS CSTRING IMMUTABLE AS 
              $$ return 'my_string_constant' $$ language plpythonu;
          

          不幸的是,这确实需要您的 redshift 数据库上的certain access permissions

          【讨论】:

            猜你喜欢
            • 2010-10-30
            • 2021-04-13
            • 2020-06-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-22
            相关资源
            最近更新 更多