Oracle pl/sql script which increments number - oracle

Looking for a way to create an Oracle script using the equivalent of java ++ syntax to increment a variable.
Ie:
int id=10
DELETE MYTABLE;
INSERT INTO MYTABLE(ID, VALUE) VALUES (id++, 'a value');
INSERT INTO MYTABLE(ID, VALUE) VALUES (id++, 'another value');
...
Trying to use a variable and not a sequence so I can rerun this multiple times with the same results.

PL/SQL doesn't have the ++ syntactic sugar. You'd need to explicitly change the value of the variable.
DECLARE
id integer := 10;
BEGIN
DELETE FROM myTable;
INSERT INTO myTable( id, value ) VALUES( id, 'a value' );
id := id + 1;
INSERT INTO myTable( id, value ) VALUES( id, 'another value' );
id := id + 1;
...
END;
At that point, and since you want to ensure consistency, you may be better off hard-coding the id values just like you are hard-coding the value values, i.e.
BEGIN
DELETE FROM myTable;
INSERT INTO myTable( id, value ) VALUES( 10, 'a value' );
INSERT INTO myTable( id, value ) VALUES( 11, 'another value' );
...
END;

You can create a SEQUENCE to increment a number.
----CREATING SEQUENCE:
SQL> create sequence seq_name
2 start with 1
3 increment by 1
4 NOCACHE
5 NOCYCLE
6 ;
Sequence created.
----EXECUTION:
SQL> select seq_name.nextval from dual;
NEXTVAL
1
SQL> select seq_name.nextval from dual;
NEXTVAL
2
Also you can create a function that can be called anywhere:
----CREATING FUNCTION:
create or replace function sequence_func(a_number IN Number)
RETURN Number
AS
id Number;
Begin
select seq_name.nextval into id from dual;
Return id;
end;
/
Function created.
----EXECUTION:
SQL> select sequence_func(1) seq from dual;
seq
1
P.S :
startwith and increment by values below can be set as per your requirement.

Related

fetching table data into a table using cursor

I have a table called phonebook and it has two columns (firstName, LastName). I want to create a table of lastName index by firstName using cursor, and I wrote this code:
CREATE OR REPLACE PROCEDURE proc1 AS
TYPE tableNames IS TABLE OF VARCHAR2(20) INDEX BY VARCHAR(20);
v1 tableNames;
v_firstName PHONEBOOK.FIRSTNAME%TYPE;
v_lastName PHONEBOOK.LASTNAME%TYPE;
CURSOR c_name IS SELECT FIRSTNAME, LASTNAME FROM PHONEBOOK;
BEGIN
OPEN c_name;
LOOP
FETCH c_name INTO v_firstName, v_lastName;
EXIT WHEN c_name%NOTFOUND;
v1(v_firstName) := v_lastName;
END LOOP;
FOR idx IN v1.FIRST..v1.LAST
LOOP
DBMS_OUTPUT.PUT_LINE (v1(idx));
END LOOP;
CLOSE c_name;
END;
/
It has been successfully compiled. When I run this procedure it should print lastNames which stored in the tableNames but it gave me an error:
ORA-06502 "PL/SQL: numeric or value error"
Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
Please help me to solve this problem
Not FOR, but WHILE. Also, I used cursor FOR loop as a source; easier to write & maintain.
SQL> create table phonebook (firstname varchar2(10), lastname varchar2(10));
Table created.
SQL> insert into phonebook
2 select 'Little', 'Foot' from dual union all
3 select 'Mc' , 'Donalds' from dual;
2 rows created.
SQL> create or replace procedure proc1 as
2 type tablenames is table of varchar2(10) index by varchar2(10);
3 v1 tablenames;
4 idx varchar2(10);
5 begin
6 for cur_r in (select firstname, lastname
7 from phonebook
8 )
9 loop
10 v1(cur_r.firstname) := cur_r.lastname;
11 end loop;
12
13 idx := v1.first;
14 while idx is not null loop
15 dbms_output.put_line(v1(idx));
16 idx := v1.next(idx);
17 end loop;
18 end;
19 /
Procedure created.
SQL> exec proc1;
Foot
Donalds
PL/SQL procedure successfully completed.
SQL>

ORA-00928: missing SELECT keyword

In MYTABLE there are courses and their predecessor courses.
What I am trying to is to find the courses to be taken after the specified course. I am getting missing SELECT keyword error. Why I am getting this error although I have SELECT statement in FOR statement ? Where am I doing wrong ?
DECLARE
coursename varchar2(200) := 'COURSE_101';
str varchar2(200);
BEGIN
WITH DATA AS
(select (select course_name
from MYTABLE
WHERE predecessors like ('''%' || coursename||'%''')
) str
from dual
)
FOR cursor1 IN (SELECT str FROM DATA)
LOOP
DBMS_OUTPUT.PUT_LINE(cursor1);
END LOOP;
end;
Unless I'm wrong, WITH factoring clause can't be used that way; you'll have to use it as an inline view, such as this:
declare
coursename varchar2(200) := 'COURSE_101';
str varchar2(200);
begin
for cursor1 in (select str
from (select (select course_name
from mytable
where predecessors like '''%' || coursename||'%'''
) str
from dual
)
)
loop
dbms_output.put_line(cursor1.str);
end loop;
end;
/
Apart from the fact that it doesn't work (wrong LIKE condition), you OVERcomplicated it. This is how it, actually, does something:
SQL> create table mytable(course_name varchar2(20),
2 predecessors varchar2(20));
Table created.
SQL> insert into mytable values ('COURSE_101', 'COURSE_101');
1 row created.
SQL>
SQL> declare
2 coursename varchar2(20) := 'COURSE_101';
3 begin
4 for cursor1 in (select course_name str
5 from mytable
6 where predecessors like '%' || coursename || '%'
7 )
8 loop
9 dbms_output.put_line(cursor1.str);
10 end loop;
11 end;
12 /
COURSE_101
PL/SQL procedure successfully completed.
SQL>
Also, is that WHERE clause correct? PREDECESSORS LIKE COURSENAME? I'm not saying that it is wrong, just looks somewhat strange.
To extend #Littlefoot's answer a bit: you can use a common table expression (WITH clause) in your cursor, but the WITH must be part of the cursor SELECT statement, not separate from it:
DECLARE
coursename varchar2(200) := 'COURSE_101';
BEGIN
FOR aRow IN (WITH DATA AS (select course_name AS str
from MYTABLE
WHERE predecessors like '''%' || coursename||'%''')
SELECT str FROM DATA)
LOOP
DBMS_OUTPUT.PUT_LINE(aRow.str);
END LOOP;
END;
Also note that the iteration variable in a cursor FOR-loop represents a row returned by the cursor's SELECT statement, so if you want to display whatever was returned by the cursor you must use dotted-variable notation (e.g. aRow.str) to extract fields from the row.
Best of luck.
CREATE TABLE product
(
PRODUCT_ID int Primary key,
NAME VARCHAR (20) not null,
Batchno int not null,
Rate int not null,
Tax int not null,
Expiredate date not null
);
INSERT INTO PRODUCT VALUSES(1 , 'vasocare', 32 , 15 , 2 , 01-JAN-2021);

Update ID if Sequence MAX_VALUE reached

I am using the following TRIGGER to Insert in my TEST Table:
create or replace
TRIGGER TRG_CYCLE
BEFORE INSERT ON TEST_CYCLE
FOR EACH ROW
BEGIN
IF :NEW.LOGID IS NULL
THEN SELECT SEQ_CYCLE.nextval INTO :NEW.LOGID from dual;
END IF;
END;
SEQ_CYCLE is the Sequence. Now I have to use the CYCLE option in order to start with 1 after the MAX_VALUE is reached. Since I don't want duplicate LOGIDs I want to do an UPDATE if the LOGID exists, if not an INSERT. Can I do this inside the Trigger?
If I understand well, you may need an INSTEAD OF trigger; to build such a trigger you need to create a VIEW over your table and build the trigger on this view.
For example, say you have:
create sequence SEQ_CYCLE maxValue 3 cycle nocache;
create table TEST_CYCLE ( logId number, someColumn varchar2(20));
You can create a view and a trigger over the view:
create or replace view v_test_cycle as select * from test_cycle;
create or replace trigger trgCycle
instead of insert on v_test_cycle
for each row
declare
vCheck number;
vSeqVal number := SEQ_CYCLE.nextVal;
begin
select count(*)
into vCheck
from v_test_cycle
where logId = vSeqVal;
--
if vCheck = 0 then
insert into test_cycle(logId, someColumn) values ( vSeqVal, :NEW.someColumn);
else
update test_cycle
set someColumn = :NEW.someColumn
where logId = vSeqVal;
end if;
end;
If you do the INSERTs on the view, this is what you get:
SQL> select * from test_cycle;
no rows selected
SQL> insert into v_test_cycle(someColumn) values('some value 1');
1 row created.
SQL> insert into v_test_cycle(someColumn) values('some value 2');
1 row created.
SQL> insert into v_test_cycle(someColumn) values('some value 3');
1 row created.
SQL> insert into v_test_cycle(someColumn) values('some value 4');
1 row created.
SQL> insert into v_test_cycle(someColumn) values('some value 5');
1 row created.
SQL> select * from test_cycle;
LOGID SOMECOLUMN
---------- --------------------
1 some value 4
2 some value 5
3 some value 3
SQL>

Oracle: Create a function that returns a set of values?

I have a table of keywords
select * from keywords;
id kw
-- --
1 foo
1 bar
2 foo
and a query that will select rows from a master table based on those keywords.
select id, stuff from assets
where id in (select unique id from keywords where kw = 'foo');
id stuff
-- -----
1 ...
2 ...
How can I turn the subquery into a function? i.e. I would like a function to return a set of values that can be used by an IN clause.
select id, stuff from assets
where id in HAS_KEYWORD('foo');
Table names differ a bit but the solution works
create table tab (
key number,
val number
);
create table foe(
col1 number,
col2 varchar2(3)
);
insert into tab values (0,3);
insert into tab values (1,4);
insert into tab values (2,5);
insert into foe values (3,'YES');
insert into foe values (4,'YES');
insert into foe values (5,'NO');
create type t_return is table of number;
/
create or replace function fnc(str varchar2)
return t_return pipelined is
begin
for rec in (select col1 from foe where col2 = str) loop
pipe row(rec.col1);
end loop;
end;
/
select * from tab where val in (select * from table(fnc('YES')))

How to write a Procedure with multiple operations like select and update

Table
Id
Count
I want to write a procedure to find 'Count' in the table with 'Id' as key.After getting 'count' i have to increment it and update back in the table for that 'Id'.How can I write this with procedure without using cursors.
I want a simple procedure like below, BUT ITS NOT EXECUTING.IT SAYS PROCEDURE SUCCESSFUL WITH COMPILATION ERRORS.Help me out.
create or replace PROCEDURE newpro( inId IN NUMBER, outcount OUT NUMBER) is
select COUNT into outcount from Table1 WHERE ID= inId ;
BEGIN
outcount := outcount +1;
update Table1 set COUNT = outcount WHERE ID = inId ;
END;
UPDATE tableName
SET "Count" = "Count" + 1
WHERE ID = valueHere
SEE SQLFiddle Demo
try this one
create or replace Procedure Newpro
(
Inid in number,
Outcount out number
) is
begin
select count + 1
into Outcount
from Table1
where Id = Inid;
update Table1
set count = Outcount
where Id = Inid;
end;

Resources