Oracle Apex 5: Procedure not working for counter? - plsql

I'm trying to create a page counter. everytime someone enters a page a procedure is executed. 1 is added to the column check_count. Unfortunately Oracle Apex 5 is saying
ORA-24344: success with compilation error.
Why do you think that is?
CREATE OR REPLACE PROCEDURE check_counter(person IN varchar2) IS
count pageTable.check_count%type;
countTwo pageTable.check_count%type;
BEGIN
SELECT check_count INTO count FROM pageTable
WHERE person = pageTable.person_name;
countTwo := count + 1;
INSERT INTO pageTable (check_count)
VALUES(countTwo);
END;

Related

PLSQL Return Sequence.currval When Sequence Name Is Built Using Substitution Strings

I would like to use the same application in different instances so I need to specify the workspace and sequence ID.
Example query
BEGIN
INSERT INTO STEP (STEP_CHART_TITLE)
VALUES ('Action', 'Action');
RETURN '"'||:v_workspace||'"."'||:v_seqid||'".currval';
END;
If I use:
"FREEADMIN"."ISEQ$$_111997".currval;
in the return statement it works fine.
If I use the substitution strings, it will build the string correctly, but won't return the sequence number.
Is there a way to get the sequence number?
Thanks
"PL/SQL" as Oracle's procedural extension to SQL? Asking because I don't quite understand what "workspace" represents (we call it a "user" or a "schema" or even "owner" in Oracle).
If so, then you can't fetch current value unless you first fetch next sequence value (you didn't post whole code you use so I'm not sure whether you did that or not; also, insert statement is wrong - you're inserting 2 values into a single column).
SQL> select seq.currval from dual;
select seq.currval from dual
*
ERROR at line 1:
ORA-08002: sequence SEQ.CURRVAL is not yet defined in this session
SQL> select seq.nextval from dual;
NEXTVAL
----------
6
SQL> select seq.currval from dual;
CURRVAL
----------
6
SQL>
Therefore, the whole code might look like this - you'd use dynamic SQL. As this is SQL*Plus, I'm using substitution variables; you'd use bind variables (i.e. :v_workspace instead of '&v_workspace') (if that's what you're doing). This code just displays the value - you'd return it.
SQL> create table step (id number, step_chart_title varchar2(10));
Table created.
SQL> declare
2 l_str varchar2(200);
3 l_id number;
4 begin
5 l_str := 'select ' || '&v_workspace' ||'.'|| '&v_seqid' ||'.nextval from dual';
6 execute immediate l_str into l_id;
7
8 insert into step (id, step_chart_title) values (l_id, 'Action');
9
10 dbms_output.put_line(l_id); --> L_ID now contains CURRVAL
11 end;
12 /
Enter value for v_workspace: scott
Enter value for v_seqid: seq
8 --> here it is
PL/SQL procedure successfully completed.
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

Passing parameter to PL/SQL procedure using select from database

Is it possible to define a variable as current_scn:= 'select current_scn from V$database' in the declaration section of a procedure. Using the one below gives me the output. But I would like to define it in the declare section, so each time it gets executed it will get the current scn. Need to execute the procedure based on the input. Is it possible do so?
DECLARE
currnet_scn VARCHAR2(500);
BEGIN
EXECUTE IMMEDIATE 'select current_scn from V$database' INTO currnet_scn;
DBMS_OUTPUT.PUT_LINE(currnet_scn);
END;
No, you can't do it exactly as you wanted (if you could, you'd already do it, I presume).
But, you can create a function which can then be used in declare section. See how:
SQL> create or replace function f_scn
2 return number
3 is
4 retval number;
5 begin
6 select current_scn into retval from V$database;
7 return retval;
8 end;
9 /
Function created.
SQL> set serveroutput on
SQL> declare
2 current_scn number := f_scn; --> function is used here
3 begin
4 dbms_output.put_line('SCN = ' || current_scn);
5 end;
6 /
SCN = 16535194799153
PL/SQL procedure successfully completed.
SQL>
Though, now you don't need to declare anything at all:
SQL> begin
2 dbms_output.put_line('SCN = ' || f_scn);
3 end;
4 /
SCN = 16535194799171
PL/SQL procedure successfully completed.
SQL>
Your example uses dynamic SQL. Why? There's nothing dynamic in it, which means that
select current_Scn into current_scn from v$database;
works just fine.
Finally: don't name variables as column names; it causes confusion. I'd suggest to make it e.g. declare v_current_scn number;

PLSQL: How to insert data in GTT using view inside an SP

I am trying to insert data in a temp table(my_temp_table) using View(VWBLKDATA) as follows but getting compilation error "Error(7,15): PL/SQL: ORA-00942: table or view does not exist". However i am able to successfully execute view separately.
create or replace PROCEDURE InsrtInTemp
AS
BEGIN
INSERT INTO my_temp_table SELECT * FROM VWBLKDATA;
COMMIT;
END InsrtInTemp;
But when i am writing dynamic query as below, it compiles successfully
create or replace PROCEDURE InsrtInTemp
AS
intrtmp VARCHAR2(200);
BEGIN
intrtmp := 'INSERT INTO my_temp_table SELECT * FROM VWBLKDATA';
EXECUTE IMMEDIATE intrtmp;
END InsrtInTemp;
Please help me understanding this behavior.

PL/SQL Execute immediate create table and insert data into it

Let's have a look on my source code:
CREATE OR REPLACE PROCEDURE MAKE_COPY_OF_CLASSROOMS AUTHID CURRENT_USER AS
TYPE classrooms_table_type IS TABLE OF classrooms%ROWTYPE INDEX BY PLS_INTEGER;
classrooms_backup classrooms_table_type;
CURSOR classrooms_cursor IS
SELECT *
FROM classrooms
WHERE year = 1
ORDER BY name;
v_rowcnt PLS_INTEGER := 0;
BEGIN
OPEN classrooms_cursor;
FETCH classrooms_cursor
BULK COLLECT INTO classrooms_backup;
CLOSE classrooms_cursor;
EXECUTE IMMEDIATE 'CREATE TABLE classrooms_copy AS (SELECT * FROM classrooms WHERE 1 = 2)';
--COPY ALL STORED DATA FROM classrooms_backup TO classrooms_copy
END MAKE_COPY_OF_classrooms;
I'm stucked for hours on trying to insert data from "classrooms_backup" into the table "classrooms_copy", which is created by EXECUTE IMMEDIATE command. It's necessary to create table "classrooms_copy" via EXECUTE IMMEDIATE command. I tried to create another EXECUTE command with for loop in it:
EXECUTE IMMEDIATE 'FOR i IN classrooms_backup.FIRST..classrooms_backup.LAST LOOP
INSERT INTO classrooms_copy(id,room_id,year,name)
VALUES(classrooms_backup(i).id,classrooms_backup(i).room_id,classrooms_backup(i).year,classrooms_backup(i).name);
END LOOP;';
But it's road to the hell. I'm retrieving an invalid SQL statement error.
Thanks for your help!
There's no need for much PL/SQL here. Also, try to avoid the keyword CURSOR - there's almost always a better way to do it.
create or replace procedure make_copy_of_classrooms authid current_user as
begin
execute immediate '
create table classrooms_copy as
select *
from classrooms
where year = 1
order by name
';
end make_copy_of_classrooms;
/

Resources