错误:未结算的美元报价字符串在“$ BODY $”附近

时间:2016-05-30 01:01:04

标签: postgresql

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

问题我试图解决:即使在现有客人签出之前,也可以为房间号码添加新条目(对于新访客)。 我正在尝试使用触发器来解决这个问题。请帮帮我。提前谢谢。

2 个答案:

答案 0 :(得分:1)

您的代码中存在多个错误。首先是depatureDate DATE;\中的反斜杠。您还缺少THEN条款IF,而new前面不需要:。您在,中也有.而不是NEW,arrDate。最终END缺少;

不是错误,但语言名称是标识符,请勿将其放在单引号中。

CREATE TRIGGER;行也是错误的。如果你想创建触发器,你的函数也需要被声明为returns trigger来返回新行,如果它是&#34;之前&#34;触发。如果你打算使用后触发器,你仍然需要从中返回一些东西。

我不确定条件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();

答案 1 :(得分:0)

正如作者提到的,他使用了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;