Почему я получаю синтаксическую ошибку в или около "@" - PullRequest
0 голосов
/ 11 сентября 2018

При попытке объединить две таблицы и обновить одну из них я получаю неожиданную ошибку от этой функции прямо здесь:

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 голосов
/ 11 сентября 2018

По какой-то причине работает, когда я не указываю смещение.Как это:

 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;
0 голосов
/ 11 сентября 2018

Пытаясь отладить вашу функцию, я получаю сообщения об ошибках, одно за другим:

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_ix равно int, а link_ix равно text).

0 голосов
/ 11 сентября 2018

Странно, жалобы на @ не делают этого для меня.Однако, что неправильно, так это указание таблицы (псевдонима) для столбцов, которые вы назначаете в наборе.Вы должны только указать имена столбцов.

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