how to split a string into characters using plsql block - plsql

declare
str varchar2(20):='&your_string';
begin
for i in 1..length(str)
loop
dbms_output.put_line(substr(str,i,1));
end loop;
end;
/
I am trying to split a string into characters and I want to print those characters one in each line. I am trying to print them with the above code but it is not printing space characters. If anyone have idea please help me?

I bet you're running the PL/SQL block in sqlplus, right ? dbms_output + sqlplus combination itself is a tricky and when you mix that with whitespace you're in trouble. My advice in to avoid whitespace sensitive dbms_output and preferably dbms_output completely.
It is possible to get the output you want with some sqlplus settings. Please see the example below:
Empty line magically disappears:
SQL> set serveroutput on
SQL> begin
dbms_output.put_line('1');
dbms_output.put_line(' ');
dbms_output.put_line('2');
end;
/
1
2
PL/SQL procedure successfully completed.
Empty line appears:
SQL> set serveroutput on size 100000 format wrapped
SQL> set trimspool on
SQL> begin
dbms_output.put_line('1');
dbms_output.put_line(' ');
dbms_output.put_line('2');
end;
/
1
2
PL/SQL procedure successfully completed.
SQL>

this code is ok might be you haven't put serveroutput on try this
declare
str varchar2(20):='i n dia';
begin
for i in 1..length(str)
loop
dbms_output.put_line(substr(str,i,1));
end loop;
end;
even with spaces
the code is same

Related

Insert array / nested table into table

I really apologise if answer already was given, but I could only find answers for php.
My problem is that I got nested table array "test_nested_table" that got values ('a','b','c'). I also got table "test_table" in the DB that got three columns col1, col2, col3.
All I want to do is something like
insert into test_table values (test_nested_table);
I understand I can do that:
insert into test_table values (test_nested_table(1), test_nested_table(2), test_nested_table(3));
However, my actual real life table might be very big and I would be very surprised if I really need to type all 100 elements to insert.
I have come up with the following solution:
declare
type test_array is varray(3) of varchar2(10);
ta test_array := test_array ('a','b','c');
sql_txt varchar2(1000) := 'insert into test_table_1 values (''';
begin
for n in 1 .. ta.count loop
sql_txt := sql_txt || ta(n)||''',''';
end loop;
sql_txt := rtrim(sql_txt,',''')||''')';
execute immediate sql_txt;
end;
/
So, if you have an array or any other collection type, you can use dynamic approach to insert a lot of values without writing them all in the insert statement; however, I believe there still should be a more usual way to do that.

How to print unique numbers dynamically with PLSQL

I would like to display Unique numbers dynamically. I have tried below code for the same but same number is displaying all the times.
DECLARE
a NUMBER;
BEGIN
FOR i IN 1 .. 3 LOOP
DBMS_OUTPUT.PUT_LINE(&a);
END LOOP;
END;
the above code will ask me for "a" value three times, if i pass 1,2,3 as parameters then it should display 1,2,3 but this code is displaying first(1) value three time as 1,1,1.
Could you please help me to get the required output like 1,2,3
You can't really create an interactive program in just PL/SQL. When you put &a in the PL/SQL and run it in a tool like SQL Developer, it prompts you once for a value for a before it runs the code, using the value you typed instead of the substitution variable a.
You want to print i and not a. Also the ampersand in front of the a means you will be prompted to enter a value for a.

Get Next roll number from table using Oracle Procedure

create or replace procedure "FINDMAX"
(maxroll OUT NUMBER)
is
begin
select max(rollno) into maxroll from std;
end;​
in this code maxroll i took to make procedure and rollno i took it as a database field. This gives me maximum(LAST) roll number from table.
Can anyone suggest me how I can get next roll number(max+1)?
For your immediate problem, you can use max(col) + 1
create or replace procedure "FINDMAX"
(maxroll OUT NUMBER)
is
begin
select 1 + max(rollno) into maxroll from std;
end;​
But if you are getting this to use while inserting the next record, it's not the right way.
You should use sequences instead.
create sequence roll_no_seq start with 1 increment by 1;
Then use it while inserting using roll_no_seq.nextval
Use a SEQUENCE.
CREATE SEQUENCE rollno_seq
START WITH 1
INCREMENT BY 1
NOCACHE
NOCYCLE;
Then you can use,
select rollno_seq.nextval from dual;
See also, Basic Elements of Oracle SQL: CURRVAL and NEXTVAL

pl/sql : extract after concatenated?

select wm_concat(COLUMN_NAME) A FROM ALL_TAB_COLUMNS where table_name like 'T_EMPLOYEE';
How to extract the data out from A and assign it to another varchar2 variable?
If you just need to store it in a VARCHAR2 variable for further processing, you can do it with something like:
DECLARE
BUFF_V VARCHAR2(2000); -- make sure there's enough space or add some substr
BEGIN
SELECT wm_concat(COLUMN_NAME)
INTO BUFF_V
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME LIKE 'T_EMPLOYEE';
END;
If you don't want to bother with the parsing of the wm_concat, you can just use something like:
DECLARE
COL_V VARCHAR2(100);
BEGIN
FOR QUERY_C IN (select COLUMN_NAME FROM ALL_TAB_COLUMNS where table_name like 'T_EMPLOYEE') LOOP
COL_V := QUERY_C.COLUMN_NAME;
-- do whatever you want with COL_V
END LOOP;
END;
This will iterate on all results (all column names of table T_EMPLOYEE) storing them in the COL_V variable.
I know there is an accepted answer already but just FYI, wm_concat will not work if your version is upgraded on 12c.
You may use LISTAGG as an alternative so why bother use an undocumented feature.Read this
Just saying.
Cheers =)

Procedure returning PLS-00103: Encountered the symbol "EOF" when expecting

I'm new to PL/SQL, doing a homework question where I need to write a procedure that returns an error message based on day of week/time but I am stuck on a basic thing before I get to that point:
I have written the following:
CREATE OR REPLACE PROCEDURE
SECURE_IT
(p_weekday NUMBER,
p_currtime TIME)
IS
BEGIN
select to_char(current_timestamp,'D')
, to_char(current_timestamp,'HH24:MI')
into p_weekday, p_currtime
from dual;
DBMS_OUTPUT.PUT_LINE(p_weekday,p_currtime);
END;
I think all of my ;'s are all in place, can't see any difference between this, code in the book, and code I've found online yet still it returns this error:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the
following: ; <an identifier> <a double-quoted delimited-identifier>
current delete exists prior <a single-quoted SQL string> The symbol ";"
was substituted for "end-of-file" to continue.
I tried changing END; to END SECURE_IT; in hopes that it would fix something (all I could think of) but can't see what's wrong. Could someone help me with this?
Thank you in advance :-)
There is a couple of mistakes in your procedure
TIME datatype (In PL/SQL there is no such datatype see Documentation, Alternatively, you can pass datetime data types: DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE, and TIMESTAMP WITH LOCAL TIME ZONE)
You can extract time part using many options. For example:
SELECT TO_CHAR(p_currDateTime, 'HH24:MI:SS') into p_currtime FROM DUAL;
You are trying to update p_weekday & p_currtime which are IN parameters. These parameters are used to pass value to the procedure, and not to return ones.
DBMS_OUTPUT.PUT_LINE takes only one parameter, so instead of , you can concatenate the two values like this: DBMS_OUTPUT.PUT_LINE(p_weekday||'-'||p_currtime);
It would help a great deal if it is not clear what are you trying to achieve by this procedure
Basically what i can see here is you need to print some value out od procedure as a part of your homework. But using dbms_output will not do any good. You need to make these as OUT param to use these values any where.
CREATE OR REPLACE PROCEDURE SECURE_IT(
p_weekday OUT VARCHAR2,
p_currtime OUT VARCHAR2)
IS
BEGIN
p_weekday := TO_CHAR(CURRENT_TIMESTAMP,'D');
p_currtime:= TO_CHAR(CURRENT_TIMESTAMP,'HH24:MI');
DBMS_OUTPUT.PUT_LINE(p_weekday||' '||p_currtime);
END;
-----------------------------EXECUTE--------------------------------------------
var week VARChaR2(100);
var curtime VARChaR2(100);
EXEC SECURE_IT(:week,:curtime);
print week;
print curtime;
-------------------------------OUTPUT--------------------------------------------
WEEK
-
6
CURTIME
-----
06:12
-------------------------------OUTPUT----------------------------------------------

Resources