我已经为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')
;
答案 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 $$;