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 =)
Related
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.
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
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----------------------------------------------
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
There is a table X having a "Long" Column and Table Y having a "CLOB" Column. Data has been migrated from Table X to Table Y. Now I need to verify if the data got converted correctly. I had the idea of using casting, but seems "Long" values cannot be converted to "Varchar" in select statements. Any ideas are highly appreciated.
Eg:
SELECT LONG_COLUMN FROM TABLE_X
Minus
SELECT CLOB_COLUMN FROM TABLE_Y
You have two problems: long can't easily be converted/compared to other datatypes and clob can't be used in a minus operation!
Fortunately, both of these can be overcome by using PL/SQL. Longs and clobs can be implicitly converted into varchar2 when they are selected in PL/SQL blocks. You can load these into a nested-table, then use the multiset except operator to find the differences between them:
create table long_t ( x long );
create table lob_t ( x clob );
insert into long_t values ('1');
insert into long_t values ('2');
insert into lob_t values ('1');
declare
type t is table of varchar2(32767);
longs t;
clobs t;
diff t;
begin
select x bulk collect into longs from long_t;
select x bulk collect into clobs from lob_t;
diff := longs multiset except clobs;
for i in 1 .. diff.count loop
dbms_output.put_line(diff(i));
end loop;
diff := clobs multiset except longs;
for i in 1 .. diff.count loop
dbms_output.put_line(diff(i));
end loop;
end;
/
anonymous block completed
2
If your tables contain more than a couple of thousand rows, you're likely to run out of memory using the above as-is, as the whole table will be loaded at once. If you've got an id or similar column on each table, then it would be best to fetch and compare rows in ranges, e.g. 1-1000, 1001-2000 and so on.