有没有办法为 sqlite 编写一个 SQL 输入文件,该文件会以某种方式“抛出”错误,例如。如果不满足条件,则退出事务并回滚?
我有一个脚本应该做一些事情,但前提是一个表中有某一行。如果不存在,脚本的执行可能会产生致命结果并损坏数据库。
该脚本现在仅按需启动,但我更愿意添加一个故障保护功能,以便在出现问题时阻止其执行。
基本上我需要的是类似的东西
/* IF */ SELECT value FROM meta WHERE key = 'version' /* != hardcoded_version_string THROW SOME EXCEPTION */
有什么办法可以做到这一点吗?在 Postgre / Oracle 中,这可以使用 PLSQL 来完成,但我不确定 sqlite 是否支持这样的事情?
Triggers可以使用RAISE函数来产生错误:
CREATE VIEW test AS SELECT NULL AS value;
CREATE TRIGGER test_insert
INSTEAD OF INSERT ON test
BEGIN
SELECT RAISE(FAIL, 'wrong value')
WHERE NEW.value != 'fixed_value';
END;
INSERT INTO test SELECT 'fixed_value';
INSERT INTO test SELECT 'whatever';
Error: wrong value
有没有办法为sqlite编写一个SQL输入文件 以某种方式“抛出”错误,例如。退出事务并回滚,如果 不满足条件?
一种解决方法可能是创建虚拟表并显式违反
NULL
约束:
CREATE TABLE meta("key" VARCHAR(100));
INSERT INTO meta("key") VALUES ('version');
CREATE TEMPORARY TABLE dummy(col INT NOT NULL);
交易:
BEGIN TRANSACTION;
INSERT INTO dummy(col)
SELECT NULL -- explicit insert of NULL
FROM meta
WHERE "key" = 'version';
-- Error: NOT NULL constraint failed: dummy.col
-- rest code
INSERT INTO meta("key")
VALUES ('val1');
INSERT INTO meta("key")
VALUES ('val2');
-- ...
COMMIT;
SqlFiddleDemo
请记住,SQLite 不是过程语言,这个解决方案有点难看。
伙计们! 看来我为我们所有人做了一些丑陋的三步决定;)
1)。创建一个虚拟表:
创建表stop_script(dummy);
2)。创建触发器:
在_stop_script_insert之前创建触发器 在为每行插入 stop_script 之前 开始 select raise(FAIL,'脚本执行停止!'); 结束;
3)。要在脚本中任意位置中断执行,请使用以下命令:
插入stop_script 选择空 其中1=1; --你自己的打破脚本执行的案例
附注 遗憾的是 raise 函数只接受 const 值。 但这比什么都没有好得多;) 享受...