繁体   English   中英

Postgresql 9.2触发器以分隔存储的字符串中的子字段

[英]Postgresql 9.2 trigger to separate subfields in a stored string

Postgresql 9.2 DB会自动从各种机器收集数据。 DB存储所有数据,包括机器ID,固件,制造商ID等以及实际结果数据。 在一个存储的字段( varchar )中,有5个子字段,由^字符分隔。

ACT18!!!8246-EN-2.00013151!1^7.00^F5260046959^H1P1O1R1C1Q1L1^1 (Machine 1)

一台计算机到另一台计算机的数据顺序似乎有所不同。 例如机器1 2和3。上面的字符串显示固件版本,在这种情况下为“ 7.0”,它出现在子字段2中。但是,另一台机器在另一个子字段中发送数据-在这种情况下为子字段3,值为“ 1”

BACT/ALERT^A.00^1^^ (Machine 2)

我想使用CREATE TRIGGER t_machine_id AFTER INSERT函数将值“ 7.0”和“ 1”存储在单独表中的不同字段中,在其中我可以根据数据来自的机器选择使用哪个子字段。

split_part是执行此split_part的最佳功能吗? 任何人都可以提供示例代码来执行此操作吗? 我在文档中找不到任何内容。

您需要(a)使用regexp_split_to_table类的数据进行拆分,然后(b)使用某些条件匹配哪些部分属于哪些部分,因为您没有字段位置顺序可依赖。 现在,我看不到任何可靠的规则来确定什么是固件版本以及什么是机器编号。 您不能真正说出where field <> machine_number因为如果计算机1的固件版本为1不会获得任何结果。

给定虚拟数据:

CREATE TABLE machine_info(data text, machine_no integer);
INSERT INTO machine_info(data,machine_no) (VALUES
  ('ACT18!!!8246-EN-2.00013151!1^7.00^F5260046959^H1P1O1R1C1Q1L1^1',1),
  ('BACT/ALERT^A.00^1^^',2)
);

就像是:

SELECT machine_no, regexp_split_to_table(data,'\^') 
FROM machine_info;

将为您提供带有机器编号的拆分数据元素表,但随后您需要确定哪些字段是:

 machine_no |    regexp_split_to_table     
------------+------------------------------
          1 | ACT18!!!8246-EN-2.00013151!1
          1 | 7.00
          1 | F5260046959
          1 | H1P1O1R1C1Q1L1
          1 | 1
          2 | BACT/ALERT
          2 | A.00
          2 | 1
          2 | 
          2 | 
(10 rows)

您可能会发现替换regexp_split_to_array的输出更有用,这取决于您是否可以从字段顺序中获取任何有用的信息以及打算如何处理数据。

regress=# SELECT machine_no, regexp_split_to_array(data,'\^') 
          FROM machine_info;
 machine_no |                      regexp_split_to_array                       
------------+------------------------------------------------------------------
          1 | {ACT18!!!8246-EN-2.00013151!1,7.00,F5260046959,H1P1O1R1C1Q1L1,1}
          2 | {BACT/ALERT,A.00,1,"",""}
(2 rows)

假设有两个固件版本; 版本1发送code^blah^fwvers^^ ,版本2和更高版本发送code^fwvers^blah^blah2^machineno 然后,您可以区分这两者,因为您知道版本1将最后两个字段留为空白:

SELECT
  machine_no,
  CASE WHEN info_arr[4:5] = ARRAY['',''] THEN info_arr[3] ELSE info_arr[2] END AS fw_vers
FROM (
  SELECT machine_no, regexp_split_to_array(data,'\^')
  FROM machine_info
) string_parts(machine_no, info_arr);

结果:

 machine_no | fw_vers 
------------+---------
          1 | 7.00
          2 | 1
(2 rows)

当然,您仅提供了两个样本数据,因此实际的匹配规则可能会更复杂。 考虑编写SQL函数以提取所需的字段,然后从传递的数组中返回它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM