I have the following structure:
ACCEPT PVAR_FLENME PROMPT 'File Name (No Space)? '
ACCEPT PVAR_FULLROUTE PROMPT 'Full Route: '
SPOOL "&PVAR_FULLROUTE.&PVAR_FLENME.";
... which works as expected.
Now I want to make the second variable to be dependent on an Procedure without having to create it (or a Function). I would normally use COLUMN & a SELECT, but the logic within the BEGIN-END is more complex:
ACCEPT PVAR_FLENME PROMPT 'File Name (No Space)? '
DEFINE PVAR_FULLROUTE; -- I'm not sure this is valid
BEGIN
{Series of validations}
{How do I assign a value to PVAR_FULLROUTE from within the procedure?}
END;
SPOOL "&PVAR_FULLROUTE.&PVAR_FLENME.";
What is the correct way to assign a value to a variable from within a procedure, so I can use it in other BEGIN-END sections? Is it possible?
Here's one option.
Accept filename:
SQL> accept par_filename prompt 'Enter filename: '
Enter filename: test.txt
Create a variable whose value is then set in anonymous PL/SQL block:
SQL> var par_fullroute varchar2(20)
SQL> begin
2 select 'this_is_route' into :par_fullroute from dual;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> print par_Fullroute
PAR_FULLROUTE
--------------------------------------------------------------------------------
this_is_route
OK; its value is set. Now, create a column and put bind variable (par_fullroute) into new substitution variable:
SQL> column par_bv_route new_value bvr
SQL> select :par_fullroute par_bv_route from dual;
PAR_BV_ROUTE
--------------------------------------------------------------------------------
this_is_route
Everything's set; what's left is to create filename for spool:
SQL> spool "&bvr.&par_filename."
SQL> select sysdate from dual;
SYSDATE
---------
08-FEB-23
SQL> spool off;
Result:
Related
I am working on a script to be later used in my SSIS ETL, the source DB is oracle and I am using SQL Developer 20.0.2.75 .
I spent so much time declaring 100 variables but it doesn't see to work in SQL developer.
Define & Initialise:
Declare
V1 number;
V2 number;
.
.
.
V100 number;
Begin
Select UDF(params1,param2) into V1 from dual;
Select UDF(params3,param4) into V2 from dual;
...
End;
I was hoping I'd be able to use these variables in my script like :
select columns from table where Col1=:V1 and Col2=:V2
When used "Run Statement" prompts for values, "Run Script" doesn't see to like into Variable statements.
I even tried :
select columns from table where Col1=&&V1 and Col2=&&V2
Now my query doesn't work !
After below responses, I changed my script to :
Variable V1 Number;
Variable V2 Number;
exec select MyFunction(p1,p2) into :V1 from Dual;
/
Select columns from table where col1=:V1 and col2=:V2
It still prompts for value
This is how I defined my function
Create Function MyFunction(m IN Varchar, s IN Number)
Return Number
IS c Number;
select code into c from table where col1=m and col2=s;
Return(c);
End;
Is there anything wrong with the function?
You define variables as per you would in SQL Plus or SQLcl and then run it as a script
Text below
variable x1 number
begin
select 123 into :x1 from dual;
end;
/
print x1
Similar example in SQL Plus (and will work in SQL Dev as well)
SQL> set serverout on
SQL> variable x1 number
SQL> begin
2 select 5 into :x1 from dual;
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> print x1
X1
----------
5
SQL>
SQL> select rownum from dual
2 connect by level <= :x1;
ROWNUM
----------
1
2
3
4
5
SQL>
SQL> begin
2 dbms_output.put_line('X1 is '||:x1);
3 end;
4 /
X1 is 5
PL/SQL procedure successfully completed.
I spent so much time declaring 100 variables
To me, it looks like a wrong approach. OK, declare a few variables, but 100 of them?! Why wouldn't you switch to something easier to maintain. What? A table, for example.
create table params
(var varchar2(20),
value varchar2(20)
);
Pre-populate it with all variables you use (and then just update their values), or just insert rows:
insert into params (var, value) values ('v1', UDF(params1, param2));
insert into params (var, value) values ('v2', UDF(params3, param4));
...
Fetch values through a function:
create or replace function f_params (par_var in varchar2)
return varchar2
is
retval varchar2(20);
begin
select value
into retval
from params
where var = par_var;
return retval;
end;
Use it (in your query) as:
select columns
from table
where Col1 = f_params('v1')
and Col2 = f_params('v2')
If many users use it, consider creating one "master" params table (which contains all the variables) and a global temporary table (which would be populated and used by each of those users).
I am trying to understand what steps I need to undertake in order to move a stored procedure from one schema and into another. The schema that this is currently sitting in is going to be made redundant and I have been asked to move all tables and procedures. I have no trouble with tables but never done anything with procedures hence want to make sure I don't miss anything out.
What I have currently done is look through the procedure and made a list of what its actually doing i.e. dropping/creating and inserting data into tables.
After this I wasn't sure if it was just a case of copying the procedure code and then creating a new procedure on the new schema with the same code and then compiling it.
I would really appreciate it if somebody could advise if I am missing anything in the steps that I am undertaking just to ensure I don't mess things up.
There is no way to "move" an object from one schema to another.
The only practible way I see here is copying the source code and then executing it in the new schema. As #pmdba wrote as comment, you should watch out for schema names like "MYSCHEMA"."TABLENAME" and other references.
If you got too much to copy you may consider writing a block where you automatically read the data of the old schema and create it automatically in the new one.
You can get the data of (nearly) everything with, i.e. procedures:
select * from all_source where owner = 'OLDSCHEMANAME' and type = 'PROCEDURE';
and use it like this:
begin
....
select listagg(text, '') within group (order by line) into proc_code
from all_source
where owner = 'OLDSCHEMANAME'
and type = 'PROCEDURE'
group by name;
execute immediate 'create or replace ' || proc_code; -- perhaps you need to remove the last ';' here
...
end;
Please note that this code is only meant as hint and doesn't need to be taken exactly that way. Also, you may still get errors due to non existing objects, wrong schema references etc..
To get the ddl of a table one may use select dbms_metadata.get_ddl('TABLE','Table_name','Schema_Name') from dual;.
By googling dbms_metadata.get_ddl you might get more info on the DBMS_METADATA-package and how to use it correctly.
As already stated, there is no mechanism to copy one object ( procedure , function or package, etc ) to another schema. One alternative is using all_source, but I prefer DBMS_METADATA because allows you to transfer all dependencies, like for example privileges. Imagine I need to copy a procedure but I need to keep the privileges, with this package I can get everything.
Example
SQL> create procedure myschema1.my_procedure ( p1 number )
2 as
3 var1 number := p1;
4 begin
5 select 1 into var1 from dual;
6 end;
7 /
Procedure created.
SQL> grant execute on myschema1.my_procedure to myuser ;
Grant succeeded.
Now, let's imagine we want to copy the procedure and its privileges to another schema
SQL> set long 99999999 set lines 200 pages 400
SQL> select dbms_metadata.get_ddl('PROCEDURE','MY_PROCEDURE','MYSCHEMA1') from dual ;
DBMS_METADATA.GET_DDL('PROCEDURE','MY_PROCEDURE','MYSCHEMA1')
--------------------------------------------------------------------------------
CREATE OR REPLACE EDITIONABLE PROCEDURE "MYSCHEMA1"."MY_PROCEDURE" ( p1 number )
as
var1 number := p1;
begin
select 1 into var1 from dual;
end;
But, imagine you don't want quotation and neither the editionable argument
SQL> select
replace(dbms_metadata.get_ddl('PROCEDURE','MY_PROCEDURE','MYSCHEMA1','11.2.0'),'"','') as ddl from dual ;
DDL
--------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE MYSCHEMA1.MY_PROCEDURE ( p1 number )
as
var1 number := p1;
begin
select 1 into var1 from dual;
end;
Then to get the final command with the new schema owner, we use regexp_replace to replace the first occurrence
SQL> select regexp_replace(replace(dbms_metadata.get_ddl('PROCEDURE','MY_PROCEDURE','MYSCHEMA1','11.2.0'),'"',''),'MYSCHEMA1','MYSCHEMA2',1,1)
2 as ddl from dual ;
DDL
--------------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE MYSCHEMA2.MY_PROCEDURE ( p1 number )
as
var1 number := p1;
begin
select 1 into var1 from dual;
end;
Finally, we can get all privileges by
SQL> select dbms_metadata.get_dependent_ddl( 'OBJECT_GRANT' , 'MY_PROCEDURE' , 'MYSCHEMA1' ) from dual ;
DBMS_METADATA.GET_DEPENDENT_DDL('OBJECT_GRANT','MY_PROCEDURE','MYSCHEMA1')
--------------------------------------------------------------------------------
GRANT EXECUTE ON "MYSCHEMA1"."MY_PROCEDURE" TO "MYUSER"
Remember to apply at session level before to start some settings to enhance dbms_metadata output:
begin
DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'SQLTERMINATOR', true);
DBMS_METADATA.set_transform_param (DBMS_METADATA.session_transform, 'PRETTY', true);
end;
I need to import/export a package body/spec into a .sql or .pkb file using only sql plus commands.
I tried to execute the standard select but this only display it in the console, but I need the file to modify.
Also I need to do the opposite, that is to import a .sql/.pks/.pkb file to the database in order to apply changes.
If you want to do that using SQL*Plus, then - as you were told - spool seems to be a natural option. Here's an example, see whether it helps.
First, I'll create a simple package:
SQL> create or replace package pkg_test as
2 function f_today return date;
3 end;
4 /
Package created.
SQL> create or replace package body pkg_test as
2 function f_today return date is
3 begin
4 return sysdate;
5 end;
6 end;
7 /
Package body created.
SQL> select pkg_test.f_today from dual;
F_TODAY
-------------------
02.09.2019 22:28:56
SQL>
In order to create a nice output file:
there are some SQL*Plus settings that should be set
as you want to export a package, we'll query user_source
it doesn't contain create (or replace) so I'll select it separately
the same goes for the terminating slash /
All that will be stored in a .SQL file. If you run those commands directly, the export file will contain select statements as well and that's something you'd want to avoid.
Spool.sql file:
set heading off
set feedback off
set pagesize 0
set termout off
set trimout on
set trimspool on
set recsep off
set linesize 120
spool pkg_test.sql
select 'create or replace' from dual;
select text from user_source
where name = 'PKG_TEST'
and type = 'PACKAGE'
order by line;
select '/' from dual;
select 'create or replace' from dual;
select text from user_source
where name = 'PKG_TEST'
and type = 'PACKAGE BODY'
order by line;
select '/' from dual;
spool off;
Let's run it; because of all those SET commands, you won't actually see anything; the SQL> prompt will be all, as if nothing happened:
SQL> #spool
SQL>
But, if you check what's written in pkg_test.sql file, you'll see the package:
SQL> $type pkg_test.sql
create or replace
package pkg_test as
function f_today return date;
end;
/
create or replace
package body pkg_test as
function f_today return date is
begin
return sysdate;
end;
end;
/
SQL>
Looks OK, so - to answer your second question (how to import it back) - just run it. I'll exit SQL*Plus first; otherwise - again because of SET commands - you won't see anything:
SQL> exit
Disconnected from Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
C:\Users\lf>sqlplus scott/tiger
SQL*Plus: Release 11.2.0.2.0 Production on Pon Ruj 2 22:36:06 2019
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> #pkg_test
Package created.
Package body created.
SQL>
For exporting tables
exp <username>/<password> file=tables.dmp tables=(tab1,tab2)
For importing tables
imp <username>/<password> file=tables.dmp tables=(tab1,tab2)
For printing onscreen output in a file simply use
spool <filename> before all your commands to modify your sql outputs as report and spool off after sql commands as
Spool file.txt
SELECT * FROM TABLE
SPOOL OFF
I'm attempting to write a simple query where I declare some variables and then use them in a select statement in Oracle. I've been able to do this before in SQL Server with the following:
DECLARE #date1 DATETIME
SET #date1 = '03-AUG-2010'
SELECT U.VisualID
FROM Usage u WITH(NOLOCK)
WHERE U.UseTime > #Date1
From the searching I've done it appears you can not declare and set variables like this in Select statements. Is this right or am I mssing something?
From the searching I've done it appears you can not declare and set variables like this in Select statements. Is this right or am I missing something?
Within Oracle PL/SQL and SQL are two separate languages with two separate engines. You can embed SQL DML within PL/SQL, and that will get you variables. Such as the following anonymous PL/SQL block. Note the / at the end is not part of PL/SQL, but tells SQL*Plus to send the preceding block.
declare
v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY');
v_Count number;
begin
select count(*) into v_Count
from Usage
where UseTime > v_Date1;
dbms_output.put_line(v_Count);
end;
/
The problem is that a block that is equivalent to your T-SQL code will not work:
SQL> declare
2 v_Date1 date := to_date('03-AUG-2010', 'DD-Mon-YYYY');
3 begin
4 select VisualId
5 from Usage
6 where UseTime > v_Date1;
7 end;
8 /
select VisualId
*
ERROR at line 4:
ORA-06550: line 4, column 5:
PLS-00428: an INTO clause is expected in this SELECT statement
To pass the results of a query out of an PL/SQL, either an anonymous block, stored procedure or stored function, a cursor must be declared, opened and then returned to the calling program. (Beyond the scope of answering this question. EDIT: see Get resultset from oracle stored procedure)
The client tool that connects to the database may have it's own bind variables. In SQL*Plus:
SQL> -- SQL*Plus does not all date type in this context
SQL> -- So using varchar2 to hold text
SQL> variable v_Date1 varchar2(20)
SQL>
SQL> -- use PL/SQL to set the value of the bind variable
SQL> exec :v_Date1 := '02-Aug-2010';
PL/SQL procedure successfully completed.
SQL> -- Converting to a date, since the variable is not yet a date.
SQL> -- Note the use of colon, this tells SQL*Plus that v_Date1
SQL> -- is a bind variable.
SQL> select VisualId
2 from Usage
3 where UseTime > to_char(:v_Date1, 'DD-Mon-YYYY');
no rows selected
Note the above is in SQLPlus, may not (probably won't) work in Toad PL/SQL developer, etc. The lines starting with variable and exec are SQLPlus commands. They are not SQL or PL/SQL commands. No rows selected because the table is empty.
I have tried this and it worked:
define PROPp_START_DT = TO_DATE('01-SEP-1999')
select * from proposal where prop_start_dt = &PROPp_START_DT
The SET command is TSQL specific - here's the PLSQL equivalent to what you posted:
v_date1 DATE := TO_DATE('03-AUG-2010', 'DD-MON-YYYY');
SELECT u.visualid
FROM USAGE u
WHERE u.usetime > v_date1;
There's also no need for prefixing variables with "#"; I tend to prefix variables with "v_" to distinguish between variables & columns/etc.
See this thread about the Oracle equivalent of NOLOCK...
Try the to_date function.
Coming from SQL Server as well, and this really bugged me. For those using Toad Data Point or Toad for Oracle, it's extremely simple. Just putting a colon in front of your variable name will prompt Toad to open a dialog where you enter the value on execute.
SELECT * FROM some_table WHERE some_column = :var_name;
I want to write reusable code and need to declare some variables at the beginning and reuse them in the script, such as:
DEFINE stupidvar = 'stupidvarcontent';
SELECT stupiddata
FROM stupidtable
WHERE stupidcolumn = &stupidvar;
How can I declare a variable and reuse it in statements that follow such as in using it SQLDeveloper.
Attempts
Use a DECLARE section and insert the following SELECT statement in BEGIN and END;. Acces the variable using &stupidvar.
Use the keyword DEFINE and access the variable.
Using the keyword VARIABLE and access the the variable.
But I am getting all kinds of errors during my tries (Unbound variable, Syntax error, Expected SELECT INTO...).
There are a several ways of declaring variables in SQL*Plus scripts.
The first is to use VAR, to declare a bind variable. The mechanism for assigning values to a VAR is with an EXEC call:
SQL> var name varchar2(20)
SQL> exec :name := 'SALES'
PL/SQL procedure successfully completed.
SQL> select * from dept
2 where dname = :name
3 /
DEPTNO DNAME LOC
---------- -------------- -------------
30 SALES CHICAGO
SQL>
A VAR is particularly useful when we want to call a stored procedure which has OUT parameters or a function.
Alternatively we can use substitution variables. These are good for interactive mode:
SQL> accept p_dno prompt "Please enter Department number: " default 10
Please enter Department number: 20
SQL> select ename, sal
2 from emp
3 where deptno = &p_dno
4 /
old 3: where deptno = &p_dno
new 3: where deptno = 20
ENAME SAL
---------- ----------
CLARKE 800
ROBERTSON 2975
RIGBY 3000
KULASH 1100
GASPAROTTO 3000
SQL>
When we're writing a script which calls other scripts it can be useful to DEFine the variables upfront. This snippet runs without prompting me to enter a value:
SQL> def p_dno = 40
SQL> select ename, sal
2 from emp
3 where deptno = &p_dno
4 /
old 3: where deptno = &p_dno
new 3: where deptno = 40
no rows selected
SQL>
Finally there's the anonymous PL/SQL block. As you see, we can still assign values to declared variables interactively:
SQL> set serveroutput on size unlimited
SQL> declare
2 n pls_integer;
3 l_sal number := 3500;
4 l_dno number := &dno;
5 begin
6 select count(*)
7 into n
8 from emp
9 where sal > l_sal
10 and deptno = l_dno;
11 dbms_output.put_line('top earners = '||to_char(n));
12 end;
13 /
Enter value for dno: 10
old 4: l_dno number := &dno;
new 4: l_dno number := 10;
top earners = 1
PL/SQL procedure successfully completed.
SQL>
Try using double quotes if it's a char variable:
DEFINE stupidvar = "'stupidvarcontent'";
or
DEFINE stupidvar = 'stupidvarcontent';
SELECT stupiddata
FROM stupidtable
WHERE stupidcolumn = '&stupidvar'
upd:
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Aug 25 17:13:26 2010
Copyright (c) 1982, 2005, Oracle. All rights reserved.
SQL> conn od/od#etalon
Connected.
SQL> define var = "'FL-208'";
SQL> select code from product where code = &var;
old 1: select code from product where code = &var
new 1: select code from product where code = 'FL-208'
CODE
---------------
FL-208
SQL> define var = 'FL-208';
SQL> select code from product where code = &var;
old 1: select code from product where code = &var
new 1: select code from product where code = FL-208
select code from product where code = FL-208
*
ERROR at line 1:
ORA-06553: PLS-221: 'FL' is not a procedure or is undefined
In PL/SQL v.10
keyword declare is used to declare variable
DECLARE stupidvar varchar(20);
to assign a value you can set it when you declare
DECLARE stupidvar varchar(20) := '12345678';
or to select something into that variable you use INTO statement, however you need to wrap statement in BEGIN and END, also you need to make sure that only single value is returned, and don't forget semicolons.
so the full statement would come out following:
DECLARE stupidvar varchar(20);
BEGIN
SELECT stupid into stupidvar FROM stupiddata CC
WHERE stupidid = 2;
END;
Your variable is only usable within BEGIN and END so if you want to use more than one you will have to do multiple BEGIN END wrappings
DECLARE stupidvar varchar(20);
BEGIN
SELECT stupid into stupidvar FROM stupiddata CC
WHERE stupidid = 2;
DECLARE evenmorestupidvar varchar(20);
BEGIN
SELECT evenmorestupid into evenmorestupidvar FROM evenmorestupiddata CCC
WHERE evenmorestupidid = 42;
INSERT INTO newstupiddata (newstupidcolumn, newevenmorestupidstupidcolumn)
SELECT stupidvar, evenmorestupidvar
FROM dual
END;
END;
Hope this saves you some time
If you want to declare date and then use it in SQL Developer.
DEFINE PROPp_START_DT = TO_DATE('01-SEP-1999')
SELECT *
FROM proposal
WHERE prop_start_dt = &PROPp_START_DT
The question is about to use a variable in a script means to me it will be used in SQL*Plus.
The problem is you missed the quotes and Oracle can not parse the value to number.
SQL> DEFINE num = 2018
SQL> SELECT &num AS your_num FROM dual;
old 1: SELECT &num AS your_num FROM dual
new 1: SELECT 2018 AS your_num FROM dual
YOUR_NUM
----------
2018
Elapsed: 00:00:00.01
This sample is works fine because of automatic type conversion (or whatever it is called).
If you check by typing DEFINE in SQL*Plus, it will shows that num variable is CHAR.
SQL>define
DEFINE NUM = "2018" (CHAR)
It is not a problem in this case, because Oracle can deal with parsing string to number if it would be a valid number.
When the string can not parse to number, than Oracle can not deal with it.
SQL> DEFINE num = 'Doh'
SQL> SELECT &num AS your_num FROM dual;
old 1: SELECT &num AS your_num FROM dual
new 1: SELECT Doh AS your_num FROM dual
SELECT Doh AS your_num FROM dual
*
ERROR at line 1:
ORA-00904: "DOH": invalid identifier
With a quote, so do not force Oracle to parse to number, will be fine:
17:31:00 SQL> SELECT '&num' AS your_num FROM dual;
old 1: SELECT '&num' AS your_num FROM dual
new 1: SELECT 'Doh' AS your_num FROM dual
YOU
---
Doh
So, to answer the original question, it should be do like this sample:
SQL> DEFINE stupidvar = 'X'
SQL>
SQL> SELECT 'print stupidvar:' || '&stupidvar'
2 FROM dual
3 WHERE dummy = '&stupidvar';
old 1: SELECT 'print stupidvar:' || '&stupidvar'
new 1: SELECT 'print stupidvar:' || 'X'
old 3: WHERE dummy = '&stupidvar'
new 3: WHERE dummy = 'X'
'PRINTSTUPIDVAR:'
-----------------
print stupidvar:X
Elapsed: 00:00:00.00
There is an other way to store variable in SQL*Plus by using Query Column Value.
The COL[UMN] has new_value option to store value from query by field name.
SQL> COLUMN stupid_column_name new_value stupid_var noprint
SQL> SELECT dummy || '.log' AS stupid_column_name
2 FROM dual;
Elapsed: 00:00:00.00
SQL> SPOOL &stupid_var.
SQL> SELECT '&stupid_var' FROM DUAL;
old 1: SELECT '&stupid_var' FROM DUAL
new 1: SELECT 'X.log' FROM DUAL
X.LOG
-----
X.log
Elapsed: 00:00:00.00
SQL>SPOOL OFF;
As you can see, X.log value was set into the stupid_var variable, so we can find a X.log file in the current directory has some log in it.
Just want to add Matas' answer.
Maybe it's obvious, but I've searched for a long time to figure out that the variable is accessible only inside the BEGIN-END construction, so if you need to use it in some code later, you need to put this code inside the BEGIN-END block.
Note that these blocks can be nested:
DECLARE x NUMBER;
BEGIN
SELECT PK INTO x FROM table1 WHERE col1 = 'test';
DECLARE y NUMBER;
BEGIN
SELECT PK INTO y FROM table2 WHERE col2 = x;
INSERT INTO table2 (col1, col2)
SELECT y,'text'
FROM dual
WHERE exists(SELECT * FROM table2);
COMMIT;
END;
END;
In Toad I use this works:
declare
num number;
begin
---- use 'select into' works
--select 123 into num from dual;
---- also can use :=
num := 123;
dbms_output.Put_line(num);
end;
Then the value will be print to DBMS Output Window.
Reference to here and here2.
Here's your answer:
DEFINE num := 1; -- The semi-colon is needed for default values.
SELECT &num FROM dual;
You can use a with clause and move filter criteria from a where to a join.
It helps here: Oracle SQL alternative to using DEFINE.
with
mytab as (select 'stupidvarcontent' as myvar from dual)
SELECT
stupiddata
FROM
stupidtable a
inner join
mytab b
on
a.stupidcolumn = b.myvar
WHERE ...;
It works in Oracle 12R2.
It works for one SQL command only.
It is standard ANSI notation.
I'm using it in SQL Developer.
One possible approach, if you just need to specify a parameter once and replicate it in several places, is to do something like this:
SELECT
str_size /* my variable usage */
, LPAD(TRUNC(DBMS_RANDOM.VALUE * POWER(10, str_size)), str_size, '0') rand
FROM
dual /* or any other table, or mixed of joined tables */
CROSS JOIN (SELECT 8 str_size FROM dual); /* my variable declaration */
This code generates a string of 8 random digits.
Notice that I create a kind of alias named str_size that holds the constant 8. It is cross-joined to be used more than once in the query.
Sometimes you need to use a macro variable without asking the user to enter a value. Most often this has to be done with optional script parameters. The following code is fully functional
column 1 noprint new_value 1
select '' "1" from dual where 2!=2;
select nvl('&&1', 'VAH') "1" from dual;
column 1 clear
define 1
Similar code was somehow found in the rdbms/sql directory.