How to load an external script file - oracle

Let's say I've got a large script and want to cut it into pieces and then load the pieces from a main script file.
The question is how to load and execute an external script using plain SQL in Oracle DBMS or PL/SQL from another script file?

For SQL*plus, you can use:
#filename.sql
or
##filename.sql
Please realize that # is a SQL*plus command - not a SQL or PL/SQL command. SO you cannot use this from inside a PL/SQL stored procedure - it would not make much sense either, as essential context like current working direcory is absent in that case.
Form inside a stored procedure, you could in principle load external code using dynamic sql, but a better way to break up a stored procedure is to break it into several smaller stored procedures. If you like you can group those togehter in a package (see http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10472/packages.htm#CIHIJECJ)

Related

PLSQL "give" script but not allow users to read

I'm new to pl/sql and my question is: is it possible to "compile" a script in sql plus or sql developer and give the file to other person in order to allow other to execute the code but not allowing them to read the code?
It sounds like you are talking about the Oracle wrap utility (a separate command-line application that is part of your Oracle client install and not a part of SQL Developer) or the dbms_ddl.wrap function which you could invoke from SQL Developer. These create obfuscated statements that will create a stored procedure (or package or function) that behaves normally but where the text in the data dictionary is not human readable. The wrap utility doesn't provide perfect security-- there are unwrapping tools and presentations on the internet that would let an attacker unwrap the code you hand them. And you can often figure out what the unwrapped code is really doing by looking at other data dictionary views (v$sql will show the unwrapped SQL statements that are executed for example) or by tracing a session.
It depends also of definition of the word give. You can store PL/SQL code in the database. Give users right to execute it, to see the source code of the package header, but not to see the source of package body. But of course DBAs can read it, They can also trace it (even if it is wrapped).
Also note that PL/SQL packages are wrapped in a different way than PL/SQL procedures. As of 11g packages are wrapped using simple one-to-one byte substitution. While for PL/SQL procedures, there is stored obfuscated bytecode of DIANA virtual machine. AFAIK there is no accessible unwrap for PL/SQL procedures, it is much harder to reverse engineer.

How to execute all pl/sql files in a directory (install_db script)

I'm trying to implement what is said in this paper: http://www.rwijk.nl/AboutOracle/psdua.pdf
(in a few words, I've sql files creating database objects such as tables, priviledges, sequences, indexes etc. in directories 'myApp/tables/', 'myApp/priviledges/', 'myApp/sequences/'... and I want to execute these files to install my database).
There is an example of what should look like the install_db.sql script p11-12 but the execution of the sql files is hard coded:
##&tables_path.SCA_OPNAMES.sql
##&tables_path.SCA_METERSTANDEN.sql
##&sequences_path.SCA_MSD_SEQ1.sql
##&sequences_path.SCA_ONE_SEQ1.sql
##&indexes_path.MSD_ONE_FK1_I.sql
##&privs_path.privileges.sql &SCHEMAPREFIX
I would prefer to execute all the files in a given directory but it seems to be tricky.
There is a nice post to get a list of files in a directory: https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:439619916584 which is working well.
So at this point, I've a list of files in a temporary table and now I want to execute these files.
Suprisingly I'm stuck with this step.
I would like to do something like this:
for tab in (select filename from dir_list) loop
#tab.filename;
end loop;
but it's not working since I'm not in a pl/sql procedure. Can I execute files from a pl/sql procedure? The answer is not very clear to me and I read opposite answers to this question.
Thank you for your help,
You could try using dynamic PL/SQL.
For example, write a PL/SQL procedure that would
- read the contents of the file into a variable and then
- execute the PL/SQL using the EXECUTE IMMEDIATE dynamic SQL construct.

Procedure to export table to multiple csv files

I am working with an Oracle database - the only way I have to access it is through SQL Developer. Part of my work involves exporting large tables to csv files to pass to another group. Since this is mostly babysitting the system, I've been looking for a way to automate the export process.
What I would like is to have a procedure like so:
PROCEDURE_EXAMPLE(table_in in VARCHAR2, file_out in VARCHAR2)
where table_in is the table I need to export, and it exports the table to a series of csv files titled "file_out_1.csv" "file_out_2.csv", etc.. each with no more than 5 million rows.
Is it possible to create a procedure like this?
You can using the UTL_FILE package. You can only read files that are accessible from the server on which your database instance is running.
See http://www.devshed.com/c/a/Oracle/Reading-Text-Files-using-Oracle-PLSQL-and-UTLFILE/
and Oracle write to file
I was just posting an answer here: Procedure to create .csv ouput
Using the UTL_FILE package is often not an option, because it can only create files on the server and is rather limited.
If you can only use SQL Developer, you can change the window to a command window and then you can run the commands just as I described in the other thread.
In the SQL Window right click -> Change Window to -> Command Window
set term off ...
spool c:\tmp\t\txt
select ...
spool off

Run SCRIPT from PL/SQL Block

How to use "START SCRIPT" in pl/sql block ?
I want to use something like this
declare
begin
proc(para1,para2);
execute immediate 'start prompt1' ;
end;
/
Also I want to know , can i get a value from prompt1 into my PL/SQL block where am calling the script ? Because I need to use the value to perform some operations in the PL/SQL block.
It is 2012 2017. Scripts are a clunky and brittle hangover from the last millennium. Oracle has a fantastic range of functionality we can execute in PL/SQL, plus there's Java Stored Procedures, and there's scheduling for starting jobs. Other than running DDL to create or amend schemas there is hardly any need for scripts in an Oracle database environment; even DDL scripts should be triggered from an external client, probably a build tool such as TeamCity.
In particular I would regard attempting to run a SQL script from a PL/SQL program as an architectural failure. What are you doing with the script which you cannot do with a stored procedure?
As for passing input to a stored procedure, that's what parameters are for. PL/SQL isn't interactive, we need a client to enter the values. Depending on the scenario this can be done asynchronously (values in a file or a table) or synchronously (calling the stored procedure from SQL*Plus, SQL Developer or a bespoke front end).
Having said all that, in the real world we work with messy architectures with inter-dependencies between the database and the external OS. So what can we do?
We can write a Java Stored Procedure to execute shell commands. This is the venerable solution, having been around since Oracle 8i. Find out more.
In 10g Oracle replace DBMS_JOB with DBMS_SCHEDULER. Once of the enhancements of this tool is its ability to run external jobs i.e. shell scripts. Find out more.
Since Oracle 11g R1 external tables support pre-processor scripts, which run shell commands before querying the table. Find out more.
Note that all these options demand elevated access (grants on DIRECTORY objects, security credentials, etc). These can only be granted by privileged users (i.e. DBAs). Unless our database has an astonishingly lax security configuration there is no way for us to run an arbitrary shell script from PL/SQL.
Finally, it is not clear what benefit you expect from running a SQL script in PL/SQL. Remember that PL/SQL runs on the database server, so it can't see scripts on the client machine. This seems relevant in the light of the requirement to accept user input.
Perhaps the simplest solution is reconfiguration of the original script. Split out the necessary PL/SQL call into a block and then just call the named script:
begin
proc(para1,para2);
end;
/
#prompt1.sql
You can write a pl/sql block in SqlPlus to check for a parameter from a table then execute a script. In the script to be executed (MyScript.sql below), the statement terminators must be ";" instead of "/"
declare
vMyParameter number := 0;
begin
select count(*) into vMyParameter
from MyTable
where MyCheckValue = 'Y';
if vMyParameter = 1 then
#MyFolder/MyScript.sql;
end if;
end;
/
If you're using sql*plus (or a tool that is using it) then you can do something like this:
set serveroutput on
variable a number;
begin
:a := &promt;
dbms_output.put_line(:a);
end;
/
If it runs in batch then you can do:
variable a number;
begin
:a := &1;
dbms_output.put_line(:a);
end;
and get the value for :a as a parameter-
sqlplus sdad/fdsfd#fdggd #<your_script.sql> <val_for_a>
Another practice is to execute on one *.bat with parameters, like:
Example c:/oracle/bin/sqlplus.exe -w #c:/name
sql %1 %2 #c:/output.sql
execute immediate 'start prompt1' ;
Execute immediate is to execute SQL statements , not arbitrary commands.
can i get a value from prompt1 into my PL/SQL block where am calling the script
You can run a run script - but I doubt you can capture input from an SQL script, esp within a PL/SQL block

in which part of stored procedures can set commands be used (declaration or executable)?

at which section we can write the set cmds(i.e like set pagesize 250) in oracle procedures
I see you have a similar question with an "oracle" tag and thought this general orientation might help.
SQL*Plus is a client program that provides an environment for issuing SQL commands to an Oracle database that also has some directives (the SET commands) that control the environment and formatting used for the duration of a session at the client. You may enter PL/SQL code in what are called "anonymous blocks", delimited by BEGIN/END, but this code is parsed at run time and never stored as a procedure in the database even though you are executing procedural code.
To blur the lines somewhat further, PL/SQL code (stored procedures/packages as well as anonymous blocks) may contain a calls to the DBMS_OUTPUT package that produces output, but this output is only visible if executing from a client environment that can receive the output. There are also size limitations to output that comes from DBMS_OUTPUT that can make its use problematic.
If you are trying to produce output from an Oracle database for reporting or post-processing you generally have these Oracle-based options:
If you have access to the database host file system you can use the Oracle UTL_FILE package to write directly to a file. You'll have to code the cursors, loops, and output formatting yourself in a PL/SQL procedure or anonymous block. Although the PL/SQL code will only write to the host filesystem, it can be called from any client.
If you need the output somewhere else and the output will fit within the DBMS_OUTPUT line and buffer limitations, you have the greatest formatting control if you write PL/SQL code that outputs exactly what you want and invoking this PL/SQL with the SQL*Plus SPOOL /SPOOL OFF directives to save the output on the client filesystem.
If your output doesn't fall into the above category (e.g. producing a 100 million row CSV file with 500 character wide lines), you might be able to get what you want by using the appropriate SQL functions in a query to get the results formatted as you need them and then using SQL*Plus SET directives to turn off everything (headings, page breaks, etc) that is not part of the result set (again using SPOOL /SPOOL OFF).
No where.
Those command are sqlplus specific -- never apply to pl/sql.
if you are using sqlplus, you can set them in sqlplus\admin\glogin.sql from within your oracle client install. this will get run whenever you open your sqlplus app. it would not be applied to a single procedure.

Resources