PRAGMA recursive_triggers won't disable recursive triggers - sqlite

I do not understand trigger recursion in SQLite 3.8.6.
From my understanding setting PRAGMA recursive_triggers to 0 should prevent a trigger from triggering another one.
But here is an example of what actually happens for me:
sqlite> PRAGMA recursive_triggers;
0
sqlite> CREATE TABLE t1(a TEXT, b TEXT, c TEXT);
sqlite> CREATE TRIGGER on_insert AFTER INSERT ON t1
...> BEGIN
...> UPDATE t1 SET b="c" WHERE rowid=NEW.rowid;
...> END;
sqlite> CREATE TRIGGER on_update_b AFTER UPDATE OF b ON t1
...> BEGIN
...> SELECT RAISE(fail,"triggered update b!");
...> END;
sqlite> INSERT INTO t1 VALUES("a","b","c");
Error: triggered update b!
I probably misunderstood something...
Is it possible to prevent the on_update_b trigger to be triggered?

These triggers are not recursive.
A trigger is recursive if it triggers itself (directly or indirectly).
This would be the case if on_update_b would execute an UPDATE or INSERT.

Related

i want to delete the data fetching from the cursor without using for update

I have set of data filtering from the select statement which I need to delete from the table 'SHOP_MATERIAL_ASSIGN_TAB'. I have used a cursor to delete. but this caused problems when executing. any idea to get it done without using 'for update' method.
DECLARE
CURSOR DELDATA_ IS
SELECT B.*
FROM IC_WQ_OLD_LOCATION_TAB A, SHOP_MATERIAL_ASSIGN_TAB B
WHERE A.LOCATION_NO = B.LOCATION_NO
AND A.SITE = B.CONTRACT
AND B.LOCATION_NO = 'HYLIN001'
FOR UPDATE;
TEMP_ DELDATA_%ROWTYPE;
BEGIN
OPEN DELDATA_;
LOOP
FETCH DELDATA_
INTO TEMP_;
EXIT WHEN DELDATA_%NOTFOUND;
DELETE FROM SHOP_MATERIAL_ASSIGN_TAB WHERE CURRENT OF DELDATA_;
END LOOP;
COMMIT;
END;
Don't use PL/SQL at all.
DELETE FROM shop_material_assign_tab
WHERE EXISTS
(SELECT NULL
FROM ic_wq_old_location_tab a
WHERE a.location_no = b.location_no
AND a.site = b.contract)
AND b.location_no = 'HYLIN001'

SQLite3 trigger does not work

The trigger defined below does not work in sqlite3.
CREATE TRIGGER 'delete_expired' BEFORE INSERT ON 'visitor' BEGIN DELETE FROM visitor WHERE 'create_at' <= date('now', '-6 day'); END
But, this does... Something might be wrong with the conditions. Can anybody point me out? Thanks in advance
CREATE TRIGGER 'delete_expired' BEFORE INSERT ON 'visitor' BEGIN DELETE FROM visitor; END
If you need to quote table names and column names, use double quotes, not single quotes.
CREATE TRIGGER 'delete_expired'
BEFORE INSERT ON visitor
BEGIN DELETE FROM visitor WHERE create_at <= date('now', '-6 day');
END;
Single quotes usually denote a literal string.
sqlite> select 'create_at' from visitor;
create_at
In an interactive session . . .
sqlite> create table visitor (create_at timestamp);
sqlite> CREATE TRIGGER 'delete_expired'
...> BEFORE INSERT ON visitor
...> BEGIN DELETE FROM visitor WHERE create_at <= date('now', '-6 day');
...> END;
sqlite> insert into visitor values ('2014-01-01');
sqlite> select * from visitor;
2014-01-01
sqlite> insert into visitor values ('2014-11-06');
sqlite> select * from visitor;
2014-11-06

SQLite time insert query

I want to insert time value to SQLite. I searched about functions, modifiers, timestrings but I could not achieve to my aim. When I write my query, this does not record the '.323', only records '08:25:01'. I want to record '08:25:01.323'. My query is:
insert into table_name (column_name) values (time('08:25:01.323'))
I'm waiting for your help..
Store the time as a string and only parse it whe necessary.
sqlite> create table t (t text);
sqlite> insert into t values ('08:25:01.323');
sqlite> select * from t;
08:25:01.323
sqlite> select t, time(t) from t;
08:25:01.323|08:25:01

PRAGMA foreign_key_check;

I am trying to use PRAGMA foreign_key_check; without success :(
I have made some foreign keys violations on a database (with PRAGMA foreign_keys = OFF;), then I set this to true then launched PRAGMA foreign_key_check; but this did not return any results.
However, when I try to insert the very same lines with foreign keys violations with PRAGMA foreign_keys = ON; I do get a foreign key constraint violation error.
I am using SQLite 3.7.3.
Is there something I am missing regarding this command? Is there a bug?
Thanks
EDIT: I have just tried with 3.8.3.1 (higher version this time ;) ) but cannot get any results though :(
However, some other commands seem to not work as expected (especially .schema !?):
SQLite version 3.8.3.1 2014-02-11 14:52:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> attach "D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db" as db1;
sqlite> .schema device
sqlite> PRAGMA foreign_keys=ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_key_check;
sqlite> select * from device
...> ;
1|test|/|/|0|0
sqlite> select * from playlist
...> ;
sqlite> PRAGMA integrity_check;
ok
sqlite> .dump device
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
COMMIT;
sqlite> PRAGMA table_info(device);
0|idDevice|INTEGER|1||1
1|name|TEXT|1||0
2|source|TEXT|1||0
3|destination|TEXT|1||0
4|idPlaylist|INTEGER|1||0
5|idMachine|INTEGER|1||0
sqlite>
PRAGMA foreign_key_check was added in sqlite 3.7.16. You have an older version.
Unknown pragmas are just no-ops; no errors are emitted.
I have found out the solution :) Problem was a misuse (or bug ?) of sqlite3.exe
When calling sqlite3.exe without parameters, a main empty database is created, and looks like the commands does not apply the attached db:
D:\>sqlite3.exe
SQLite version 3.8.3.1 2014-02-11 14:52:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> attach "D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db" as db1
...> ;
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main
2 db1 D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db
sqlite> .tables
db1.device db1.libType db1.optiontype db1.playlist
db1.file db1.machine db1.path db1.statement
db1.genre db1.option db1.playCounter db1.statsource
sqlite> .schema db1.device
sqlite> .exit
If opening database as an argument of sqlite3.exe, it works as expected:
D:\>sqlite3.exe MusicLib_Minimal_TEST_FOREIGN_KEYS.db
SQLite version 3.8.3.1 2014-02-11 14:52:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main D:\MusicLib_Minimal_TEST_FOREIGN_KEYS.db
sqlite> .tables
device genre machine optiontype playCounter statement
file libType option path playlist statsource
sqlite> .schema device
CREATE TABLE "device" (
"idDevice" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"name" TEXT NOT NULL,
"source" TEXT NOT NULL,
"destination" TEXT NOT NULL,
"idPlaylist" INTEGER NOT NULL,
"idMachine" INTEGER NOT NULL,
FOREIGN KEY(idPlaylist) REFERENCES playlist(idPlaylist),
FOREIGN KEY(idMachine) REFERENCES machine(idMachine)
);
sqlite> PRAGMA foreign_keys;
0
sqlite> PRAGMA foreign_keys=ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_key_check;
device|1|machine|0
device|1|playlist|1
sqlite> select * from device
...> ;
1|test|/|/|0|0
sqlite> select * from playlist
...> ;
sqlite> select * from machine
...> ;

SQLite Trigger to SQL Server Express 2008

I need help on SQL Server syntax to create some triggres that I´ve used with success on SQLite, but I'm having trouble with NEW.Table once it´s not part of SQL Server.
That´s my SQLite trigger code:
UPDATE EngineeringItems set ElevacaoFIT = CAST(round((select "Position Z" - MatchingPipeOD / 2 from EngineeringItems where PnPId = new.PNPID), 0) as INT) where PNPID = new.PNPID;
PNPID is the table pk!
EDIT 2:
Thanks again buddy!
I´ve tried your new code with a little modifications and SQL Server accepted it and trigger was created successfully. So the code is:
CREATE TRIGGER [ElevacaoFIT_Insert]
ON [dbo].[EngineeringItems]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE EngineeringItems
SET
ElevacaoFIT = CAST(ROUND((select EngineeringItems."Position Z" - (EngineeringItems.MatchingPipeOD / 2)
FROM
EngineeringItems INNER JOIN inserted ON EngineeringItems.PnPId = inserted.PnPId), 0) AS INT);
END
But now I get this message: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.! Any idea?
Sorry for bother you... Thanks again!!
Can you post what you have tried on SQL Server?
Something like the following may do it:
CREATE TRIGGER [dbo].[EngineeringItems_Trigger]
ON [dbo].[EngineeringItems]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
UPDATE EngineeringItems
SET
ElevacaoFIT = CAST(round(("Position Z" - MatchingPipeOD / 2), 0) as INT)
FROM
EngineeringItems INNER JOIN inserted ON EngineeringItems.PnPId = inserted.PNPID;
END

Resources