Postgresql中的时间比较逻辑不起作用

时间:2014-09-27 08:20:17

标签: postgresql timestamp comparison plpgsql

我已经为postgresql编写了大约两个星期的代码,这是我第一次在(真正的)数据库中玩,已经从访问2003(哦没有)进行了交换,这对于限制太多而且进程缓慢数据。

我编写了一个功能,可以查看另一个数据库中的日志,以了解为客户提供服务所需的时间。问题是,如果数据库中没有动作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')
;

1 个答案:

答案 0 :(得分: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 $$;