2014-09-27 28 views
0

我已經爲postgresql編寫了大約兩週的代碼,而且這是我第一次玩一個(真實)數據庫,已經從access 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/。我也不太瞭解你在這裏用一個無效的程序來達到目的。 – 2014-09-27 12:44:43

+0

我沒有OpenID,所以我只是在這裏添加架構。這兩個transactional_endtime都是正確的,但開始時間應分別爲2014-09-19 01:17:43和2014-09-15 01:03:14。 – TLOCK 2014-09-27 13:26:30

+0

另外說實話,我不知道爲什麼我選擇了一個無效的程序。我只是這樣做,因爲它允許我執行代碼。我並不太自信或對其他選項有所瞭解。 – TLOCK 2014-09-27 13:55:08

回答

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