如何在psql脚本中使用变量

时间:2013-09-07 12:17:50

标签: postgresql psql

这是我的psql脚本,它不起作用:

\set path '''c:\\server\\data\\''';
COPY paymentMethods (name,regexString) FROM :path+'paymentMethods.csv' WITH (FORMAT csv, HEADER true);
COPY priceLevels (name) FROM :path+'priceLevels.csv' WITH (FORMAT csv, HEADER false);

psql抱怨+

的语法错误

如何更改它以使其有效,同时只提供一次实际路径字符串?

2 个答案:

答案 0 :(得分:7)

首先,您尝试使用+运算符连接两个字符串,但连接的SQL运算符为||,使用该信息,您可以认为预期的结果是(将无效):

\set path '''c:\\server\\data\\'''
COPY paymentMethods (name,regexString) FROM :path || 'paymentMethods.csv' WITH (FORMAT csv, HEADER true);
COPY priceLevels (name) FROM :path || 'priceLevels.csv' WITH (FORMAT csv, HEADER false);

但是! COPY命令期望路径的文字字符串,而不是表达式,所以你真的应该给出路径。请注意,它适用于SELECTINSERTUPDATE等命令。

使用该信息,您只能使用psql变量,如Pavel指出的那样,并将字符串连接成psql的变量。一个好的解决方案是使用psql的{​​{1}}语法,将变量作为字符串插入SQL表达式中:

:'var'

将生成(将发送到PostgreSQL的服务器):

\set path 'c:\\server\\data\\'
\set paymentMethodsPath :path 'paymentMethods.csv'
\set priceLevelsPath :path 'priceLevels.csv'
COPY paymentMethods (name,regexString) FROM :'paymentMethodsPath' WITH (FORMAT csv, HEADER true);
COPY priceLevels (name) FROM :'priceLevels' WITH (FORMAT csv, HEADER false);

COPY paymentMethods (name,regexString) FROM E'c:\\server\\data\\paymentMethods.csv' WITH (FORMAT csv, HEADER true); COPY priceLevels (name) FROM E'c:\\server\\data\\priceLevels.csv' WITH (FORMAT csv, HEADER false); 语法不适用于所有:'var'版本(我现在不记得引入了哪一个版本),但对于旧版本,您可以轻松使用美元引用:

psql

或转入单引号:

\set path 'c:\\server\\data\\'
\set paymentMethodsPath :path 'paymentMethods.csv'
\set priceLevelsPath :path 'priceLevels.csv'
COPY paymentMethods (name,regexString) FROM $$:paymentMethodsPath$$ WITH (FORMAT csv, HEADER true);
COPY priceLevels (name) FROM $$:priceLevels$$ WITH (FORMAT csv, HEADER false);

就是这样。

答案 1 :(得分:3)

psql没有运算符。你只能放置一个变量(某处)

postgres=# \set var1 AAAA
postgres=# \set var2 BBBB
postgres=# \echo :var1:var2
AAAABBBB
postgres=# \echo :var1 :var2
AAAA BBBB
postgres-# \echo :var1'\\':var2
AAAA\BBBB

postgres=# \set mypath '/tmp'
postgres=# \set mypathx :mypath/x.csv
postgres=# \echo :mypathx
/tmp/x.csv
postgres=# copy fo from :'mypathx';
COPY 1
postgres=# \set mypathy :mypath/y.csv
postgres=# copy fo from :'mypathy';
COPY 1