3

Here is my psql script, which does not work:

\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 complains about the syntax error at the +

How can I change it so that it works, while having the actual path string mentioned just once?

4

2 回答 2

12

首先,您尝试使用+运算符连接两个字符串,但是用于连接的 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命令需要路径的文字字符串,而不是表达式,因此您确实应该提供路径。请注意,它适用于SELECT, INSERT,UPDATE等命令。

有了这些信息,您只能使用psql变量,正如 Pavel 指出的那样,并将字符串连接到 apsql的变量中。一个好的解决方案是使用psql's:'var'语法,将变量作为字符串插入到 SQL 表达式中:

\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);

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

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);

或转义为单引号:

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

这就对了。

于 2013-09-08T11:31:33.953 回答
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=# 从 :'mypathx' 复制 fo;
副本 1
postgres=# \set mypathy :mypath/y.csv
postgres=# 从 :'mypathy' 复制 fo;
副本 1
于 2013-09-07T12:29:41.930 回答