Creating table with limited number of rows - oracle11g

I would like to create table that have limited numbers of rows.
For example if we try insert data into that table where rownumber is bigger than 2.000, that return some error or something.
How to manage this?

An approach could be by creating a trigger to check the number of inserted rows; for example, say you have this table
create table notManyRows(n number)
and you want to limit the number of rows to 3, you can add a trigger like:
create or replace trigger notManyRowsTrg
after insert on notManyRows
declare
vCheck number;
begin
select count(*)
into vCheck
from notManyRows;
--
if vCheck > 3 then
raise_application_error(-20001, 'Too many rows in the table');
end if;
end;
How it works:
SQL> insert into notManyRows values (1);
1 row created.
SQL> insert into notManyRows values (1);
1 row created.
SQL> insert into notManyRows values (1);
1 row created.
SQL> insert into notManyRows values (1);
insert into notManyRows values (1)
*
ERROR at line 1:
ORA-20001: Too many rows in the table
ORA-06512: at "ALEK.NOTMANYROWSTRG", line 9
ORA-04088: error during execution of trigger 'ALEK.NOTMANYROWSTRG'
SQL>

Related

How to solve this issue in pl/sql

How to create a trigger which interdicts insertion of symbols and space in a certain column and after insertion just to have only the upper letters
for example:
insert into tale xxx values '"&$))(/-$:&##¥*|^]asjdj';
and the result should be the following:
ASJDJ
thank you
a lot of functions procedures trigger and nothing was right
Add a new column to the table and update that column extracting only the letters from the column with special characters.
Using your eg.
Add new column value in tale table. Right after inserting the xxx column do the updates like:
update tale set value = upper(regexp_substr(xxx,'[[:alpha:]]+'));
That would be a row-level trigger which fires both before insert or update on table so that value is modified in any case. There are various options which let you remove everything but letters; regular expression is simple enough.
Sample table:
SQL> create table test (col varchar2(40));
Table created.
Trigger:
SQL> create or replace trigger trg_biu_test
2 before insert or update on test
3 for each row
4 begin
5 :new.col := upper(regexp_replace(:new.col, '[^[:alpha:]]'));
6 end;
7 /
Trigger created.
Testing:
SQL> insert into test (col) values ('"&$))(/-$:&##¥*|^]asjdj');
1 row created.
SQL> select * from test;
COL
----------------------------------------
YASJDJ
SQL> update test set col = '25xyz';
1 row updated.
SQL> select * from test;
COL
----------------------------------------
XYZ
SQL>

How do I reset a sequence in Oracle APEX or fill my PK automatically without sequence and trigger, starting from number 1 every time i delete my data?

i have this table
TABLE "KEYWORD_RSLT"
( "ID" NUMBER PRIMARY KEY,
"SESSION_MONTH" VARCHAR2(40) NOT NULL ENABLE,
"PATIENT_NAME" VARCHAR2(50)
and i have this procedure that imports data to my table KEYWORD_RSLT.
create or replace PROCEDURE "PR_KEYWORD_SEARCH" (v_patient_id NUMBER, v_keyWord varchar2)
IS
BEGIN
delete from KEYWORD_RSLT;
insert into KEYWORD_RSLT (SESSION_MONTH, PATIENT_NAME)
select distinct
to_char(s.SESSION_DATE, 'MM-YYYY') as SESSION_MONTH,
p.FIRST_NAME ||' '||p.LAST_NAME as PATIENT_NAME
from SESSIONS s,
CLIENTS p
where s.CLIENTS_ID = p.ID
and (s.CRITICAL_POINT like LOWER ('%'||v_keyWord||'%') and s.CLIENTS_ID = v_patient_id
or s.ACTIONS like LOWER ('%'||v_keyWord||'%') and s.CLIENTS_ID = v_patient_id);
END PR_KEYWORD_SEARCH;
I want my primary key "ID" to take automatically the next available number starting from 1, but when my procedure deletes all data from this table, i want to start again from 1.
I tried with sequence ("SQ_KEYWORD_RSLT_INCREAMENT") and trigger but i can not reset this sequence from a new procedure using this code:
alter sequence SQ_KEYWORD_RSLT_INCREAMENT restart start with 1;
How can i fill my ID automatically from the beginning every time i delete all the data?
You say i can not reset this sequence but you don't say why so I'm assuming that you got an error. It is not possible to execute ddl statements in pl/sql directly, but it can be done using EXECUTE IMMEDIATE.
CREATE SEQUENCE koen_s START WITH 1;
Sequence KOEN_S created.
SELECT koen_s.NEXTVAL FROM DUAL;
NEXTVAL
----------
1
BEGIN
EXECUTE IMMEDIATE 'ALTER SEQUENCE koen_s RESTART START WITH 1';
END;
/
PL/SQL procedure successfully completed.
SELECT koen_s.NEXTVAL FROM DUAL;
NEXTVAL
----------
1

PL/SQL not functioning

Im currently trying to implement a row trigger that fires when the new Employee number inserted into the table is not continuous.
"Continuous" in a relationship to the Employee number means the first record inserted will have the Employee number 1, the second record will have the employee number 2, and each next position must have a number greater by one that a number of the previous position.
I have successfully created the trigger, however when I inserted a new record that have an Employee number that is not continuous, my trigger is not fired.
Im unsure where I went wrong and hope I can get some explanation and corrections on my code.
CREATE OR REPLACE TRIGGER CONTENUM
AFTER INSERT ON TRKEMPLOYEE
FOR EACH ROW
DECLARE
continuous_value EXCEPTION;
PRAGMA exception_init(continuous_value, -20111);
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF (:NEW.E# > :OLD.E# + 1) THEN
RAISE_APPLICATION_ERROR (-20111,'The value of Employee number must be continuous');
END IF;
END CONTENUM;
/
Here is the format of my sample TRKEMPLOYEE table
CREATE TABLE TRKEMPLOYEE(
E# NUMBER(12) NOT NULL,
NAME VARCHAR(50) NOT NULL,
DOB DATE ,
ADDRESS VARCHAR(300) NOT NULL,
HIREDATE DATE NOT NULL,
CONSTRAINT TRKEMPLOYEE_PKEY PRIMARY KEY(E#) );
Here is my insert statement.
Currently in my table TRKEMPLOYEE there is only 15 rows thus with my insert statement, the trigger should fire but it is not happening.
INSERT INTO TRKEMPLOYEE VALUES( 17, 'David', NULL, 'GB',sysdate );
Thank you.
First of all you are checking AFTER INSERT ON TRKEMPLOYEE which will be executed after the row is inserted.
Secondly, you cannot check :OLD.E# since you are not updating and you are not using a old value.
Also you should drop the trigger at all and use SEQUENCES and let Oracle take care of the auto-increment values every time you add a new employee.
If you want to continue with your current logic, fixes that can be applied:
Change AFTER INSERT ON TRKEMPLOYEE to BEFORE INSERT ON TRKEMPLOYEE
Logic should be changed as below:
CREATE OR REPLACE TRIGGER contenum BEFORE
INSERT ON trkemployee
FOR EACH ROW
DECLARE
continuous_value EXCEPTION;
PRAGMA exception_init ( continuous_value, -20111 );
PRAGMA autonomous_transaction;
max_e# INTEGER;
BEGIN
SELECT
nvl(MAX(e#), 0)
INTO max_e#
FROM
trkemployee;
IF ( :new.e# > max_e# + 1 ) THEN
raise_application_error(-20111, 'The value of Employee number must be continuous');
END IF;
END contenum;
/
I do not recommend this solution because it will start to become slower as your table starts to grow.

ORA-4088, ORA-6512 Using Triggers and RAISE_APPLICATION_ERROR

While trying to Enforce Foreign Key Integrity in Oracle with Trigger
CREATE OR REPLACE TRIGGER TRG_IU_SPONSORID_user_registration
BEFORE INSERT OR UPDATE OF U_SPONSORID ON user_registration
FOR EACH ROW
DECLARE l_SPONSORID VARCHAR2 (2000);
BEGIN
SELECT U_SPONSORID
Into l_SPONSORID
FROM U_SPONSOR WHERE U_SPONSORID = :NEW.U_SPONSORID;
If l_SPONSORID is null
THEN raise_application_error(-20010, 'Not a valid SPONSORID: '|| ':NEW.U_SPONSORID');
End if;
END;
I am getting the following errors, while raise error message is not printing
ORA-6512: at "BPORTD1.TRG_IU_SPONSOR_USER_REGISTRATION", line 3
ORA-4088: error during execution of trigger 'BPORTD1.TRG_IU_SPONSOR_USER_REGISTRATION'
​Any idea of why is this happening?
Code you wrote has 1.5 mistakes:
1st: if there's no such row in U_SPONSOR table, select won't return NULL as you thought, but no_data_found you should handle; I presume that's what happened to you
0.5th: remove single quotes from ':new.u_sponsorid' in dbms_output.put_line as you'll display literally that, not the ID value.
Sample tables and trigger:
SQL> create table u_sponsor (u_sponsorid number);
Table created.
SQL> create table user_registration(u_sponsorid number);
Table created.
SQL> create or replace trigger trg_iu_sponsor
2 before insert or update of u_sponsorid on user_registration
3 for each row
4 declare
5 l_sponsorid varchar2 (2000);
6 begin
7 select u_sponsorid
8 into l_sponsorid
9 from u_sponsor
10 where u_sponsorid = :new.u_sponsorid;
11 exception
12 when no_data_found then
13 raise_application_error(-20010,
14 'Not a valid SPONSORID: '|| :new.u_sponsorid);
15 end;
16 /
Trigger created.
Testing: master row first:
SQL> insert into u_sponsor values (200);
1 row created.
Two details:
SQL> insert into user_registration values (100);
insert into user_registration values (100)
*
ERROR at line 1:
ORA-20010: Not a valid SPONSORID: 100
ORA-06512: at "SCOTT.TRG_IU_SPONSOR", line 10
ORA-04088: error during execution of trigger 'SCOTT.TRG_IU_SPONSOR'
SQL> insert into user_registration values (200);
1 row created.
SQL>
However, I guess you used a trigger to enforce referential integrity just for educational purposes, because - if you want to do that properly, create a foreign key constraint. Something like this:
SQL> create table u_sponsor (u_sponsorid number primary key);
Table created.
SQL> create table user_registration(u_sponsorid number references u_sponsor);
Table created.
SQL> insert into u_sponsor values (200);
1 row created.
SQL> insert into user_registration values (100);
insert into user_registration values (100)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.SYS_C009854) violated - parent key not found
SQL> insert into user_registration values (200);
1 row created.
SQL>

Sequential Insertion of data using multiple procedure being called in sequence

I have a requirement where in I need to insert one row for customer and next for address and than all his account in a particular table.
For this I have written 3 procedure 1 calling 2 other in FOR LOOP.
While I am running it is running in sequence but when I check the data inserted. some of the rows of calling procedure are inserted before the called procedure are oveR. How to resolve the same?
CREATE OR REPLACE PROCEDURE XYG(REP_DATE IN custom.C_CIBILRPT_TBL.RPT_DATE%type)
AS
V_AS_COU NUMBER DEFAULT 1;
V_BS_COU NUMBER DEFAULT 1;
V_CS_TOT NUMBER DEFAULT 1;
V_BOD_DATE DATE;
V_LINE_DATA VARCHAR(300);
BEGIN
<<Getting Date into V_BOD_DATE using into statemet>>
--#### Truncating Temp Table
execute immediate 'Truncate table CUSTOM.C_CIBILRPT_TMP';
--#### Borrower Segment Generation Starts --####
FOR custid IN
( Fetching customer id
LOOP
<<Getting the data in V_LINE_DATA>>
INSERT
INTO C_CIBILRPT_TMP VALUES
(
REP_DATE,
V_BOD_DATE,
'XXX',
'BS',
V_BS_COU,
V_LINE_DATA,
custid.cifid
);
COMMIT;
V_BS_COU := V_BS_COU+1;
DBMS_OUTPUT.put_line (custid.cifid);
ADDRESS_SEG_BG (custid.cifid,v_as_cou,rep_date);
V_AS_COU := V_AS_COU+1;
CREDIT_SEG_BG(custid.cifid,rep_date);
END LOOP;
END XYG;

Resources