現在一個汽車售票系統,會出現相同座位重復售票的問題,這個系統使用的postgres數據庫,小弟不太熟悉,只會寫一些基本的SQL,對trigger等太不懂,網上找到不是太難就是太簡單了。請高手們幫忙指教一下。CREATE TABLE ticket_info
(
  paymentmethod smallint,
  ticket_type_id integer,
  ticket_id integer NOT NULL, -- nextval('ticket_info_id_seq'::regclass)
  member_id character varying(10),
  schedule_id bigint,
  payment_status smallint DEFAULT 0,
  seat_no character varying(20),
  auth_code character varying(10), -- 每张票唯一码,10位
  ticket_time timestamp(6) without time zone DEFAULT now(),
  sale_employee_id integer,
  price numeric,
  sale_station_id integer,
  ticket_method integer, -- 1:正常售票,2:柜台预订,3:网上订票
  from_station_id integer, -- 上車點,可以是小站
  to_station_id integer, -- 下車點,可以是小站
  ticket_comment character varying(100), -- 車輛備註,如座位保留備註
  ticket_kind integer DEFAULT 1, -- 1:正常票,2:補差價
  valid_flag integer DEFAULT 1, -- 1:有效,0:无效
  back_flag integer DEFAULT 1, -- 来回票的回票等于2,其它为1
  back_fee numeric DEFAULT 0,
  back_employee_id integer,
  back_station_id integer,
  back_time timestamp without time zone,
  CONSTRAINT ticket_info_index PRIMARY KEY (ticket_id)
) schedule_id,seat_no,valid_flag三個欄位當valid_flag=0可能會有好幾條記錄,但要求valid_flag=1只能有一條。現在的問題就是valid_flag=1出現兩條以上的記錄了,也就是相同座位重復售票了,想在table加一個check,在update,insert的時候檢查valid_flag=1記錄只能有一條。但小弟對postgres不熟悉,請高手指教啦。先謝謝,分后面補上。

解决方案 »

  1.   

    测试过程如下--创建测试表
    create table ticket_info(schedule_id bigint,seat_no varchar(20),valid_flag int);--创建检查过程tri_ticket_info.逻辑是如果新插入的记录valid_flag =1并且在表中已经存在相同的schedule_id和seat_no,则抛出异常.CREATE OR REPLACE FUNCTION "public"."tri_ticket_info" () RETURNS "trigger" AS
    $body$
    DECLARE
      
    BEGIN
      if NEW.valid_flag = 1 THEN
       if exists(select 1 from ticket_info where schedule_id = NEW.schedule_id and seat_no =NEW.seat_no) then
             raise exception 'can not add or update this record!';
            end if;
      end if;
      
      return NEW;
      
    END;
    $body$
    LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;--创建前触发器.在插入和更新的时候触发.
    CREATE TRIGGER tri_tic_info BEFORE INSERT OR UPDATE ON ticket_info
        FOR EACH ROW EXECUTE PROCEDURE tri_ticket_info();--测试 insert into ticket_info values(1,'aa-bb-cc',0);
    INSERT 0 1insert into ticket_info values(2,'aa-bb-cc',1);  
    INSERT 0 1insert into ticket_info values(2,'aa-bb-cc',1);
    ERROR:  can not add or update this record!--测试完成!
      

  2.   

    if exists(select 1 from ticket_info where valid_flag = 1 and schedule_id = NEW.schedule_id and seat_no =NEW.seat_no) then
            raise exception 'can not add or update this record!';
    end if; 上面應該加valid_flag=1才對。不過謝謝。非常感謝!!!
      

  3.   

    謝謝了,分后面加。剛到CSDN上,還沒有分可以送啊。
      

  4.   

    发现这个问题加了check这后还在存在~postgres这个数据库还真的难搞呀~
    在B/S下多线程的情况还是会出现这个情况~
    晕坏了~