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

Why am I getting syntax error at or near "@"

当我尝试加入两个 table 并更新其中一个时,我收到了来自此函数的意外错误:

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,
        ^

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

Postgres 版本:10.5 简化的 table 结构:

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

奇怪的是,关于 @ 的抱怨对我没有帮助。然而,错误的是为您在集合中分配的列指定 table (别名)。您应该只指定列名。

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;

在我未指定偏移量时出于某种原因工作。像这样:

 CREATE OR REPLACE FUNCTION tsi.update_data(_creation_time int)
 RETURNS VOID

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

尝试调试您的函数时,我收到了这些错误消息,一个接一个:

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_ixintlink_ixtext)。