Don't seem to find a working example:
a) How can we CREATE TRIGGER trigger_name AFTER INSERT,UPDATE,DELETE on table_name FOR ...
b) Is there a simple syntax to drop a table with defined triggers, and why would TD try to block it anyway?
Related
I am sure I can solve this programmatically, but I am curious if I can do this in one query.
Context:
I will be querying multiple databases, some will have a table; 'table', others will instead have the table; 'table_v2'. I want to run the same SELECT statement on the table that exists. I know I can check if a table exists, but I want to know if I can do it all in one statement.
psuedo code summary of what I want to do in one statement:
if 'SELECT name FROM sqlite_master WHERE type='table' AND name=''table'; is not empty:
SELECT * FROM table;
else
SELECT * FROM table_v2;
I am beholden to constraints out of my control.
Thoughts:
Could I have the table name be a regex?
Can I run both SELECTS, ignore the failed result, and just return the success?
Generally, you can't do either. The query planner in SQLite needs to know the name of the table beforehand, and it must be valid so it can determine which paths to take.
You can use the loadable extension eval to build up the SQL query based off of the schema. Though, this exposes a variant of the same issue, since the query planner needs the table name, you need to build up the entire SQL statement, then run it, so you'll need two eval calls.
SELECT EVAL(
'SELECT * FROM ''' ||
EVAL('SELECT name FROM sqlite_master WHERE type=''table'' AND name IN (''table'', ''table_v2'');') ||
''';'
);
To use the eval function, you'll need to either build and load the extension as a library, or build it into your own custom build of SQLite itself.
Of course, I can't answer if you should do this.
I want to create a new table for every row that is inserted into an existing table.
As I understand only DML operation is allowed on trigger, is it correct.
If so is there a alternative way of achieving my objective?
SQLite indeed allows only DML in a trigger body.
However, you could do a SELECT with a user-defined function that then executes another SQL command to create the table:
CREATE TRIGGER ...
...
BEGIN
SELECT my_create_table_function(NEW.name);
END;
Please help me in resolving below issue i am facing, i have to insert data into a table(table name genereted using variable value and table is created already) within FORALL..
Declare
TYPE dept_data_rec IS RECORD
(
Dept_no number,
Dept_name varchar2(100),
Dept_loc Varchar2(20)
);
TYPE nt_dept_data IS TABLE OF dept_data_rec ;
l_dept_data_nt nt_dept_data;
BEGIN
FORALL j IN 1..l_dept_data_nt.COUNT SAVE EXCEPTIONS
EXECUTE IMMEDIATE 'INSERT INTO '||l_get_dept_rec.dept_seq_no||'_Dept_Data VALUES '||
l_dept_data_nt(j);
COMMIT;
while compiling this code i am getting below error:
PLS-00306: wrong number or types of arguments in call to '||'
However when code using actual table name it works
FORALL j IN 1..l_dept_data_nt.COUNT SAVE EXCEPTIONS
INSERT INTO A1_dept_data VALUES
l_dept_data_nt(j);
COMMIT;
Oracle 10g -
In versions of Oracle prior to 11g, you can't use FORALL with EXECUTE IMMEDIATE, only with INSERT, UPDATE, or DELETE.
See http://docs.oracle.com/cd/B13789_01/appdev.101/b10807/13_elems021.htm
It's a special syntax
that reads like a FOR loop but isn't, and
is used by PL/SQL to perform bulked DML operations and only with the exact keyword, not with dynamic SQL or any other code.
Oracle 11g +
In 11g, the restriction on using EXECUTE IMMEDIATE was lifted. See http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/forall_statement.htm
However, the only variables allowed in the string are subscripted elements from a single array in the USING clause.
The documentation is unclear whether you can dynamically "change" the table per row using the FORALL syntax. Remember that the FORALL is used by PL/SQL to perform a bulk DML operation and that needs to go to one table for this to yield any performance benefit.
Best performance solution for the above problem
You should make two levels of arrays, the first defines which table and the second defines the data for that table.
Use an ordinary FOR loop over the table array and inside that loop use the special FORALL syntax to perform all the DML for the one table.
I want to create a update trigger,
can I create a variable betweent "BEGIN" and "END" , and set value by query from a select sql statement ??
And then execute "if" "else" statement by judging this variable
As an embedded database, SQLite is designed to be used directly from another programming language, so it does not have programming constructs like variables or IF statements.
If it is not possible to implement your logic with the trigger's WHEN clause or subqueries, you have to do this in Java (i.e., without a trigger).
There is the table OLD and a similar one, NEW. I want to insert in the existing process that fills the table OLD a trigger event that for each new inserted row, this event will insert the newly inserted row to table NEW, as well. Inside the body of trigger, i need to include the query BELOW which aggregates values of OLD before inserted in NEW:
insert into NEW
select (select a.id,a.name,a.address,b.jitter,a.packet,a.compo,b.rtd,a.dur from OLD a,
select address,packet,compo, avg(jitter) as jitter, avg(rtd) as rtd from OLD
group by address,packet,compo ) b
where a.address=b.address and a.packet=b.packet and a.compo=b.compo;
can you correct any possible mistakes or suggest other trigger syntax on the statement below?
CREATE OR REPLACE TRIGGER insertion
after update on OLD
for each row
begin
MY select query above
end;
In a for each row trigger you cannot query the table itself. You will get a mutating table error message if you do.
I recommend only to use triggers for the most basic functionality such as handing out ID numbers and very basic checks.
If you do use triggers for more complex tasks you may very easily end up with a system that's very hard to debug and maintain because of all kinds of actions that appear out of knowhere.
Look at this question for another approach: getting rid of Insert trigger
Oracle Streams might also be a good solution. In the apply handler, you can include your own custom PL/SQL code. This procedure will be called after the COMMIT, so you can avoid mutating table errors.
However, Streams requires a large amount of setup to make it work. It might be overkill for what you are doing.