【问题标题】:How do I use session variables in Netezza nzsql?如何在 Netezza nzsql 中使用会话变量?
【发布时间】:2015-12-14 15:20:30
【问题描述】:
  1. 如何在 Netezza nzsql 中创建和使用会话变量?

  2. 如何将会话变量用作字符串的一部分?

    • 能否将会话变量与字符串连接起来?
    • 我可以在字符串中嵌入会话变量吗?
  3. 如何将它们用作表名或列名的一部分?

【问题讨论】:

    标签: netezza nzsql


    【解决方案1】:

    基本变量用法

    Netezza nzsql 中会话变量的 documentation 有点缺乏。
    它指出,要在脚本中或在nzsql 提示符处设置变量,请使用\set

    \set var value
    

    您也可以在命令行中指定变量。这对于将变量传递到脚本中很有用。

    nzsql -v var=value
    

    在您的会话或脚本中,您可以通过 :var 访问该变量的值

    DB.TST(LLAMA)=> \set foo example_table
    
    DB.TST(LLAMA)=> \d :foo
                           Table "EXAMPLE_TABLE"
       Attribute    |         Type          | Modifier | Default Value
    ----------------+-----------------------+----------+---------------
     EXAMPLE_COLUMN | CHARACTER VARYING(16) |          |
    Distributed on hash: "EXAMPLE_COLUMN"
    
    DB.TST(LLAMA)=> SELECT * FROM :foo;
     EXAMPLE_COLUMN
    ----------------
     Hello World
    

    高级变量用法

    \set 命令还具有未记录的功能,可增加更大的灵活性。
    实际上,\set 接受传递给它的 所有 值并将它们连接在一起。

    DB.TST(LLAMA)=> \set foo bar baz qux
    DB.TST(LLAMA)=> \echo :foo
    barbazqux
    

    该命令还支持以类似于 shell 脚本的方式引用,允许您在变量中包含空格。
    不过要小心,带引号和不带引号的字符串仍然会相互连接。

    DB.TST(LLAMA)=> \set foo 'bar baz qux'
    DB.TST(LLAMA)=> \echo :foo
    bar baz qux
    
    DB.TST(LLAMA)=> \set foo 'bar baz' qux
    DB.TST(LLAMA)=> \echo :foo
    bar bazqux
    

    双引号也可以保留空白。但是,双引号仍然会保留在变量中。

    DB.TST(LLAMA)=> \set foo "bar baz qux"
    DB.TST(LLAMA)=> \echo :foo
    "bar baz qux"
    
    DB.TST(LLAMA)=> \set foo "bar baz" qux
    DB.TST(LLAMA)=> \echo :foo
    "bar baz"qux
    

    当然,不同类型的引用可以混合使用:

    DB.TST(LLAMA)=> \set foo "Hello World" 'Goodbye World'
    DB.TST(LLAMA)=> \echo :foo
    "Hello World"Goodbye World
    

    单引号

    \set 命令中正确嵌入单引号可能很困难。
    顺便说一句,由于双引号总是被保留,它们很少出现问题。

    未加引号的单词中的单引号将被保留。

    DB.TST(LLAMA)=> \set foo bar'baz'qux
    DB.TST(LLAMA)=> \echo :foo
    bar'baz'qux
    

    引用的单词中的单引号可能会导致问题。

    DB.TST(LLAMA)=> \set foo 'bar'baz'qux'
    DB.TST(LLAMA)=> \echo :foo
    barbaz'qux'
    

    双引号内的单引号被保留。

    DB.TST(LLAMA)=> \set foo "This'll work fine!"
    DB.TST(LLAMA)=> \echo :foo
    "This'll work fine!"
    

    单独的单引号需要被引用转义。

    DB.TST(LLAMA)=> \set foo '
    parse error at end of line
    
    DB.TST(LLAMA)=> \set foo \'
    Invalid command \'. Try \? for help.
    
    DB.TST(LLAMA)=> \set foo '\''
    DB.TST(LLAMA)=> \echo :foo
    '
    

    如有疑问:单引号该短语并用反斜杠转义所有剩余的单引号。

    DB.TST(LLAMA)=> \set foo '\'bar\'baz\'qux\''
    DB.TST(LLAMA)=> \echo :foo
    'bar'baz'qux'
    

    标识符中的变量

    有时您需要使用变量作为标识符的一部分(即列名或表名)。
    考虑以下示例表和变量:

    DB.TST(LLAMA)=> SELECT * FROM example_table;
     BAR_COLUMN  | QUX_COLUMN
    -------------+-------------
     This is bar | This is qux
    (1 row)
    
    DB.TST(LLAMA)=> \set foo bar
    

    在此示例中,您希望使用变量 :foo(其中包含 bar)和文本 _column 来选择 bar_column
    以下将不起作用:

    DB.TST(LLAMA)=> SELECT :foo_column FROM example_table;
    foo_column:
    ERROR:  'SELECT  FROM example_table;'
    error            ^ found "FROM" (at char 9) expecting an identifier found a keyword
    

    上述示例失败,因为nzsql 无法确定变量名称的结束位置 (:foo) 和剩余列 (_column) 名称的开始位置。
    要解决此问题,您需要通过连接 :foo 的值和列名的其余部分来使用 \set 创建一个新变量:

    DB.TST(LLAMA)=> \set fixed_foo :foo _column
    DB.TST(LLAMA)=> \echo :fixed_foo
    bar_column
    
    DB.TST(LLAMA)=> SELECT :fixed_foo FROM example_table;
     BAR_COLUMN
    -------------
     This is bar
    (1 row)
    

    如果变量包含您希望使用的标识符的end,则不需要创建中间变量。
    在这种特定情况下,nzsql 将正确扩展变量(例如 column_:foo -> column_bar)。


    字符串化

    有时您需要将变量的内容用作字符串。
    考虑以下示例表和变量:

    DB.TST(LLAMA)=> SELECT * FROM example_table;
     EXAMPLE_COLUMN
    ----------------
     Hello World
     Whatever
     Something
    (3 rows)
    
    DB.TST(LLAMA)=> \set foo Something
    

    如果您只是在语句中引用变量,那么它将被视为文字。

    DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column = 'Something';
     EXAMPLE_COLUMN
    ----------------
     Something
    (1 row)
    
    DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column = ':foo';
     EXAMPLE_COLUMN
    ----------------
    (0 rows)
    
    DB.TST(LLAMA)=> \p
    SELECT * FROM example_table WHERE example_column = ':foo';
    

    如果变量不加引号,那么它将用作标识符。

    DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column = :foo;
    ERROR:  Attribute 'SOMETHING' not found
    

    要解决此问题,您需要使用 \set 和您的引用知识来创建可用变量。
    您可以通过组合一个单引号(正确转义!)、变量的内容和另一个单引号来创建一个新变量来完成此操作。

    DB.TST(LLAMA)=> \set quoted_foo '\'' :foo '\''
    DB.TST(LLAMA)=> \echo :quoted_foo
    'Something'
    
    DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column = :quoted_foo;
     EXAMPLE_COLUMN
    ----------------
     Something
    (1 row)
    

    如果您的变量需要在字符串中使用,将变量字符串化并使用常规字符串连接可能会更容易。

    DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column LIKE '%ello%';
     EXAMPLE_COLUMN
    ----------------
     Hello World
    (1 row)
    
    DB.TST(LLAMA)=> \set foo ello
    DB.TST(LLAMA)=> \set quoted_foo '\'' :foo '\''
    DB.TST(LLAMA)=> \echo :quoted_foo
    'ello'
    
    DB.TST(LLAMA)=> SELECT * FROM example_table WHERE example_column LIKE '%' || :quoted_foo || '%';
     EXAMPLE_COLUMN
    ----------------
     Hello World
    (1 row)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2017-04-06
      • 2013-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多