错误:在“$BODY$”处或附近未终止的美元引号字符串

Posted

技术标签:

【中文标题】错误:在“$BODY$”处或附近未终止的美元引号字符串【英文标题】:ERROR: unterminated dollar-quoted string at or near "$BODY$ 【发布时间】:2016-05-30 01:01:04 【问题描述】:

我正在使用sql fiddle...PostgreSQL 9.3:

CREATE TABLE HotelStays
(roomNum INTEGER NOT NULL,
arrDate DATE NOT NULL,
depDate DATE NOT NULL,
guestName CHAR(30) NOT NULL,
PRIMARY KEY (roomNum, arrDate))
;


CREATE OR REPLACE FUNCTION new_customer() RETURNS void AS
$BODY$
DECLARE
    depatureDate DATE;\
BEGIN
    SELECT depDate INTO depatureDate FROM HotelStays WHERE OLD.roomNum = NEW.roomNum;
    IF (depatureDate <= NEW,arrDate)
      INSERT INTO HotelStays (roomNum, arrDate, depDate, guestName)
    VALUES (:NEW.roomNum, :NEW.arrDate, :NEW.depDate, :NEW.guestName);
    END IF;
    RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
CREATE TRIGGER;

INSERT INTO HotelStays(roomNum, arrDate, depDate, guestName)
VALUES 
(123, to_date('20160202', 'YYYYMMDD'), to_date('20160206','YYYYMMDD'), 'A');

我正在尝试解决的问题:即使在现有客人退房之前,也可以为房间号输入新条目(针对新客人)。 我正在尝试使用触发器来解决这个问题。请帮帮我。提前致谢。

【问题讨论】:

是 depatureDate DATE 行的斜线;\? 还是 LANGUAGE 行...尝试删除 LANGUAGE 行 【参考方案1】:

正如作者所说,他使用了 SQL Fiddle。我在 db-fiddle.com 上遇到了同样的问题,并通过将 $$$BODY$ 替换为单引号 ' 来解决它(并在其间的其他地方加倍单引号。

例如,db-fiddle

CREATE OR REPLACE FUNCTION update_datem()
  RETURNS trigger AS
'
BEGIN
 NEW.dateM = DATE_TRUNC(''MONTH'', NEW.date);
 RETURN NEW;
END;
'
LANGUAGE plpgsql;

【讨论】:

感谢您的提示。在 Liquibase 迁移脚本中面临同样的问题。用单引号替换“$$”就可以了!! 我在 IntelliJ 中使用 $$ 运行我的原始脚本,这很好,但 Liquibase 迁移失败。这解决了问题。谢谢!【参考方案2】:

您的代码中有几个错误。首先是depatureDate DATE;\ 中的反斜杠。您还缺少THENIF 子句,new 前面不需要:。在NEW,arrDate 中,您还有一个, 而不是.。最后的END 缺少;

不是错误,而是语言名称是标识符,不要放在单引号中。

CREATE TRIGGER; 行也是错误的。如果您想创建触发器,您的函数还需要声明为 returns trigger 并且 has 如果它是“之前”触发器,则返回新行。如果您打算使用后触发器,您仍然需要从中返回一些内容。

我不确定WHERE OLD.roomNum = NEW.roomNum; 应该选择什么条件。如果要获取更改行的房间号,只需使用new.depdate。如果该查询返回多于一行,select .. into ... 将失败。您可能打算使用where roomnum = new.roomnum 或类似的东西。

所以函数应该是这样的:

CREATE OR REPLACE FUNCTION new_customer() 
  RETURNS trigger 
AS
$BODY$
DECLARE
    depatureDate DATE;
BEGIN
    SELECT depDate 
       INTO depatureDate 
    FROM HotelStays 
    WHERE roomNum = NEW.roomNum;

    IF (depatureDate <= NEW.arrDate) THEN
      INSERT INTO HotelStays (roomNum, arrDate, depDate, guestName)
      VALUES (NEW.roomNum, nEW.arrDate, NEW.depDate, NEW.guestName);
    END IF;

    RETURN NEW; -- this is important for a trigger
END;
$BODY$
LANGUAGE plpgsql;

创建触发器的代码是这样的:

CREATE TRIGGER check_stays
  before update or insert on hotelstays
  execute procedure new_customer();

【讨论】:

我收到以下错误:错误:在“$BODY$ DECLARE depatureDate DATE”处或附近未终止的美元引号字符串。你能帮帮我吗 @SunilkumarVuppala:为我工作。您使用的是哪个 SQL 客户端?也许这不理解美元报价。如果对函数体使用“常规”单引号会发生什么?您的确切 Postgres 版本是什么? (select version() 的输出) 我正在使用 sql fiddle...PostgreSQL 9.3 您需要将脚本分隔符更改为其他内容,然后在左侧输入字段下方的下拉菜单中将 ; 更改为其他内容。例如。斜线:/。然后将每个语句的最终; 替换为单行上的/:sqlfiddle.com/#!15/2cee0

以上是关于错误:在“$BODY$”处或附近未终止的美元引号字符串的主要内容,如果未能解决你的问题,请参考以下文章

[Amazon](500310) 无效操作:"$$" 处或附近未终止的美元引号字符串

Liquibase : $BODY$ 或附近的未终止的美元引号字符串

postgres 迁移错误;未终止的美元引号字符串

PostgreSQL 中的“'order' 处或附近的语法错误”

在“PARALLEL”处或附近创建 postgis 扩展语法错误

错误:“修改”处或附近的语法错误 - 在 postgres