Postgresql 为什么在“或”附近出现语法错误@&引用;

Postgresql 为什么在“或”附近出现语法错误@&引用;,postgresql,quoted-identifier,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:0

当尝试连接两个表并更新其中一个表时,我从该函数接收到一个意外错误:

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很难处理执行格式的字符串列吗

博士后版本: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)
);

奇怪的是,it对@的抱怨并不适合我。但是,错误之处在于为集合中要指定的列指定表(别名)。您应该只指定列名

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;

奇怪的是,it对@的抱怨并不适合我。但是,错误之处在于为集合中要指定的列指定表(别名)。您应该只指定列名

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;

当我没有指定偏移量时,由于某种原因,它会起作用。像这样:

 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;

尝试调试您的函数时,我收到以下错误消息,一条接一条:

在修复之前的错误后,每个错误都会发生。
我得出了这个工作版本:

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;
但我无法重现你的错误:

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


除此之外,重新考虑您的命名约定和db设计可能会有好处。使用合法、小写、不带引号的标识符和匹配的数据类型(
link_ix
int
,而
link_ix
text
)。

尝试调试函数时,我一个接一个地收到以下错误消息:

在修复之前的错误后,每个错误都会发生。
我得出了这个工作版本:

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;
但我无法重现你的错误:

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


除此之外,重新考虑您的命名约定和db设计可能会有好处。使用合法的、小写的、不带引号的标识符和匹配的数据类型(
link_ix
int
,而
link_ix
text
)。

你到底为什么要使用这样的列名?@a_horse__,没有名称可以节省空间,也没有时间重新格式化为更好的列名structure@Jesper:很明显,你这样是在浪费时间。非常容易出错。考虑法律,小写,无引号的名字无处不在。这样可以节省时间。至于您的问题,缺少最低要求:表定义,Postgres版本。@ErwinBrandstetter添加了要求。我以前曾讨论过这种结构:你到底为什么要使用这样的列名?@a_horse_和_no_名称节省了空间,也没有时间重新格式化为更好的列名structure@Jesper:很明显,你这样是在浪费时间。非常容易出错。考虑法律,小写,无引号的名字无处不在。这样可以节省时间。至于您的问题,缺少最低要求:表定义,Postgres版本。@ErwinBrandstetter添加了要求。之前我们已经讨论过这个结构:可能是一些未知的配置导致了问题。幸运的是,db设计不是我设计的,目前正在进行重组,但需要一个快速补丁:)可能确实有一些未知的配置导致了问题。幸运的是,db设计不是我做的,目前正在进行重组,但需要快速修补:)