oracle sql if condition then select statement1 else select statement2 - sql

I have parameter :prmtr and what I wanted is to use a select statement based on the parameter input.
I tried this:
if :prmtr= 'A' then
select * from tblA;
else
select * from tblB;
end if;
But it wont work.
Is there some other way to do this?

You may try something like this with a CURSOR variable and PRINT command. This works in SQL* plus and in SQL developer or TOAD when run as script.
VARIABLE prmtr VARCHAR2
EXEC :PRMTR := 'A' -- SET values of parameter
VARIABLE x refcursor -- a cursor variable
DECLARE
BEGIN
IF :PRMTR = 'A' THEN
OPEN :x FOR
SELECT *
FROM employees;
ELSE
OPEN :x FOR
SELECT *
FROM departments;
END IF;
END;
/
PRINT x -- gives you the result of the query.

Related

How to check if row exists before SELECT INTO statement in Oracle SQL

I'm using Oracle SQL and have a procedure that is doing some operations on tables. During the procedure there is a "SELECT x INTO y FROM TABLE z WHERE..." statement inside a loop. Unfortunatly during the procedure I can't guarante that there is always a row to the corresponding where condition because it changes dynamically.
Is it possible to check if a row exists before the statement? I was thinking of sth like "if exists(select ...) then SELECT X INTO y..."
Thanks for the help!
Jack
Well, there's no point in checking it first, and re-using the same statement again.
You could handle the exception (possibly in an inner BEGIN-EXCEPTION-END block):
declare
y number;
begin
begin --> inner block starts here
select x into y from z where ...
insert into ...
exception
-- handle it, somehow; I chose not to do anything
when no_data_found then
null;
end; --> inner block ends here
end;
Or, if you used cursor FOR loop, you wouldn't have to handle it because - if select returns x, insert would run. Otherwise, nothing in that loop would ever be executed:
begin
for cur_r in (select x from z where ...) loop
insert into ...
end loop;
end;
An exception handler as in Littlefoot's answer is the most correct and explicit approach, however just for completeness you might also consider using an aggregate.
Value 'X' exists in the table:
declare
p_someparam varchar2(1) := 'X';
l_somevalue varchar2(1);
l_check number;
begin
select max(dummy), count(*) into l_somevalue, l_check
from dual d
where d.dummy = p_someparam;
dbms_output.put_line('Result: '||l_somevalue);
dbms_output.put_line(l_check||' row(s) found');
end;
Result: X
1 row(s) found
Value 'Z' does not exist in the table:
declare
p_someparam varchar2(1) := 'Z';
l_somevalue varchar2(1);
l_check number;
begin
select max(dummy), count(*) into l_somevalue, l_check
from dual d
where d.dummy = p_someparam;
dbms_output.put_line('Result: '||l_somevalue);
dbms_output.put_line(l_check||' row(s) found');
end;
Result:
0 row(s) found
You can add logic to handle the cases where the count check is 0 or greater than 1.
If you are having procedure then I should say use if statement and then write the sql:
select some_column into some_variable from tablename where condition
IF somevariable not in (<list of values separated by comma>)THEN
{statements to execute }
END IF;

Snowflake SQL stored procedure and save value from query with dynamic SQL

I am writing a SQL stored procedure in Snowflake (language SQL NOT Javascript).
I am trying to save a count from a SELECT statement into a variable and the table name for the select statement needs to come from a variable.
Here is what I have so far but this is failing. I don't know where to put the USING or if I can even do this? I feel like I just don't have it syntactically correct yet.
create or replace procedure myprocedure(DBNAME varchar(16777216))
returns int
language sql
as
$$
DECLARE
excludeCount int;
fullyQualifiedProceduresTable varchar(16777216);
BEGIN
fullyQualifiedProceduresTable := CONCAT(DBNAME, '.INFORMATION_SCHEMA.PROCEDURES');
excludeCount := (SELECT count(*) as count from TABLE (?) WHERE PROCEDURE_OWNER = '<ROLE NAME>') USING fullyQualifiedProceduresTable ;
IF (excludeCount > 0) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
$$;
This is what I got to work using slightly different syntax for using variables.
Syntax taken from here
create or replace procedure myprocedure(DBNAME varchar(16777216))
returns int
language sql
as
$$
DECLARE
excludeCount int;
fullyQualifiedProceduresTable varchar(16777216);
BEGIN
SELECT CONCAT(:DBNAME, '.INFORMATION_SCHEMA.PROCEDURES') into :fullyQualifiedProceduresTable;
SELECT count(*) into :excludeCount from IDENTIFIER(:fullyQualifiedProceduresTable) WHERE PROCEDURE_OWNER = '<role>';
IF (excludeCount > 0) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
$$;
I am not sure why you need a procedure for this. Could you not do...
set table_name='abc';
set excludeCount=(select case when count(*)>0 then 1 else 0 end from identifier($table_name));
try this
call my_proc('bus_day');
create or replace procedure my_proc(table_name varchar)
returns table(a integer)
language sql
as
$$
declare
res RESULTSET;
query varchar default 'SELECT count(*) FROM ' || :table_name ;
begin
res := (execute immediate :query);
return table (res);
end;
$$;

Oracle variable from select statement is empty value

In Oracle SQL statement I need to assign variable value from Select Statement. I am doing it according to line documentation but the variable value is empty.
In SQL server the following is what I need to do.
DECLARE #variable INT;
SELECT #variable= mycolumn from myTable;
In Oracle here is the output and query that I am having problem with. I am using Toad client.
My goal is to use the variable value as part of a query.
Here is a simple example intended use.
SELECT * FROM mytable WHERE DateField >= :varCurrMoDateBeg
DECLARE
varCurrMoDateBeg DATE;
varCurrMoDateEnd DATE;
BEGIN
SELECT MONTH_BEG_DATE INTO varCurrMoDateBeg FROM
(
SELECT
CALENDAR.MONTH_BEG_DATE MONTH_BEG_DATE
FROM
CALENDAR
WHERE
CALENDAR.CAL_TYPE='M'
AND (sysdate) BETWEEN CALENDAR.MONTH_BEG_DATE AND CALENDAR.MONTH_END_DATE
) ;
--DBMS_OUTPUT.PUT_LINE(varCurrMoDateBeg);
SELECT MONTH_END_DATE INTO varCurrMoDateEnd FROM
(
SELECT
CALENDAR.MONTH_END_DATE MONTH_END_DATE
FROM
CALENDAR
WHERE
CALENDAR.CAL_TYPE='M'
AND (sysdate) BETWEEN CALENDAR.MONTH_BEG_DATE AND CALENDAR.MONTH_END_DATE
);
--DBMS_OUTPUT.PUT_LINE(varCurrMoDateEnd);
END;
SELECT :varCurrMoDateBeg, :varCurrMoDateEnd from dual;
Online sources:
SELECT INTO Statement
https://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems045.htm
plsql - Declaring a variable and setting its value from a SELECT query in Oracle - Stack Overflow
Declaring a variable and setting its value from a SELECT query in Oracle
PL/SQL SELECT INTO Statement By Practice Examples
https://www.oracletutorial.com/plsql-tutorial/plsql-select-into/
Oracle Tutorials - Assign Query Results to Variables
http://dba.fyicenter.com/faq/oracle/PL-SQL-Assign-Query-Results-to-Variables.html
Using Toad, a small example
declare
v_var date;
v_bind date :=to_date('01.01.2020','DD.MM.YYYY');
v_stm varchar2(4000);
v_counter pls_integer;
begin
select sysdate into v_var from dual ;
dbms_output.put_line(v_var);
execute immediate ' select sysdate from dual ' into v_var ;
dbms_output.put_line(v_var);
-- with bind
v_stm := ' select count(*) from dba_objects where created > :1 ' ;
execute immediate v_stm into v_counter using v_bind;
dbms_output.put_line(v_counter);
end;
/
When I ran this code
As you can see, it is a very easy piece of code that shows how to use bind variables in PL/SQL.
You could create a function for each of the dates you want to use outside of your current PL/SQL block. Here is a rough example to demonstrate how that could be made to work.
CREATE OR REPLACE FUNCTION varCurrMoDateBeg
RETURN DATE
AS
dt_Work DATE;
BEGIN
-- Replace this with your query
SELECT SYSDATE INTO dt_Work FROM dual;
RETURN dt_Work;
END varCurrMoDateBeg;
/
SELECT varCurrMoDateBeg FROM dual;

Declaring cursor in a PL/SQL stored procedure

printf('local_time_greeting');
Having some trouble getting a stored procedure to run with SQL Developer. Below is an example patterned exactly like the first few lines, with variable names changed for security reasons.
CREATE OR REPLACE PROCEDURE redacted ( an_in_variable IN VARCHAR ) AS
these VARCHAR;
variables VARCHAR;
don_apostrophe_t INT;
matter INT;
BEGIN
DECLARE cursor_giving_me_trouble CURSOR FOR
SELECT something FROM db.table WHERE condition_1 = condition_2;
...
In the editor the SELECT word is red-wavy-lined, and when I try to run the code the output returns
PLS-00103: Encountered symbol "FOR" when expecting one of the following := . ( # % ; not null range default character
Any ideas?
You need to use IS rather than FOR, but you have the terms of the definition in the wrong order as well:
DECLARE
CURSOR cursor_giving_me_trouble IS
SELECT something FROM db.table WHERE condition_1 = condition_2;
db<>fiddle which still errors because of the illegal object names in your obfuscated code, but not from the syntax; and a more complete example.
It's also possible you're trying to use the construct:
FOR cursor_giving_me_trouble IN (
SELECT something FROM db.table WHERE condition_1 = condition_2
) LOOP
...
rather than a sub-block (a new declare, followed by begin/end) with references only to cursor within that. db<>fiddle.
To get you started:
create or replace procedure redacted
( an_in_variable in varchar2 )
as
these varchar2(123);
variables varchar2(456);
don_apostrophe_t integer;
matter integer;
cursor cursor_giving_me_trouble is
select 'Welcome to PL/SQL' as whatever from dual where 1=1;
begin
for r in cursor_giving_me_trouble loop
dbms_output.put_line(r.whatever);
end loop;
end;
However, you often don't need a separate cursor definition as there is this compact syntax:
create or replace procedure redacted
( an_in_variable in varchar2 )
as
these varchar2(123);
variables varchar2(456);
don_apostrophe_t integer;
matter integer;
begin
for r in (
select 'Welcome to PL/SQL' as whatever from dual where 1=1
)
loop
dbms_output.put_line(r.whatever);
end loop;
end;

PLSQL oracle select after declare ORA-06550 PLS-00103

Using PL/SQL Developer client.
Oracle throws me ORA-065550 PLS-00103 Encountered the symbol "SELECT".
Well, can not find what's wrong here.
DECLARE someId NUMBER;
BEGIN
select id into someId from someTable where someColumn = 'someUniqueValue';
select * from someTable; --here
END;
select * from someTable; --or here
Neither second select, neither third works. When I dmbs_output someId into console it works well, this assigning to declared variable. But why I can not just select after 'into'? I want to declare one time value, and then make
select * from someTable where id = someId
or to be precised want to make like thousand inserts and I want to cache that first select.
DECLARE someId NUMBER;
BEGIN
select id into someId from someTable where someColumn = 'someValue';
END;
/
select * from otherTable where otherTableId = someId;
Here I lost someId scope I guess.
Basically you doing a lot of mistakes while doing this code.
1.You cant just 'SELECT *' in the anonymous block. You need to have cursor to do it.
2.Your variable scope is till the anonymous block. Now you are trying to access the variable outside the block --> NAAH not possible.
So I have tried to resolve your issue by below snippet hope it helps.
DECLARE
someId NUMBER;
p_lst sys_refcursor;
BEGIN
SELECT id INTO someId FROM someTable WHERE someColumn = 'someUniqueValue';
OPEN p_lst FOR
'SELECT * FROM someTable
where otherTableId = '||someId;
END;
Assuming you're coding a sql script, you can
1) declare your variable
2) populate it in an anonymous pl/sql block
3) use it elsewhere
--1
variable my_num number
--2
begin
select 1 into :my_num from dual;
end;
/
--3
select :my_num from dual;
That you can achieve through using SQL*Plus
SQL> variable id number
SQL> begin
select 1000 into :id from dual;
end;
/
SQL> print id
ID
----------
1000
SQL> SELECT * FROM tbl_a WHERE id = :id
In Oracle doesn't let you implicitly return the result of a query. The result always has to be explicitly returned in some fashion. The simplest way is to use DBMS_OUTPUT (roughly equivalent to print) to output the variable:
DECLARE
myname varchar2(20);
BEGIN
myname := 'Tom';
dbms_output.print_line(myname);
END;
This isn't terribly helpful if you're trying to return a result set, however. In that case, you'll either want to return a collection or a refcursor. However, using either of those solutions would require wrapping your code in a function or procedure and running the function/procedure from something that's capable of consuming the results. A function that worked in this way might look something like this:
CREATE FUNCTION my_function (myname in varchar2)
my_refcursor out sys_refcursor
BEGIN
open my_refcursor for
SELECT *
FROM Customers
WHERE Name = myname;
return my_refcursor;
END my_function;