Limit number of Rows inserted into a Table - sql

How can we restrict a table to have fixed number of rows?
for example if i give Limit as 20, then 20 rows can be inserted into it and after that table should indicate the limit has been exceeded.
EXAMPLE: IF we create a trigger
CREATE TRIGGER log AFTER INSERT ON TEST_TABLE
BEGIN
INSERT INTO TEST_TABLE VALUES(....);
SELECT COUNT(COL) FROM TEST_TABLE;
END;
This is not giving me the count as soon as i enter a row into the table.

Create a Trigger before Insert on That table.
In Trigger you can check for count for records that same table has.
Check this link for Creating Trigger.

Related

Auto-increment in Oracle table when insert in the same table

I have a table and I want to increment a column by 1 when I insert a row into the same table.
Table users - when I insert first row value of idusers is 1, and in second row value is 2 ....
This is the table
USERS
EMAIL primary key
USERNAME
PASSWORD
IDUSER and this the column I want to be AUTO_INCREMENT
I have tried this code
CREATE SEQUENCE seq_person
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10;
create or replace trigger incrementIdUser
before insert on users
for each row
begin
select seq_person.nextval into :new.IDUSER from users;
end;
But I get an error when I insert a row:
Erreur lors de l'enregistrement des modifications de la table "SOCIAL"."USERS" :
Ligne 1 : ORA-01403: no data found
ORA-01403: no data found
ORA-06512: at "SOCIAL.INCREMENTIDUSER", line 2
ORA-04088: error during execution of trigger 'SOCIAL.INCREMENTIDUSER'
ORA-06512: at line 1
Not like that, but
create or replace trigger incrementIdUser
before insert on users
for each row
begin
:new.iduser := seq_person.nextval;
end;
Code you wrote selects from users table (which is empty, hence NO_DATA_FOUND). If it contained more than a single row, you'd get TOO_MANY_ROWS (as you're selecting into a scalar variable (:new.iduser). Finally, there's danger of mutating table error as you can't select from a table which is just being modified (in this trigger type).
Insetead of select seq_person.nextval into :new.IDUSER from users; to assign sequence value into iduser you need to use :new.IDUSER :=seq_person.nextval;
create or replace trigger incrementIdUser
before insert on users
for each row
begin
:new.IDUSER :=seq_person.nextval;
end;
You get that error because there are zero rows in the USERS table so SELECT ... FROM USERS returns no rows.
What you want is to either use a table that will always return a single row (which, in Oracle, is the DUAL table):
create or replace trigger incrementIdUser
before insert on users
for each row
begin
select seq_person.nextval into :new.IDUSER from DUAL;
end;
Or, the better solution, is to not use an SQL statement and use pure PL/SQL:
create or replace trigger incrementIdUser
before insert on users
for each row
begin
:new.IDUSER := seq_person.nextval;
end;
Instead of using a trigger, you should use an identity column in the create table statement:
create table users
(iduser integer generated by default on null as identity (nomaxvalue nocache order),
...);

Get table does not exist error, when trying to insert into table from a trigger

I'm attempting to use a trigger to fill values of another table. The trigger watches for insert on table ratings and updates the values of another table, top5restaurants. I haven't figured out how to maintain only the top 5 in top5restaurants, I don't know how to limit a table to a certain number of entries. But right now I can't seem to do anything to top5restaurants from within the trigger.
drop view top_rest;
create view top_rest (rid, rat)
as
(select distinct rid, max(stars)
from rating
group by rid);
drop table top5restaurants;
create table top5restaurants(rid int);
insert into top5restaurants(rid)
select rid from top_rest
where rownum <= 5
order by rat asc;
create or replace trigger top5_trigger
after insert on ratings
for each row
declare top5 top5restaurants%rowtype;
cursor top5_cursor is
select rid from top_rest
where rownum <=5
order by rat;
begin
for record in top5_cursor
loop
fetch top5_cursor into top5;
insert into top5restaurants values(top5);
end loop;
end;
/
--
--
begin
update_reviews('Jade Court','Sarah M.', 4, '08/17/2017');
update_reviews('Shanghai Terrace','Cameron J.', 5, '08/17/2017');
update_reviews('Rangoli','Vivek T.',3,'09/17/2017');
update_reviews('Shanghai Inn','Audrey M.',2,'07/08/2017');
update_reviews('Cumin','Cameron J.', 2, '09/17/2017');
end;
/
select * from top5restaurants;
insert into top5restaurants values(184);
However, the table does exist and I can run queries on it and it returns the data I inserted when I created the table. I can also insert values. Not sure why I get table not found error when using a trigger.
Apart from the difference in table names(answer by Littlefoot) in the trigger and view, You have not used the rowtype collection properly while inserting the data.
you must remove the brackets:
replace
insert into top5restaurants values(top5);
with
insert into top5restaurants values top5;
Cheers!!
You didn't post all tables involved, but - what is obvious, is that view is created as
create view top_rest ... from rating
------
while trigger is created as
after insert on ratings
-------
^
s?
Which one is it? rating or ratings?

SQL Server: If a row is inserted in one table, how do I write a trigger to insert that same row in a different table?

I'm not sure how to create this trigger,.I need to add a row in pub_info table when a row is inserted in publishers table. The exact same row. SQL server
CREATE TRIGGER checkCity
ON pub_info
AFTER INSERT
AS
IF -- a row is inserted into publishers table,
-- how do I add the same row into pub_info table?
INSERT VALUES(#pub_id, NULL, 'new publishers')
BEGIN
END;
You have to create a trigger on publishers table and not on pub_info .
The inserted data is available in the INSERTED table in the trigger
CREATE TRIGGER checkCity
ON publishers
AFTER INSERT
AS
BEGIN
INSERT INTO pub_info(pubid, pubname, pub_description)
SELECT pubid, pubname, pub_description
FROM INSERTED;
END;

Values of the inserted row in a Trigger Oracle

I want a trigger that updates the value of a column, but I just want to update a small set of rows that depends of the values of the inserted row.
My trigger is:
CREATE OR REPLACE TRIGGER example
AFTER INSERT ON table1
FOR EACH ROW
BEGIN
UPDATE table1 t
SET column2 = 3
WHERE t.column1 = :new.column1;
END;
/
But as I using FOR EACH ROW I have a problem when I try it, I get the mutating table runtime error.
Other option is not to set the FOR EACH ROW, but if I do this, I dont know the inserted "column1" for comparing (or I dont know how to known it).
What can I do for UPDATING a set of rows that depends of the last inserted row?
I am using Oracle 9.
You should avoid the DML statements on the same table as defined in a trigger. Use before DML to change values of the current table.
create or replace trigger example
before insert on table1
for each row
begin
:new.column2 := 3;
end;
/
You can modify the same table with pragma autonomous_transaction:
create or replace trigger example
after insert on table1 for each row
declare
procedure setValues(key number) is
pragma autonomous_transaction;
begin
update table1 t
set column2 = 3
where t.column1 = key
;
end setValues;
begin
setValues(:new.column1);
end;
/
But I suggest you follow #GordonLinoff answere to your question - it's a bad idea to modify the same table in the trigger body.
See also here
If you need to update multiple rows in table1 when you are updating one row, then you would seem to have a problem with the data model.
This need suggests that you need a separate table with one row per column1. You can then fetch the value in that table using join. The trigger will then be updating another table, so there will be no mutation problem.
`create table A
(
a INTEGER,
b CHAR(10)
);
create table B
(
b CHAR (10),
d INTEGER
);
create trigger trig1
AFTER INSERT ON A
REFERENCING NEW AS newROW
FOR EACH ROW
when(newROW.a<=10)
BEGIN
INSERT into B values(:newROW.b,:newROW.a);
END trig1;
insert into A values(11,'Gananjay');
insert into A values(5,'Hritik');
select * from A;
select * from B;`

Oracle trigger insert other table

I have 2 tables which are my_school and my_class
And "my_school" table has 'info_id' column and also "my_class" table has 'info_id' then I want to get a query that automatically generate "info_id" then I found solution..
Here are my working TRIGGER on "my_school" table...
CREATE OR REPLACE TRIGGER info_id
before insert on my_direction
for each row
begin
if :NEW.WAY_ID is null then
:NEW.WAY_ID := example_id_seq.nextval;
end if;
end;
It works and it's generating auto id when inserting value.
But now how to get this trigger do it on "my_class" table when users insert value on my_school's table then take id with "my_class" table's "info_id" column same time?
You can create trigger on my_school table to update info_id similar to that you have explained and while inserting records, use returning into clause.
Declare a variable to store returned value, for example
v_info_id number(9);
And use it in returning into clause
insert into my_school(column.......list)
values (values........list)
RETURNING info_id INTO v_info_id;
Use v_info_id in your program to insert value of info_id into another tables.