1

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最好的功能吗?任何人都可以提供一个示例代码来做到这一点吗?我在文档中找不到任何内容。

4

1 回答 1

0

您需要 (a) 使用类似regexp_split_to_tablethen (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 函数来提取所需的字段并从传递的数组中返回它们。

于 2012-10-23T08:36:07.733 回答