2014-09-27 2 views
0

Я писал код для postgresql около двух недель и его первый раз играл в (настоящую) базу данных, заменив доступ 2003 (о нет), что тоже было ограничивать и замедлять обработку данных.Логика сравнения времени в Postgresql не работает

Я написал функцию, которая просматривает журналы в другой базе данных, чтобы указать, сколько времени потребуется для обслуживания клиента. Проблема в том, что я пытаюсь сделать стоп смотреть и действовать так, как если бы обслуживание закончилось, если в базе данных нет действий в течение 3 минут. Существует транзакция, которая является жесткой остановкой, и я отмечаю это с помощью «E», и если имя пользователя отличается от другого, обслуживание заканчивается. Для жесткой остановки и изменения имени пользователя код работает нормально. Для логики времени это не так.

CREATE FUNCTION rspcalc() RETURNS VOID 
language plpgsql as $$ 
<<fn>> 
DECLARE 

_reportdata public.transactional_flag%ROWTYPE; 
_currentusername varchar(255); 
_intransaction boolean; 
_nextslice time; 
_endtime timestamp; 
_currenttime timestamp; 

BEGIN 

_currentusername = 'XXXX'; 
_intransaction = false; 

FOR _reportdata IN 
    SELECT * FROM transactional_flag 
     ORDER BY transactional_username, transactional_actiontime DESC LOOP 

    --If username currently in use is not the username on the row, end the transaction measure 

    IF NOT (_currentusername = _reportdata.transactional_username) THEN 

     IF _intransaction THEN 
     INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username) 
      VALUES (_endtime, _currenttime, _currentusername); 
     END IF; 

     _intransaction = FALSE; 
     _currentusername = _reportdata.transactional_username; 
     _nextslice = '00:00:00'::time; 

    END IF; 

    CASE _reportdata.transactional_type 

    --O represents an output - the assumption is if they do happen, they happen within 5 secounds of the end of a transaction 

     WHEN 'O' THEN 

      IF _intransaction THEN 

       IF _reportdata.transactional_actiontime > (_currenttime + _nextslice) THEN 

       INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username) 
        VALUES (_endtime, _currenttime, _currentusername); 

       _intransaction = FALSE; 
       _nextslice = '00:00:05'::time; 
       ELSE 

       _currenttime = _reportdata.transactional_actiontime; 
       _nextslice = '00:03:00'::time; 

       END IF; 

      ELSE 

       _currenttime = _reportdata.transactional_actiontime; 
       _endtime = _reportdata.transactional_actiontime; 
       _nextslice = '00:00:05'::time; 

      END IF; 

    --E represents the end of a transaction 

     WHEN 'E' THEN 

      IF _intransaction THEN 

       INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username) 
        VALUES (_endtime, _currenttime, _currentusername); 

       _intransaction = true; 
       _endtime = _reportdata.transactional_actiontime; 
       _currenttime = _reportdata.transactional_actiontime; 
       _nextslice = '00:03:00'::time; 

      ELSE 

       IF _reportdata.transactional_actiontime > (_currenttime + _nextslice) THEN 

       _endtime = _reportdata.transactional_actiontime; 

       END IF; 

      _currenttime = _reportdata.transactional_actiontime; 
      _nextslice = '00:03:00'::time; 
      _intransaction = true; 

      END IF; 

    --N represents any user use of the system, except an end 
    --S represents a document creation 

     WHEN 'N', 'S' THEN 

      IF _intransaction THEN 

       IF _reportdata.transactional_actiontime > (_currenttime + _nextslice) THEN 

       INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username) 
        VALUES (_endtime, _currenttime, _currentusername); 

       _intransaction = FALSE; 
       _nextslice = '00:00:00'::time; 

       ELSE 
       _currenttime = _reportdata.transactional_actiontime; 
       _nextslice = '00:03:00'::time; 
       END IF; 

      ELSE 

      _nextslice = '00:00:00'::time; 

      END IF; 

     ELSE 
     --PANIC 

    END CASE; 

END LOOP; 

END $$; 

У меня есть RTFM так сложно (но, вероятно, недостаточно сложно). Я тестировал большую часть кода по частям, но у меня свободный конец.

Я научил себя кодировать в VB6 только недавно, поэтому любые советы, которые вы можете дать по любому аспекту кода, будут оценены!

CREATE TABLE transactional_flag 
(
    transactional_rowid bigserial NOT NULL, 
    transactional_actiontime timestamp without time zone, 
    transactional_systemstring character varying(3), 
    transactional_username character varying(255), 
    transactional_type character varying(1), 
    CONSTRAINT transactional_flag_pkey PRIMARY KEY (transactional_rowid) 
) 
WITH (
    OIDS=FALSE 
); 

CREATE INDEX transactional_index 
    ON transactional_flag 
    USING btree 
    (transactional_username COLLATE pg_catalog."default", transactional_actiontime DESC); 

CREATE TABLE transactional_report 
(
    transactional_rowid bigserial NOT NULL, 
    transactional_endtime timestamp without time zone, 
    transactional_starttime timestamp without time zone, 
    transactional_username character varying(255), 
    CONSTRAINT transactional_report_pkey PRIMARY KEY (transactional_rowid) 
) 
WITH (
    OIDS=FALSE 
); 


INSERT INTO transactional_report 
    ("transactional_rowid", "transactional_endtime", "transactional_starttime", "transactional_username") 
VALUES 
    (1004053,'2014-09-19 01:21:09','2014-09-15 01:06:07','EXSP1049'), 
    (1004054,'2014-09-15 01:06:06','2014-09-12 06:30:49','EXSP1049') 
; 

INSERT INTO transactional_flag 
    ("transactional_rowid", "transactional_actiontime", "transactional_systemstring", "transactional_username", "transactional_type") 
VALUES 
    (16543226, '2014-09-19 01:21:22', 'PEA', 'EXSP1049', 'N'), 
    (16543163, '2014-09-19 01:21:10', 'PEA', 'EXSP1049', 'N'), 
    (16543153, '2014-09-19 01:21:09', 'PEA', 'EXSP1049', 'N'), 
    (16820614, '2014-09-19 01:21:09', 'PEA', 'EXSP1049', 'E'), 
    (16543135, '2014-09-19 01:21:03', 'PEA', 'EXSP1049', 'N'), 
(16543012, '2014-09-19 01:20:36', 'PEA', 'EXSP1049', 'N'), 
(16543007, '2014-09-19 01:20:35', 'PEA', 'EXSP1049', 'N'), 
(16542996, '2014-09-19 01:20:34', 'PEA', 'EXSP1049', 'N'), 
(16542997, '2014-09-19 01:20:34', 'PEA', 'EXSP1049', 'N'), 
(16542908, '2014-09-19 01:20:09', 'PEA', 'EXSP1049', 'N'), 
(16542864, '2014-09-19 01:19:58', 'PEA', 'EXSP1049', 'N'), 
(16542858, '2014-09-19 01:19:56', 'PEA', 'EXSP1049', 'N'), 
(16542852, '2014-09-19 01:19:54', 'PEA', 'EXSP1049', 'N'), 
(16542693, '2014-09-19 01:19:17', 'PEA', 'EXSP1049', 'N'), 
(16542605, '2014-09-19 01:18:53', 'PEA', 'EXSP1049', 'N'), 
(16542600, '2014-09-19 01:18:52', 'PEA', 'EXSP1049', 'N'), 
(16542498, '2014-09-19 01:18:24', 'PEA', 'EXSP1049', 'N'), 
(16542494, '2014-09-19 01:18:22', 'PEA', 'EXSP1049', 'N'), 
(16542424, '2014-09-19 01:18:13', 'PEA', 'EXSP1049', 'N'), 
(16542183, '2014-09-19 01:17:43', 'PEA', 'EXSP1049', 'N'), 
(15903153, '2014-09-15 01:06:07', 'PEA', 'EXSP1049', 'N'), 
(15903146, '2014-09-15 01:06:06', 'PEA', 'EXSP1049', 'N'), 
(16797265, '2014-09-15 01:06:06', 'PEA', 'EXSP1049', 'E'), 
(15903060, '2014-09-15 01:05:48', 'PEA', 'EXSP1049', 'N'), 
(15903046, '2014-09-15 01:05:45', 'PEA', 'EXSP1049', 'N'), 
(15902188, '2014-09-15 01:03:18', 'PEA', 'EXSP1049', 'N'), 
(15902173, '2014-09-15 01:03:14', 'PEA', 'EXSP1049', 'N'), 
(15900149, '2014-09-15 00:57:18', 'PEA', 'EXSP1049', 'N'), 
(15899930, '2014-09-15 00:56:36', 'PEA', 'EXSP1049', 'N'), 
(15899922, '2014-09-15 00:56:34', 'PEA', 'EXSP1049', 'N'), 
(15899430, '2014-09-15 00:54:55', 'PEA', 'EXSP1049', 'N'), 
(15899406, '2014-09-15 00:54:51', 'PEA', 'EXSP1049', 'N'), 
(15899053, '2014-09-15 00:53:16', 'PEA', 'EXSP1049', 'N'), 
(15899042, '2014-09-15 00:53:12', 'PEA', 'EXSP1049', 'N'), 
(15898854, '2014-09-15 00:52:17', 'PEA', 'EXSP1049', 'N'), 
(15898698, '2014-09-15 00:51:32', 'PEA', 'EXSP1049', 'N'), 
(15898683, '2014-09-15 00:51:29', 'PEA', 'EXSP1049', 'N'), 
(15898682, '2014-09-15 00:51:28', 'PEA', 'EXSP1049', 'N'), 
(15898645, '2014-09-15 00:51:21', 'PEA', 'EXSP1049', 'N'), 
(15898637, '2014-09-15 00:51:19', 'PEA', 'EXSP1049', 'N'), 
(15898605, '2014-09-15 00:51:11', 'PEA', 'EXSP1049', 'N'), 
(15898046, '2014-09-15 00:49:23', 'PEA', 'EXSP1049', 'N'), 
(15897966, '2014-09-15 00:49:10', 'PEA', 'EXSP1049', 'N'), 
(15897916, '2014-09-15 00:49:00', 'PEA', 'EXSP1049', 'N'), 
(15897894, '2014-09-15 00:48:54', 'PEA', 'EXSP1049', 'N'), 
(15897620, '2014-09-15 00:48:02', 'PEA', 'EXSP1049', 'N'), 
(15897556, '2014-09-15 00:47:49', 'PEA', 'EXSP1049', 'N'), 
(15897528, '2014-09-15 00:47:44', 'PEA', 'EXSP1049', 'N'), 
(15897324, '2014-09-15 00:47:00', 'PEA', 'EXSP1049', 'N'), 
(15897300, '2014-09-15 00:46:55', 'PEA', 'EXSP1049', 'N'), 
(15892174, '2014-09-15 00:28:37', 'PEA', 'EXSP1049', 'N'), 
(15886571, '2014-09-15 00:10:07', 'PEA', 'EXSP1049', 'N'), 
(15886455, '2014-09-15 00:09:47', 'PEA', 'EXSP1049', 'N'), 
(15886286, '2014-09-15 00:09:22', 'PEA', 'EXSP1049', 'N'), 
(15859397, '2014-09-12 06:30:49', 'PEA', 'EXSP1049', 'N'), 
(16795869, '2014-09-12 06:30:49', 'PEA', 'EXSP1049', 'E'), 
(15859389, '2014-09-12 06:30:48', 'PEA', 'EXSP1049', 'N'), 
(15859375, '2014-09-12 06:30:46', 'PEA', 'EXSP1049', 'N'), 
(15859247, '2014-09-12 06:30:18', 'PEA', 'EXSP1049', 'N'), 
(15859228, '2014-09-12 06:30:15', 'PEA', 'EXSP1049', 'N') 
; 
+0

Я думаю, вам может потребоваться показать фактические данные, соответствующие коду, в противном случае довольно сложно сказать, что происходит. Можете ли вы показать некоторые данные образца? http://sqlfiddle.com/. Я также не совсем понимаю, что вы пытаетесь достичь с помощью процедуры void. –

+0

У меня нет OpenID, поэтому я просто добавил схему здесь. Оба transactional_endtime являются правильными, но время начала должно быть 2014-09-19 01:17:43 и 2014-09-15 01:03:14 соответственно. – TLOCK

+0

Также, честно говоря, я не знаю, почему я выбрал процедуру void. Я просто сделал это, потому что это позволило мне выполнить код. Я не слишком уверен в себе и осведомлен о других вариантах. – TLOCK

ответ

0

Не знаете, почему это работает, но я изменил код и изменил тип _nextslice на метку времени. Я также добавил некоторые дополнительные функции, связанные с заказами на продажу.

CREATE FUNCTION rspcalc() RETURNS VOID 
language plpgsql as $$ 
<<fn>> 
DECLARE 

_reportdata public.transactional_flag%ROWTYPE; 
_currentusername varchar(255); 
_currentSOtype varchar(4); 
_intransaction boolean; 
_nextslice timestamp; 
_endtime timestamp; 
_currenttime timestamp; 

BEGIN 

_currentusername = 'XXXX'; 
_intransaction = false; 
_currentSOtype = ''; 

FOR _reportdata IN 
    SELECT * FROM transactional_flag 
     ORDER BY transactional_username, transactional_actiontime DESC LOOP 

    --If username currently in use is not the username on the row, end the transaction measure 

    IF NOT (_currentusername = _reportdata.transactional_username) THEN 

     IF _intransaction THEN 
     INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username, transactional_salesordertype) 
      VALUES (_endtime, _currenttime, _currentusername, _currentSOtype); 
     END IF; 

     _intransaction = FALSE; 
     _currentusername = _reportdata.transactional_username; 
     _endtime = _reportdata.transactional_actiontime; 
     _currentSOtype = ''; 

    END IF; 

    --If this row's actiontime is before the acceptable backwards-stretching _nextslice, end the transaction 

    IF _intransaction AND (_reportdata.transactional_actiontime < _nextslice) THEN 

    INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username, transactional_salesordertype) 
     VALUES (_endtime, _currenttime, _currentusername, _currentSOtype); 

    _intransaction = FALSE; 
    _currentSOtype = ''; 

    END IF; 

    CASE _reportdata.transactional_type 

    --N represents any CIC0 or VA01 transaction in STAD 

     WHEN 'N' THEN 

      IF _intransaction THEN 

      _nextslice = _reportdata.transactional_actiontime - '00:03:00'::time; 

      ELSE 

      _nextslice = _reportdata.transactional_actiontime; 

      END IF; 
    --S represents a document creation in VBAK 

     WHEN 'S' THEN 

      IF _intransaction THEN 

      _nextslice = _reportdata.transactional_actiontime - '00:03:00'::time; 
      _currentSOtype = _reportdata.transactional_salesordertype; 

      ELSE 

      _nextslice = _reportdata.transactional_actiontime; 

      END IF; 

    --O represents an output in NAST 

     WHEN 'O' THEN 

      IF _intransaction THEN 

      _nextslice = _reportdata.transactional_actiontime - '00:03:00'::time; 

      ELSE 

      _nextslice = _reportdata.transactional_actiontime - '00:00:05'::time; 
      _endtime = _reportdata.transactional_actiontime; 

      END IF; 

    --E represents a VA - U - 3000 in STAD - the end of a transaction 

     WHEN 'E' THEN 

      IF _intransaction THEN 

       INSERT INTO transactional_report (transactional_endtime, transactional_starttime, transactional_username, transactional_salesordertype) 
        VALUES (_endtime, _currenttime, _currentusername, _currentSOtype); 

       _currentSOtype = ''; 

       _endtime = _reportdata.transactional_actiontime; 

      ELSE 
       IF _endtime > (_reportdata.transactional_actiontime + '00:00:05'::time) THEN 
        _endtime = _reportdata.transactional_actiontime; 
       END IF; 

      END IF; 

     _nextslice = _reportdata.transactional_actiontime - '00:03:00'::time; 
     _intransaction = TRUE; 

     ELSE 
     --PANIC 

    END CASE; 

_currenttime = _reportdata.transactional_actiontime; 

END LOOP; 

END $$;