如何在 Netezza nzsql 中使用会话变量?
How do I use session variables in Netezza nzsql?
如何在 Netezza nzsql
中创建和使用会话变量?
如何将会话变量用作字符串的一部分?
- 我可以将会话变量与字符串连接起来吗?
- 我可以在字符串中嵌入会话变量吗?
如何将它们用作 table 名称或列名称的一部分?
基本变量用法
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'
标识符中的变量
有时您需要将变量用作标识符的一部分(即列或 table 名称)。
考虑以下示例 table 和变量:
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
在这个例子中,你想 select bar_column
使用你的变量 :foo
(其中包含 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
)。
字符串化
有时您需要将变量的内容用作字符串。
考虑以下示例 table 和变量:
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)
如何在 Netezza
nzsql
中创建和使用会话变量?如何将会话变量用作字符串的一部分?
- 我可以将会话变量与字符串连接起来吗?
- 我可以在字符串中嵌入会话变量吗?
如何将它们用作 table 名称或列名称的一部分?
基本变量用法
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'
标识符中的变量
有时您需要将变量用作标识符的一部分(即列或 table 名称)。
考虑以下示例 table 和变量:
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
在这个例子中,你想 select bar_column
使用你的变量 :foo
(其中包含 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
)。
字符串化
有时您需要将变量的内容用作字符串。
考虑以下示例 table 和变量:
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)