为什么在“ @”或附近出现语法错误

时间:2018-09-11 11:52:25

标签: postgresql quoted-identifier

当试图连接两个表并更新其中一个表时,我在这里从此函数收到意外错误:

CREATE OR REPLACE FUNCTION tsi.update_data(_creation_time int)
RETURNS VOID
AS $$
BEGIN
    EXECUTE format($sql$
        UPDATE tsi.forecasts_%s a SET
        a."incidents @ 01:00" = b.n_incid,
        a."road @ 01:00" = b.n_roads
        FROM tgi_tmp b WHERE a.link_ix = b.link_id;
  $sql$,_creation_time);
END $$ LANGUAGE plpgsql;

它给了我这个错误信息:

syntax error at or near "@"
cidents @ 01:00" = n_incid,
        ^

有人知道为什么我会收到此错误吗?这些表确实包含提到的列,所以这不是问题。 Postgres是否很难处理Execute格式的字符串列?

Postgres版本:10.5 简化的表格结构:

CREATE TABLE tsi.forecasts_%s (
    link_ix int PRIMARY KEY,
    "slipincidents @ 00:00" SMALLINT NOT NULL,
    "roadcoverage @ 00:00" SMALLINT NOT NULL,
);

和tgi_tmp:

CREATE TEMPORARY TABLE tgi_tmp (
    link_id TEXT,
    n_road SMALLINT,
    n_incid SMALLINT
    CONSTRAINT tgi_tmp_pkey PRIMARY KEY (link_id)
);

3 个答案:

答案 0 :(得分:3)

怪异的@抱怨对我没有帮助。但是,错误的是为集合中要分配的列指定表(别名)。您只应指定列名称。

CREATE OR REPLACE FUNCTION tsi.update_data(_creation_time int)
RETURNS VOID
AS $$
BEGIN
    EXECUTE format($sql$
        UPDATE tsi.forecasts_%s a SET
          "incidents @ 01:00" = b.n_incid,
          "road @ 01:00" = b.n_roads
        FROM tgi_tmp b WHERE a.link_ix = b.link_id;
  $sql$,_creation_time);
END $$ LANGUAGE plpgsql;

答案 1 :(得分:1)

尝试调试您的功能时,我一次又一次收到以下错误消息:

ERROR:  operator does not exist: integer = text
ERROR:  column b.n_roads does not exist
ERROR:  column "a" of relation "tsi_forecasts_1" does not exist
ERROR:  column "incidents @ 01:00" of relation "tsi_forecasts_1" does not exist

修复先前的错误后的每个结果。
我到达了这个工作版本:

CREATE OR REPLACE FUNCTION tsi_update_data(_creation_time int)
  RETURNS VOID AS
$func$
BEGIN
    EXECUTE format($sql$
       UPDATE tsi_forecasts_%s a
       SET    "slipincidents @ 00:00" = b.n_incid  -- don't table-qualify target cols
            , "roadcoverage @ 00:00"  = b.n_road   -- col names in q don't match
       FROM   tgi_tmp b
       WHERE  a.link_ix = b.link_id::int; -- your db design forces a cast
  $sql$, _creation_time);
END
$func$  LANGUAGE plpgsql;

但是我无法重现您的错误:

syntax error at or near "@"
cidents @ 01:00" = n_incid,
        ^

必须由问题中不是 的东西来调用,例如外部双引号或未命名的客户端程序中字符的特殊含义。

除此之外,重新考虑您的命名约定和数据库设计可能是值得的。使用合法的,小写的,未加引号的标识符和匹配的数据类型(link_ixint,而link_ixtext)。

答案 2 :(得分:0)

当我不指定偏移量时,由于某种原因,可以工作。像这样:

   Country Column1 Product     Week    Val
0       UK      S1       A  2019-36   10.0
1       UK      S1       A  2019-37   20.0
2       UK      S1       A  2019-38   30.0
3       UK      S1       B  2019-36   35.0
4       UK      S1       B  2019-37   40.0
5       UK      S1       B  2019-38   45.0
6       DE      S1       A  2019-39  100.0
7       DE      S1       A  2019-40  100.0
8       DE      S1       A  2019-41  100.0
9       DE      S1       B  2019-36   10.0
10      DE      S1       B  2019-37   15.0
11      DE      S1       B  2019-38   10.0