Define date variable in Oracle - oracle

How to define date variable and assign that variable from the table in oracle?
I tried below
DEFINE EXTRACTION_DATE = SELECT DATA_EXTRACTION_DATE FROM tbl1
SELECT PA.PERSON_ID,A.PERIOD_END_DATE,PA.OPT_OUT_OF_PLAN_DATE,A.TERMINATION_DATE,
CASE WHEN A.PERIOD_END_DATE <= ADD_MONTHS(TRUNC(&EXTRACTION_DATE), -3) THEN 'Y' ELSE 'N' END
FROM
tbl2
it throwing invalid statement error.
its not duplicate of another. Because I need to get variable from the table not by static variable.

I dont fully understand what you are tyring to do but as far as I understand
you can set a variable such a way as follows
1 - ) if you write a procedure,
declare
EXTRACTION_DATE date;
begin
SELECT DATA_EXTRACTION_DATE into EXTRACTION_DATE FROM tbl1;
end;
2 - ) If your data reference to a table, you can user cursor
declare
cursor crs is SELECT * into EXTRACTION_DATE FROM tbl1;
then use crs in for loop
3 - ) You can write upper query in you second query.
SELECT PA.PERSON_ID,A.PERIOD_END_DATE,PA.OPT_OUT_OF_PLAN_DATE,A.TERMINATION_DATE,
CASE WHEN A.PERIOD_END_DATE <= ADD_MONTHS(TRUNC(SELECT DATA_EXTRACTION_DATE FROM tbl1), -3) THEN 'Y' ELSE 'N' END
FROM
tbl2

I'm going to assume that this is required for some sort of script. If so, you can do this using the COLUMN command and its new_value parameter in SQL*Plus:
SQL> column my_val new_value my_val_subst_param
SQL> define my_val_subst_param
Symbol my_val_subst_param is UNDEFINED
SQL> select 'hello!' my_val from dual;
MY_VAL
------
hello!
SQL> select '&my_val_subst_param' some_val from dual;
'HELLO!'
--------
hello!
I highly recommend you read all of this article, and specifically this section.
ETA: Bear in mind that if you use this method, DATEs are output as strings, so you will have to ensure that you do the appropriate conversion in your select statement, eg.:
SQL> column dt new_value dt_val
SQL> select to_char(sysdate, 'dd/mm/yyyy') dt from dual;
DT
----------
29/09/2016
SQL> define dt_val;
DEFINE DT_VAL = "29/09/2016" (CHAR)
SQL> select * from dual where trunc(sysdate) = to_date('&dt_val', 'dd/mm/yyyy');
DUMMY
-----
X

Try something like:-
declare
var1 <dtatatype same as your table column>;
var2 <dtatatype same as your table column>;
var3 <dtatatype same as your table column>;
var4 <dtatatype same as your table column>;
var5 <dtatatype same as your table column>;
var_dt date;
begin
SELECT EXTRACTION_DATE
into var_dt
FROM tbl1;
SELECT PA.PERSON_ID,
A.PERIOD_END_DATE,
PA.OPT_OUT_OF_PLAN_DATE,
A.TERMINATION_DATE,
CASE WHEN A.PERIOD_END_DATE <= ADD_MONTHS(var_dt), -3)
THEN 'Y'
ELSE 'N' END
into
var1,
var2,
.
.
var5
FROM tbl2;
end;

Related

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);

Get list of columns and alias name by a query string in Oracle

I'm using Pl/SQL with Oracle Database 11g.
I want to get a list of columns with alias by a query string.
There is a way to get all the column names of a query, using dbms_sql.describe_columns2 but only I get alias.
For example:
DECLARE
l_cursor NUMBER := dbms_sql.open_cursor;
l_ignore NUMBER;
l_desc dbms_sql.desc_tab2;
l_cnt NUMBER;
BEGIN
dbms_sql.parse( l_cursor, 'select a.col1 column1, a.col2 column2 from table_test a', dbms_sql.native );
dbms_sql.describe_columns2( l_cursor, l_cnt, l_desc );
FOR i IN 1 .. l_cnt LOOP
dbms_output.put_line(l_desc(i).col_name);
END LOOP;
dbms_sql.close_cursor( l_cursor );
END;
/
Returns:
column1
column2
Is there any way to get the values a.col1, or a.col2 with alias in the query?
The column names used in a SQL statement can be retrieved using Rob van Wijk's custom view DBA_DEPENDENCY_COLUMNS.
Install the view as SYS and grant select on dba_dependency_columns to <your user>;.
The view only works on objects. Create a VIEW on the SELECT statement and then the dependencies will be available. For example:
create table table_test(col1 number, col2 number);
create or replace view test_view as
select a.col1 column1, a.col2 column2 from table_test a;
select referenced_column
from sys.dba_dependency_columns
where owner = user
and name = 'TEST_VIEW'
order by 1;
Results:
REFERENCED_COLUMN
-----------------
COL1
COL2
The above results get the "list of columns". But part of your answer also implies you may want to get the "column expressions". That would be a completely different task, but is possible. Parsing SQL can be ridiculously difficult so it might help to explain exactly what you want and why you want it.

Can i use a variable in oracle sql script?

I am using a SQL script to spool data and load data into XML
I want to check whether I can use variable in the SQL script which get it value from another SQL query.
Something like this:
var1= select count(1) from emp
spool filename
select * from dept where empcnt=var1
Will it work? Is this the best way or any other way of doing it?
If you are using SQLplus, and you only want SQL ( not PLSQL) you can do something like the following, with bind variables:
spool yourFile
variable var1 number
select count(1) into :var1 from dual;
select * from dual where rownum = :var1;
Another way could be with substitution variables:
spool yourFile
column var1 new_value valueFor_var1
select count(1) as valueFor_var1 from dual;
select * from dual where rownum = &var1;
If you can use a PLSQL block, you can do:
spool yourFile
declare
var1 number;
vDummy varchar2(100);
begin
select count(1) into var1 from dual;
select dummy into vDummy from dual where rownum = var1;
dbms_output.put_line(vDummy);
end;
/

oracle select from table if values not exists

I need to write oracle query (Just query)
to select values from table, and if not found select from another table.
any help to do this in pl/sql?
SELECT * FROM firstTable
UNION ALL
SELECT * FROM secondTable WHERE (SELECT count(*) FROM FIRST_TABLE ) = 0
You can enclose the SELECT statement within a block and add an exception handler to it.
So, if there are no rows selected from the first table, then you select from the second table. The structure would be something like below:
Begin
select <many columns> into <many variables or row type>
From Table1
where <conditions>;
EXCEPTION
WHEN NO_DATA_FOUND THEN
select <many columns> into <many variables or row type>
From Table2
Where <Conditions>;
End;
References:
Another related SO question
Exception Handlers
Documentation for the SELECT INTO statement
Here is an example of a PL/SQL function that will perform a test, and then execute a secondary query based upon the results of the test. You can adjust it to fit your needs:
set serveroutput on;
declare
row_count number;
column1 varchar(10);
column2 varchar(10);
column3 number;
begin
/*Perform your test*/
select count(target_column) into row_count
from my_table
where condition_column = 'x';
/*Run your secondary query based on the output of the first*/
if row_count > 0 then
select
col_x into column1,
col_y into column2,
col_z into column3
from my_other_table_A;
else
select
col_a into column1,
col_b into column2,
col_c into column3
from my_other_table_B;
end if;
/*Show the results*/
dbms_output.put_line('column1: ' || column1);
dbms_output.put_line('column2: ' || column2);
dbms_output.put_line('column3: ' || column3);
end;
/

if (select count(column) from table) > 0 then

I need to check a condition. i.e:
if (condition)> 0 then
update table
else do not update
end if
Do I need to store the result into a variable using select into?
e.g:
declare valucount integer
begin
select count(column) into valuecount from table
end
if valuecount > o then
update table
else do
not update
You cannot directly use a SQL statement in a PL/SQL expression:
SQL> begin
2 if (select count(*) from dual) >= 1 then
3 null;
4 end if;
5 end;
6 /
if (select count(*) from dual) >= 1 then
*
ERROR at line 2:
ORA-06550: line 2, column 6:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:
...
...
You must use a variable instead:
SQL> set serveroutput on
SQL>
SQL> declare
2 v_count number;
3 begin
4 select count(*) into v_count from dual;
5
6 if v_count >= 1 then
7 dbms_output.put_line('Pass');
8 end if;
9 end;
10 /
Pass
PL/SQL procedure successfully completed.
Of course, you may be able to do the whole thing in SQL:
update my_table
set x = y
where (select count(*) from other_table) >= 1;
It's difficult to prove that something is not possible. Other than the simple test case above, you can look at the syntax diagram for the IF statement; you won't see a SELECT statement in any of the branches.
Edit:
The oracle tag was not on the question when this answer was offered, and apparently it doesn't work with oracle, but it does work with at least postgres and mysql
No, just use the value directly:
begin
if (select count(*) from table) > 0 then
update table
end if;
end;
Note there is no need for an "else".
Edited
You can simply do it all within the update statement (ie no if construct):
update table
set ...
where ...
and exists (select 'x' from table where ...)
not so elegant but you dont need to declare any variable:
for k in (select max(1) from table where 1 = 1) loop
update x where column = value;
end loop;

Resources