Simple Oracle variable SQL Assignment - oracle

Despite having spent an hour researching I can't seem to figure out how to correctly define a variable and then use it in your SQL.
This is what I have so far produced:
DECLARE startDate DATE := to_date('03/11/2011', 'dd/mm/yyyy');
of which I get the reply:
ORA-06550: line 1, column 63: PLS-00103: Encountered the symbol
"end-of-file" when expecting one of the following:
begin function package pragma procedure subtype type use form current
cursor
Details: DECLARE startDate DATE := to_date('03/11/2011',
'dd/mm/yyyy'); Error at line 1 ORA-06550: line 1, column 63:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of
the following:
begin function package pragma procedure subtype type use form current
cursor
I'd love to find out how to do such a simple task!

Your variable declaration is correct.
The DECLARE keyword is used to define variables scoped in a PL/SQL block (whose body is delimited by BEGIN and END;). How do you want to use this variable?
The following PL/SQL works fine for me:
DECLARE
startDate DATE := to_date('03/11/2011', 'dd/mm/yyyy');
reccount INTEGER;
BEGIN
SELECT count(*) INTO reccount
FROM my_table tab
WHERE tab.somedate < startDate;
dbms_output.put_line(reccount);
END;
You can also use the DEFINE statement to use simple string substitution variables. They are suitable for a client like SQL/PLUS or TOAD.
DEFINE start_date = "to_date('03/11/2011', 'dd/mm/yyyy')"
SELECT COUNT(*) from my_table tab where tab.some_date < &start_date;

To accomplish what you're attempting in Toad, you don't need to declare the variable at all. Simply include your variable prefaced with a colon and Toad will prompt you for the variable's value when you execute the query. For example:
select * from all_tables where owner = :this_is_a_variable;
If this doesn't work initially, right-click anywhere in the editor and make sure "Prompt for Substitution Variables" is checked.
If you really want to do it similarly to the way SQL Server handles variables (or you want to be able to do the same thing in SQL*Plus), you can write it as follows:
var this_is_a_variable varchar2(30);
exec :this_is_a_variable := 'YOUR_SCHEMA_NAME';
print this_is_a_variable;
select * from all_tables where owner = :this_is_a_variable;
However, to make this work in Toad, you'll need to run it through "Execute as script", rather than the typical "Execute statement" command.

Take in mind that Oracle's PL/SQL is not SQL.
PL/SQL is a procedural language. SQL is not procedural, but you can define "variables" the user can enter via the "&var" syntax (see http://www.orafaq.com/node/515).

This is an old post, but in case anyone stumbles on this (as I just did), you can handle this with a CTE:
with params as (
select date '2011-11-03' as startdate
from dual
)
select . . .
from params cross join
. . .
Almost the same syntax works in SQL Server (minus the date-specific stuff and from dual).

Solution
DEF startDate = to_date('03/11/2011', 'dd/mm/yyyy');
Select &startDate from dual;

Related

Can't declare a variable in Oracle SQL(SQL Fiddle)

When I run declare query, it always gives me errors.
DECLARE
the_variable date;
BEGIN
SELECT MIN("Start Date") INTO the_variable FROM "Employee_Master";
END;
ORA-06550: line 2, column 20: PLS-00103: Encountered the symbol
"end-of-file" when expecting one of the following: := . ( # % ; not
null range with default character.
I am not sure where is the problem.
Works OK for me:
SQL> create table "Employee_Master" ("Start Date" date);
Table created.
SQL> insert into "Employee_Master" values (sysdate);
1 row created.
SQL> declare
2 the_variable date;
3 begin
4 select min("Start Date") into the_variable
5 from "Employee_Master";
6 end;
7 /
PL/SQL procedure successfully completed.
SQL>
Though, why, oh, why are you making your life miserable? Avoid double quotes while working with Oracle. If you do that, you always have to reference tables (and columns) using double quotes and matching letter case exactly as during creation process.
By default, Oracle stores everything as uppercase, but you can reference those objects any way you want (upper, lower, mixed case - doesn't matter). But, with double quotes, as I've said - exact matching is required.
By the way, screenshot you attached shows a lot of nothing and just a little bit of something. Couldn't you have taken a better screenshot?
On the SQL Fiddle website, you need to tell it that you are going to be using PL/SQL and a statement will be ended with a / terminator (and not by a ; semi-colon). To do this you need to click on the "Query Terminator" button (right of the "Run SQL" and "Edit Fullscreen" buttons) and change it from [;] to [/].
Then it will work:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE Employee_Master ( Start_Date DATE );
INSERT INTO Employee_Master ( Start_Date ) VALUES ( SYSDATE );
Query 1:
DECLARE
the_variable date;
BEGIN
SELECT MIN(Start_Date) INTO the_variable FROM Employee_Master;
END;
/
Results:

How to use a variable in a LIKE clause in PL/SQL

I am new to Oracle and learning; I am simply trying to run this T-SQL query
DECLARE #SearchObj varchar(100);
SET #SearchObj='%aldbrough%';
SELECT
obj_id,
name,
description
FROM
agnis.t_object
WHERE
lower(name) = ObjToSearch ;
I am using SQL Developer Oracle tool which also have a "Scratch Editor" to help with translation from T-SQL. When i run the tool it gave me this code
DECLARE
v_SearchObj VARCHAR2(100);
BEGIN
v_SearchObj := '%aldbrough%' ;
SELECT obj_id ,
NAME ,
DESCRIPTION
FROM agnis.t_object
WHERE LOWER(NAME) = ObjToSearch;
END;
but the same tool give me this error
Error report -
ORA-06550: line 10, column 26:
PL/SQL: ORA-00904: "OBJTOSEARCH": invalid identifier
ORA-06550: line 6, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
so what is the correct syntax to use a variable into a LIKE clause that returns multiple rows?
I hope I do not have to use cursors etc for such of a simple statement as suggested in this question
Well, yes - those "translators" don't always do what they are supposed to.
This is how your code should look like:
use like, not = in the where clause
in PL/SQL, you have to put the result of the select statement into something - for example, locally declared variables (as my example shows).
So:
DECLARE
v_SearchObj VARCHAR2 (100) := '%aldbrough%';
--
v_obj_id t_object.obj_id%TYPE;
v_name t_object.name%TYPE;
v_description t_object.description%TYPE;
BEGIN
SELECT obj_id, NAME, DESCRIPTION
INTO v_obj_id, v_name, v_description
FROM agnis.t_object
WHERE LOWER (NAME) LIKE v_searchobj;
END;
If such a code returns an error - too_many_rows (and yes, it does), then one option is to loop through rows and do something (such as display those values):
DECLARE
v_SearchObj VARCHAR2 (100) := '%aldbrough%';
BEGIN
FOR cur_r IN (SELECT obj_id, NAME, DESCRIPTION
FROM agnis.t_object
WHERE LOWER (NAME) LIKE v_searchobj)
LOOP
DBMS_OUTPUT.put_line (
'Name = ' || cur_r.name || ', description = ' || cur_r.description);
END LOOP;
END;
Since this is tagged SQL Developer, use a bind variable:
SELECT obj_id,
name,
description
FROM agnis.t_object
WHERE lower(name) = :ObjToSearch;
and SQL developer will pop up a dialog box where you can set the value of the ObjToSearch variable.
If you want to specify the bind variable in code then:
VARIABLE objtosearch VARCHAR2(50)
BEGIN
:objtosearch := '%aldbrough%';
END;
/
SELECT obj_id,
name,
description
FROM agnis.t_object
WHERE lower(name) = :ObjToSearch;
And run the statements as a script using F5 rather than as individual statements.

How to Declare, Populate and Use a Variable using Oracle PL/SQL

I swear this has been asked so many times previously, yet I cannot seem to apply other examples to my use case:
First things first, this query will be executed as part of an Informatica SQL Source Qualifier, and in some circumstances, be passed-through from an SQL Server OpenQuery statement, so please be mindful of this, and
that SQL Plus will not be used be used; Oracle SQL Developer is used only for code development.
My history is primarily SQL Server & Teradata, but as the title suggests, I now have a requirement where I need to declare, populate and use a variable in Oracle, all within the same procedure. Not SP, so no In/Out declarations
In SQL Server, this code will work as expected (line numbers added for clarity):
1. Declare #MaxDate Int
2.
3. With f_data (cal_period) As (Select 201904 As cal_period)
4.
5. Select #MaxDate = Max(cal_period) From f_data
6.
7. Select
8. Case
9. When (#MaxDate%100) < 12 Then #MaxDate+1
10. Else (#MaxDate+100) - ((#MaxDate%100)-1)
11. End As dt
Line 1: These are YYYYMM date periods defined as int
Line 3: I am using an inline view (CTE) here for illustration, and to
make it easier for you to copy and paste, but in reality, this is
actually a physical control table, so would not normally be visible in the
script.
Line 5: Populates the parameter (SQL Server prefixes parameters with
the at symbol) with the single-value resultset
Line 7-11: Is simply the logic to progress the period by one, the
percentage-mark in SQL Server is the Modulus function, Oracle is
written as Mod(#MaxDate,100)
For those unfamiliar with SQL Server, it does not need a reference table such as Dual ("Sys.Dual") in order to execute the query, such that for Oracle a "From Dual" statement is necessary on the missing Line 12
My requirement is essentially a carbon-copy of the above T-SQL, so I need to declare a one-time use variable, to populate that variable with the results of an SQL query, and then to use this variable in a transformation - the result of which is captured to an Informatica and SSIS variable for later use.
So far, I have tried declaring a variable, this seemed to work (by which I mean it didn't return an error):
Declare MaxPeriod Int;
Begin
Select 201904 Into MaxPeriod From Dual;
End;
And populating from an SQL statement is also showing as successfully completed:
Declare MaxPeriod Int;
Begin
Select Max(MaxPeriodVal) Into MaxPeriod From CtrlTable;
End;
Although I can't seem to get beyond this to actually test the variable as put.line statements fail, as do simple Case checks:
Declare MaxPeriod Int;
Begin
Select 201904 Into MaxPeriod From Dual;
End;
Select
Case
When 201904 = MaxPeriod Then 'Match'
Else 'No Match'
End As dteChk
From Dual;
I have attempted to prefix the MaxPeriod in the check with a colon, and, to have prefixed,suffixed/both with an ampersand eg :MaxPeriod; &MaxPeriod; MaxPeriod&; &MaxPeriod&
All of which failed.
The basic issue is a variable scope problem. You're declaring MaxPeriod within the context of a PL/SQL anonymous block, so it will disappear (fall out of scope) when the block ends on line 4.
You could put your entire query inside the PL/SQL block, but there's not an easy way to return an entire result set from a PL/SQL block, so I don't think you want that.
I don't know how your Oracle driver handles native queries, but this might work:
var MaxPeriod number; -- bind variable declared as global scope for this script
Begin -- one of several ways to assign values to bind variables
:MaxPeriod := 201904;
End;
/
Select
Case
When 201904 = :MaxPeriod Then 'Match'
Else 'No Match'
End As dteChk
From Dual;
If the var syntax doesn't work for you to declare a SQL bind variable, then you may have to look into some other way of passing a bind variable for the query string. You could probably pass a null value (for a number datatype, anyway) and then overwrite it in the SQL script.
Alternately, in your original example code, I think I'd use a CTE or an inline view instead of a variable anyway.
With f_data As (Select 201904 As cal_period from dual)
Select
Case
When Mod(MaxDate,100) < 12 Then MaxDate+1
Else (MaxDate+100) - (Mod(MaxDate,100)-1)
End As dt
from (Select Max(cal_period) as MaxDate From f_data) mp
You can use substitution variable using define in sql*plus as following.
Define MaxPeriod := 201904
Select
Case
When &MaxPeriod = MaxPeriod Then 'Match'
Else 'No Match'
End As dteChk
From Dual;
Cheers!!

select inside a case statement not works

I wanted to write a select statement inside CASE THEN statement in PLSQL but it throws error. Please advise if I could write select statement inside THEN Statement.
An example similar to my requirement looks like below
SET SERVEROUTPUT ON
DECLARE
LV_VAR VARCHAR2(4000):=NULL;
BEGIN
LV_VAR:= CASE
WHEN 1=1 THEN
(SELECT 1 FROM DUAL)
ELSE
0
END;
DBMS_OUTPUT.PUT_LINE(LV_VAR);
END;
While executing , it throws error as below
ORA-06550: line 6, column 26:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:
( - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
You can't use scalar subqueries directly in PL/SQL code, like you have shown. (Of course, you knew that already.) You must select the value INTO a variable, and then use it.
ALSO: You have no case statements in your code. You have a case expression. It just won't work quite the way you wrote it.
One alternative is to use a case expression within the SQL SELECT ... INTO statement, as David Goldman has shown in his Answer.
However, if the whole point of your exercise was to practice case expressions as used in PL/SQL, not inside a SQL statement, you would need to SELECT ... INTO a variable you declare in your code, and then use that variable in the case expression. Something like this:
DECLARE
LV_VAR VARCHAR2(4000);
BEGIN
SELECT 1 INTO LV_VAR FROM DUAL;
LV_VAR:= CASE
WHEN 1=1 THEN
LV_VAR
ELSE
0
END;
DBMS_OUTPUT.PUT_LINE(LV_VAR);
END;
As you can see, I did something that is done frequently in procedural language code: Instead of declaring and using TWO variables, I only declared one. I populated it with the result of the SELECT ... INTO query. Then I assigned to it again in the case expression: in one case I assign it to itself and in the other I assign to it the value 0.
In PL/SQL, you'll need to do a SELECT ... INTO. So, to re-write your code:
SET SERVEROUTPUT ON
DECLARE
LV_VAR VARCHAR2(4000):=NULL;
BEGIN
SELECT CASE
WHEN 1=1 then 1
else 0
end
INTO LV_VAR
FROM DUAL;
DBMS_OUTPUT.PUT_LINE(LV_VAR);
END;
You are trying to combine PL/SQL Control Statement CASE with SQL CASE Expressions.
While it is possible to use a sub-query in THEN return expression of SQL CASE,
select CASE WHEN 1=1 THEN ( select 1 FROM DUAL )
ELSE 0 END FROM DUAL;
The same is not true while you use it in PL/SQL although the syntax is same.
Read the Oracle documentation for SQL , CASE1 and PL/SQL : CASE2

Function Create but Statement is Ignored

Hello everyone, please help me again!
I could create the function but when I execute it, I always get the following error. Line 1, column 7 (I guess it's datatype of parameter) and statement ignored! :(
What you are using is to execute a function. Either assign the result to a variable or run sql query using dual
declare
x varachar2(100);
begin
x := fct1('dd');
end;
Alternatively you can also use
select fct1('dd') from dual;

Resources