Oracle Trigger Issue (Toad) - oracle11g

Oracle 11g/XE
Toad 12.7.1.11
I have a newly-installed db. Connected as SYS, created a user called 'jasons' with password and granted DBA. Disconnected and reconnected as 'jasons'. Then ran the following script:
CREATE SEQUENCE people_seq
MINVALUE 0
MAXVALUE 10000
START WITH 0
INCREMENT BY 1
CACHE 20;
commit;
create table people (PID number(10), FirstName varchar(20), LastName varchar(20));
commit;
alter table people add (constraint people_pk primary key (PID));
commit;
CREATE OR REPLACE TRIGGER people_trig
BEFORE INSERT ON people
FOR EACH ROW
BEGIN
SELECT people_seq.NEXTVAL
INTO :new.pid
FROM dual;
END;
commit;
When I run the script, everything goes well until the CREATE TRIGGER section. It throws:
ORA-04089: cannot create triggers on objects owned by SYS
I just created that very table as jasons! Can somebody please tell me what's going on?

Duh...
When making a new connection in Toad there's a nice little dropdown box in the middle of the right-hand side that says "Connect As" with your choice of Normal, SYSDBA, and SYSOPER.
It defaults to SYSDBA -- but when you select 'Normal'... Well... The above script works just fine ;-)

Related

MariaDB init_connect not working for one user

I have strange problem, im using 10.2.27 mariadb version .
created procedure for auditing user connections using init_connect parameter to call the procedure.
this procedure working for all the users except one user who is having REPLICATION CLIENT and table level privs and table is not getting updated with this user details where i can see the user connections in the processlist.
Please help me how to fix this issue a or any pointer are most appreciated
here is the procedure
DELIMITER //
CREATE PROCEDURE login_trigger()
SQL SECURITY DEFINER
BEGIN
INSERT INTO test.tracking (user, host, ts)
VALUES (SUBSTR(USER(), 1, instr(USER(), '#')-1), substr(USER(), instr(USER(), '#')+1), NOW())
ON DUPLICATE KEY UPDATE ts = NOW();
END;
//
DELIMITER ;
parameter set set from root user of the database
SET GLOBAL init_connect="CALL test.login_trigger()";

SQLite error: cannot start a transaction within a transaction with very basic tables

I am brand new to SQL, and I am learning on an SQLite editor. So I create a couple of very simple tables. This code is straight from Linkedin learning "SQL essential training", and I am using the recommended SQLite editor.
CREATE TABLE widgetInventory(
id INTEGER PRIMARY KEY,
description TEXT,
onhand INTEGER NOT NULL);
CREATE TABLE widgetSales(
id INTEGER PRIMARY KEY,
inv_id INTEGER,
quan INTEGER,
price INTEGER);
Then I update widgetInventory with some data:
INSERT INTO widgetInventory (description, onhand) VALUES ('rock', 25);
INSERT INTO widgetInventory (description, onhand) VALUES ('paper', 25);
INSERT INTO widgetInventory (description, onhand) VALUES ('scissors', 25);
Next, I want to update the widgetSales table with a sale, and update the widgetInventory table to record the reduction of onhand.
BEGIN TRANSACTION;
INSERT INTO widgetSales (inv_id, quan, price) VALUES (1,5,500);
UPDATE widgetInventory SET onhand = (onhand-5) WHERE id = 1;
END TRANSACTION;
I am not understanding why this gives me an error when I run it, as it is exactly as it is in the lesson.
[06:18:04] Error while executing SQL query on database 'test': cannot start a transaction within a transaction
But, I can run the INSERT and UPDATE lines separately, and they do what I want them to do.
Apparently, running - END TRANSACTION; - before running the entire transaction appears to work.
I think that somehow, SQL thinks that a transaction is already occurring. Though, I'm not sure where exactly. So to stop it, you have to end the transaction first before proceeding with the course.
In the SQLite Editor, you may have to delete or comment out all of the code before and after these two transactions.
BEGIN TRANSACTION;
INSERT INTO widgetSales ( inv_id, quan, price ) VALUES ( 1, 5, 500 );
UPDATE widgetInventory SET onhand = ( onhand - 5 ) WHERE id = 1;
END TRANSACTION;
BEGIN TRANSACTION;
INSERT INTO widgetInventory ( description, onhand ) VALUES ( 'toy', 25 );
ROLLBACK;
Otherwise it won't execute the transaction.
Other than that, there is probably an error written in somewhere. Copying and pasting in the .txt file didn't give me that transaction error and could execute the transaction normally.
Just had this same error and my issue was I only highlighted the first line so SQLLite started the transaction but didn't run it fully. All I did was run end transaction, highlight the whole block of code and run that and it worked fine. Must be some syntax issue in Lite that doesn't run the full block itself.
while executing SQL query on database 'test': cannot start a
transaction within a transaction
means a transaction already exists. It may happen if someone forgets to select the END TRANSACTION; statement.
If you face this issue just select END TRANSACTION once and run. With this it will end the active transaction and then you can run any of the existing transaction.
For the particular case of following the Linkedin learning "SQL essential training" course, I have figured out to fix it by running (f9) the "BEGIN TRANSACTION", "...TRANSACTION CONTENTS..." and "END TRANSACTION" statements separately, not all the statements at the same time.
So,
First select the "BEGIN TRANSACTION;" and run it by pressing f9.
Then select the contents of the transactions (I think you can include also the "END TRANSACTION;" part) and run it.

Trigger compiled successfully but still not firing as desired

Here is my simple PL/SQL code for demonstration purpose.
create table cust(cname varchar(10));
set SERVEROUTPUT ON;
create or replace trigger tgr
before insert on cust
for each row
enable
begin
dbms_output.put_line('Trigger hit on insert');
end;
/
insert into cust values('John');
OUTPUT:/
Table CUST created
Trigger TGR compiled
1 row inserted // *EXPECTING* Trigger hit on insert
You can't use DBMS_OUTPUT.PUT_LINE because when you insert data to your table, there is no prompt or screen which shows the execution of trigger. this applied same for procedures , functions , triggers.
Don't use commit inside a table. it will throw an exception. if you want to use commit then make the trigger pragma autonomous_transaction (i suggest not to use commit.it will automatically commit) .
Also make sure you don't modify the same table in the trigger. it will also throw and exception for mutating the data.
sample code
create table cust(cname varchar(10));
create table log(log varchar(10));
create or replace trigger tgr
before insert on cust
for each row
enable
begin
insert into log values('test');
end;
/
Don't use DBMS_OUTPUT.PUT_LINE inside a trigger to check if it was fired or not. Some of the IDEs like SQL developer might not output the message , even if you use SET SERVEROUTPUT ON.
However it could work on sqlplus . When i tried, it did display the message in sqlplus. So, it is not an issue with the database or your trigger.
SQL> insert into cust values('John');
Trigger hit on insert
And if you issue commit or rollback on the transaction, the messages might appear in sql developer.
I would suggest , it is better if you can create a log table and try to insert records into it rather than use dbms_output.
begin
INSERT INTO LOG_TABLE ( log_date,log_message) VALUES (SYSDATE,'Trigger hit on insert');
end;
/

How to write sqlite transaction that rolls back on any error

I have searched extensively on this and I have found a lot of people asking the question but no answers that included code examples to help me understand.
I'd like to write a transaction (in sql using the command line sqlite3 interface) that performs several update statements, and if any of them fail for any reason, rolls back the transaction. The default behaviour appears to be to roll-back the statement that failed but commit the others.
This tutorial appears to advise that it's sufficient to add begin; and rollback; before and after the statements, but that's not true because I've tried it with deliberate errors and the non-error statements were definitely committed (which I don't want).
This example really confuses me because the two interlocutors seem to give conflicting advice at the end - one says that you need to write error handling (without giving any examples) whereas the other says that no error handling is needed.
My MWE is as follows:
create table if not exists accounts (
id integer primary key not null,
balance decimal not null default 0
);
insert into accounts (id, balance) values (1,200),(2,300);
begin transaction;
update accounts set balance = field1 - 100 where id = 1;
update accounts set balance = field1 + 100 where id = 2;
update accounts set foo = 23; //Deliberate error
commit;
The idea is that none of these changes should be committed.
The sqlite3 command-line shell is intended to be used interactively, so it allows you to continue after an error.
To abort on the first error instead, use the -bail option:
sqlite3 -bail my.db < mwe.sql
If you are executing line by line, then the idea is that you first run these commands:
create table if not exists accounts (
id integer primary key not null,
balance decimal not null default 0
);
insert into accounts (id, balance) values (1,200),(2,300);
begin transaction;
update accounts set balance = field1 - 100 where id = 1;
update accounts set balance = field1 + 100 where id = 2;
update accounts set foo = 23; //Deliberate error
At this point, if you have no errors, you run the commit:
commit;
All the updates should be visible if you open a second connection and query the table.
On another hand if you got an error, instead of committing you rollback:
rollback;
All the updates should be rolled back;
If you are doing it programatically in java you would enclose the updates in a try - catch block, and commit at the end of the try, or rollback inside the catch.

Oracle Cursor for dropping users

I have a list of users that I need to drop from a schema. I created the table OWNERS_TO_REMOVE that has the names of the users that need to be dropped. I tried created the following cursor to drop the users, but it didn't work. Does it need a minor adjustment or do I need to drop the users in a completely different way?
DECLARE
CURSOR c_remove_owners IS
SELECT OWNER FROM OWNERS_TO_REMOVE;
v_owner OWNERS_TO_REMOVE.OWNER%TYPE;
BEGIN
OPEN c_remove_owners;
LOOP
FETCH c_remove_owners INTO v_owner;
EXIT WHEN c_remove_owners%NOTFOUND;
DROP USER v_owner CASCADE;
END LOOP;
CLOSE c_remove_owners;
END;
/

Resources