Sequential Insertion of data using multiple procedure being called in sequence - plsql

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;

Related

MariaDB Stored Procedure store paramters for update

I am trying to write a MariaDB stored procedure.
Due to SQL_SAFE_UPDATES, it is required to use the ID column to use in the WHERE clause for updates. Due to this, what is the normal approach to also select a value from one of the other columns? I do not want to have multiple SELECT statements as it seems inefficient and room for error because they could return values from different rows.
I would like to store my first select statement
SELECT id, sequence FROM RECORDSEQUENCE WHERE SEQTABLE = SeqTable;
In the following two parameters #id, #seq from two seperate columns in the above query and use them in the UPDATE statement as well as the IF statement.
CREATE DEFINER=`sd`#`%` PROCEDURE `SD_GenerateNextRecordSequence`(IN SeqTable int)
BEGIN
SELECT id, sequence FROM RECORDSEQUENCE WHERE SEQTABLE = SeqTable;
IF (#seq IS NOT NULL) THEN
SET #NEXTSEQ := #seq+1;
UPDATE RECORDSEQUENCE SET RECORDSEQUENCE = #NEXTSEQ WHERE id = #id;
ELSE
SET #NEXTSEQ := 100;
INSERT INTO RECORDSEQUENCE (RECORDSEQUENCE,SEQTABLE) VALUES (#NEXTSEQ,SeqTable);
END IF;
SELECT #NEXTSEQ as SEQUENCE;
END

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

Creating a Database Trigger that checks if more than one record was added on a date?

CREATE OR REPLACE TRIGGER POSITION_NUMBER
BEFORE UPDATE OR INSERT OR DELETE ON APPLIES
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
NUMBER_OF_POSITIONS NUMBER;
BEGIN
SELECT count(pnumber) INTO NUMBER_OF_POSITIONS
FROM APPLIES WHERE anumber = :NEW.anumber;
IF( NUMBER_OF_POSITIONS > 2 AND count(APPDATE) > 2 )
THEN
RAISE_APPLICATION_ERROR(-20000,'an Employee cannot apply for
more than two positions');
END IF;
END;
/
Im attemtping to create a trigger that goes off if an Applicant applys for more than two Positions on the Same Day, but im not sure how i would implement the Date side of it. Below is the set of relational Schemeas
You can use the TRUNC function to remove the time portion and then see if the application date matches today's date, regardless of time.
Also, there is no need for the autonomous transaction pragma. You are not executing any DML.
CREATE OR REPLACE TRIGGER position_number
BEFORE UPDATE OR INSERT OR DELETE
ON applies
DECLARE
number_of_positions NUMBER;
BEGIN
SELECT COUNT (pnumber)
INTO number_of_positions
FROM applies
WHERE anumber = :new.anumber AND TRUNC (appdate) = TRUNC (SYSDATE);
IF number_of_positions > 2
THEN
raise_application_error (
-20000,
'An Employee cannot apply for more than two positions on the same day');
END IF;
END;
/

Return multiple rows in a plqsl stored procedure in output parameters

I have to write a PL/SQL stored procedure to extract all rows from a selected table in a database
I have tried something like this:
create or replace PROCEDURE ANAGRAFICA_GET (
ID_O OUT NUMBER
NOME_O OUT VARCHAR2(25),
COGNOME_O OUT VARCHAR2(25),
DATA_NASCITA_O OUT VARCHAR2(25),
CITTA_NASCITA_O VARCHAR2(25),
GENERE_O OUT VARCHAR2(25),
OCCUPAZIONE_O OUT VARCHAR2(25)
)
AS
CURSOR RESULTS IS
SELECT ID,NOME,COGNOME,DATA_NASCITA,CITTA_NASCITA,GENERE,OCCUPAZIONE
FROM TAB_ANAGRAFICA;
ESTRAZIONE TAB_ANAGRAFICA%ROWTYPE;
LAST_ID INT;
FIRST_ID INT;
BEGIN
SELECT ID
INTO LAST_ID
FROM TAB_ANAGRAFICA
WHERE ROWNUM <=1
ORDER BY ID DESC;
SELECT ID
INTO FIRST_ID
FROM TAB_ANAGRAFICA
WHERE ROWNUM <=1
ORDER BY ID ASC;
OPEN RESULTS;
FOR i IN FIRST_ID .. LAST_ID LOOP
FETCH RESULTS INTO ESTRAZIONE;
ID_O := ESTRAZIONE.ID;
NOME_O := ESTRAZIONE.NOME;
COGNOME_O := ESTRAZIONE.COGNOME;
DATA_NASCITA_O := ESTRAZIONE.DATA_NASCITA;
CITTA_NASCITA_O := ESTRAZIONE.CITTA_NASCITA;
GENERE_O := ESTRAZIONE.GENERE;
OCCUPAZIONE_O := ESTRAZIONE.OCCUPAZIONE;
END LOOP;
CLOSE RESULTS;
END;
But when i run the stored procedure i just can see the last row in the output variables; instead if i try to write a dbms_outputline command in the loop when i run the procedure i can see that is able to fetch all the data.
How can i solve this problem ? How can i obtain a resulset instead of a single record in the output variables section ?
Thanks to all
Marco
The stored procedure only gives the parameters marked as out in the declaration. What you are effectively doing is opening the cursor, looping through it, assigning to these parameters each time but only when the stored procedure has ended are these parameters passed out.
What you'd want to do is to just put the cursor as a paremeter:
create or replace PROCEDURE ANAGRAFICA_GET (
PASSED_CURSOR OUT SYS_REFCURSOR,
) AS
BEGIN
OPEN PASSED_CURSOR FOR
SELECT X, Y, Z FROM EXAMPLE_TABLE;
END

How to place a plsql block inside a sequence

I am trying to create a user generated sequence. According to usual syntax of oracle sequence we can start with a number and increment a value.
Is there a method to write a plsql block (declare begin end) inside a sequence and generate my own sequnce.
example : ABC001
When i call the next val of sequence , the value should be ABC002
PLEASE CLEAR FIRST WHAT YOU EXACTLY WANT TO ASK.
If you are asking HOW TO DYNAMICALLY CREATE SEQUENCE USING PL/SQL, then check below.
Simplest way.
DECLARE
SQL_S VARCHAR2(100);
BEGIN
SQL_S := 'CREATE SEQUENCE SQN_NAME INCREMENT BY 1 START WITH 1';
EXECUTE IMMEDIATE SQL_S;
END;
/
If you want to dynamically create sequence with some DYNAMIC name as argument passed to procedure, then it will be like
CREATE OR REPLACE PROCEDURE DYNAMIC_SQN (ARG IN VARCHAR2) IS
SQL_S VARCHAR2(100);
PARAM1 VARCHAR2(20);
BEGIN
PARAM1 := 'SQN_NAME_' || ARG;
SQL_S := 'CREATE SEQUENCE ' || PARAM1 || ' INCREMENT BY 1 START WITH 1';
EXECUTE IMMEDIATE SQL_S;
END;
/
And if you simply want to insert in to any column, and create the PK using it in addition to some String, then
INSERT INTO TABLE_T VALUES('ABC'|| SEQUENCE_NAME.nextval, OTHER_VALUES);
It will still give you values like : ABC1, ABC2, .... ABC12, ABC13, .... ABC99, ABC100 and so on...
Considering the sample example you have given i m writing the following code
create your sequence, then
insert into seq values('ABC'||YOURSEQUENCENAME.nextval,YOUR_VALUE);

Resources