Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Triggers sqlite3触发器将十六进制文本转换为等效的二进制blob_Triggers_Sqlite_Hex_Blob - Fatal编程技术网

Triggers sqlite3触发器将十六进制文本转换为等效的二进制blob

Triggers sqlite3触发器将十六进制文本转换为等效的二进制blob,triggers,sqlite,hex,blob,Triggers,Sqlite,Hex,Blob,我想要一个后插入触发器,将十六进制文本字符串转换为其二进制blob等价物 我试过这样的方法: CREATE TABLE data ( t_hex TEXT, b_hex BLOB ); CREATE TRIGGER data_insert_trigger AFTER INSERT ON data BEGIN UPDATE data SET b_hex = "x''"||t_hex||"''" WHERE rowid = new.rowid; END; INSERT i

我想要一个后插入触发器,将十六进制文本字符串转换为其二进制blob等价物

我试过这样的方法:

CREATE TABLE data
(
   t_hex   TEXT,
   b_hex   BLOB
);

CREATE TRIGGER data_insert_trigger AFTER INSERT ON data
BEGIN
  UPDATE data SET b_hex = "x''"||t_hex||"''" WHERE rowid = new.rowid;
END;

INSERT into data(t_hex) VALUES ('A5A5');
sqlite> update data set t_hex = 'DEADBEEF';
Error: too many levels of trigger recursion
这导致:

sqlite> select * from data;
t_hex = A5A5
b_hex = x''A5A5''
sqlite> select * from data;
t_hex = A5A5
b_hex = A5A5
也试过

CREATE TRIGGER data_insert_trigger AFTER INSERT ON data
BEGIN
  UPDATE data SET b_hex = x''||t_hex||'' WHERE rowid = new.rowid;
END;
这导致:

sqlite> select * from data;
t_hex = A5A5
b_hex = x''A5A5''
sqlite> select * from data;
t_hex = A5A5
b_hex = A5A5
有人知道一种利用x'value'语法但引用现有列值或其他基于SQL的机制的方法吗

***编辑***

考虑到定制函数,感谢CL和LS_-dev。LS_-dev在这里提供的纯SQL解决方案,我就在这里。我将数据更新触发器调整为

CREATE TRIGGER data_t_update_trigger 
AFTER UPDATE ON data 
WHEN NEW.t_hex IS NOT OLD.t_hex
BEGIN
   UPDATE data SET b_hex = x'' WHERE ROWID = NEW.ROWID;
END;
我的测试集生成:

sqlite> insert into data(t_hex) values('A5A5');
sqlite> select t_hex, hex(b_hex) from data;
A5A5|A5A5
sqlite> update data set t_hex = 'FF'; 
sqlite> select t_hex, hex(b_hex) from data;
FF|FF
sqlite> update data set t_hex = 'FFFE';
sqlite> select t_hex, hex(b_hex) from data;
FFFE|FFFE3F
sqlite> update data set t_hex = '00';
Error: too many levels of trigger recursion
通过这项工作,我将data_h_update_触发器中的几行限定为:

CREATE TRIGGER data_b_update_trigger
AFTER UPDATE ON data 
WHEN LENGTH(NEW.t_hex)>LENGTH(NEW.b_hex)*2
BEGIN
   UPDATE data SET b_hex = NEW.b_hex||COALESCE((
      SELECT b FROM _hb WHERE h=SUBSTR(NEW.t_hex, (LENGTH(NEW.b_hex)*2)+1, 2)
   ), CAST('?' AS BLOB)) WHERE ROWID = NEW.ROWID;
END;
现在,我的测试集生成:

sqlite> select t_hex, hex(b_hex) from data;
A5A5|A5A5
sqlite> update data set t_hex = 'FF'; 
sqlite> select t_hex, hex(b_hex) from data;
FF|FF
sqlite> update data set t_hex = 'FFFE';
sqlite> select t_hex, hex(b_hex) from data;
FFFE|FFFE
sqlite> update data set t_hex = '00';
Error: too many levels of trigger recursion
所以仍然在处理一些无法解释的递归。FWIW,这种情况也发生在这样的语句中:

CREATE TABLE data
(
   t_hex   TEXT,
   b_hex   BLOB
);

CREATE TRIGGER data_insert_trigger AFTER INSERT ON data
BEGIN
  UPDATE data SET b_hex = "x''"||t_hex||"''" WHERE rowid = new.rowid;
END;

INSERT into data(t_hex) VALUES ('A5A5');
sqlite> update data set t_hex = 'DEADBEEF';
Error: too many levels of trigger recursion
运行: SQLite版本3.7.9 2011-11-01 00:52:41只能在SQL语句中直接使用;它们不能从SQL代码动态构造


要将十六进制字符串转换为blob,您必须安装自己的用户定义函数。

使用用户定义函数将更简单、更便宜,但我找到了一个解决方案

首先,您需要一个查找表,如下所示:

CREATE TABLE _hb(h TEXT COLLATE NOCASE, b BLOB);
BEGIN;
INSERT INTO _hb VALUES('00', x'00');
INSERT INTO _hb VALUES('01', x'01');
(...)
INSERT INTO _hb VALUES('A4', x'A4');
INSERT INTO _hb VALUES('A5', x'A5');
INSERT INTO _hb VALUES('A6', x'A6');
(...)
INSERT INTO _hb VALUES('FE', x'FE');
INSERT INTO _hb VALUES('FF', x'FF');
COMMIT;
然后,启用(SQLite>=3.6.18):

您可以创建一个触发器,该触发器将逐步向
b_hex
添加字节:

CREATE TRIGGER data_h_update_trigger
AFTER UPDATE ON data 
WHEN LENGTH(NEW.t_hex)>LENGTH(NEW.b_hex)*2
BEGIN
   UPDATE data SET b_hex = b_hex||COALESCE((
      SELECT b FROM _hb WHERE h=SUBSTR(NEW.t_hex, LENGTH(b_hex)*2+1, 2)
   ), CAST('?' AS BLOB)) WHERE ROWID = NEW.ROWID;
END;
插入数据或更新数据时再触发两个触发器:

CREATE TRIGGER data_insert_trigger 
AFTER INSERT ON data
BEGIN
   UPDATE data SET b_hex = x'' WHERE ROWID = NEW.ROWID;
END;

CREATE TRIGGER data_t_update_trigger 
AFTER UPDATE OF t_hex ON data
BEGIN
   UPDATE data SET b_hex = x'' WHERE ROWID = NEW.ROWID;
END;

限制:单步blob计算限制为(默认情况下为1000)字节。

非常漂亮和接近。将数据更新触发器更改为更新后和s/h\U hex/t\U hex/g。然后触摸更新并选择数据更新触发器。将结果发布到顶部。仍然在处理一个简单的“太多级别的触发器递归”:更新数据集t_hex='00';和其他类似的陈述。是的,我的回答有一些拼写错误。如果您运行了太多级别的触发器递归,那么您将缺少
when
子句。你在问题中贴出答案对我来说不是很正确。我的功绩在哪里?功绩被授予。我将继续修改到实际的工作解决方案,并将结果发布到顶部。谢谢你的开始。