oracle SQL plus how to end command in SQL file? - oracle

I have SQL file with few commands.
What it the correct way to end lines in the script?
Is it slash [/] semicolon [;] both?
Is there any diffarent between regular sqls and Stored procedure code?
Thank you

For normal SQL statements, either a / on a line by itself, or a ; at the end of the command, will work fine.
For statements that include PL/SQL code, such as CREATE FUNCTION, CREATE PROCEDURE, CREATE PACKAGE, CREATE TYPE, or anonymous blocks (DECLARE/BEGIN/END), a ; will not execute the command. Since PL/SQL uses semicolons as line terminators, its use as a command terminator must be suppressed in these statements. So in these cases, you must use / to execute the command.
In my experience, people prefer to use the semicolon when possible and use the slash only when required.
Note that for SQLPlus client commands -- such as SET or EXECUTE -- no command terminator is necessary at all, although people often end them with a semicolon out of habit.

; is the way you should end your sql commands, same goes for PLSQL procedures:
select * from dual;
select sysdate from dual;
select table_name from user tables;
exec dbms_output.putline('Hello');

Usually we can use ";" to end sql statement,
but for create functions, triggers, procedures you have to use "/" after ";" to end SQL statement.
"/" might not be required when you use some developers tool like, oracle SQL developer, toad etc, but it should be mandate when you execute your query directly in the linux machine.

Related

Replace characters (&amp) in oracle

I'm trying to use the inbuilt oracle function to replace '&amp' with &. I wrote two functions below but it's not working for me. On running these two in sql developer tool its asking me for input. My requirement is to replace html entities.
select REPLACE('&', '&', '&') from DUAL;
select regexp_replace('&', '&', '&') from DUAL;
Could any one please tell me what's wrong I am doing?.
This should probably be marked as a duplicate, but you need to add this to your script
SET SCAN OFF - that tells us to ignore the & which is used for replacing text when running code in SQLPlus
Once you have that disabled, you can run the queries one at a time with data grids (the first execution mode) or as sqlplus scripts (the second execution mode).
You should execute set define off before executing your query to suppress processing of substitution variables which start by &.
The command set define off will stay active until you enter set define on on your sqlplus session or sql developer worksheet.
thatjeffsmith answer was right but set scan off is tagged obsolete by Oracle. Anyway, it still work.

Jmeter with Oracle 12c: the ";" is unusable

I have a jMeter 3.0 to oracle 12 c using thin connection (used ojdbc 7 and 7_c) and I cannot use the row end line ( ; ). It always returns
Cannot create PoolableConnectionFactory (ORA-00933: SQL command not properly ended
If I remove the ";" from the query everything goes fine. How can I fix this?
I found a workaround for this that avoids having the semi-colon problem:
JDBC Request Query Type needs to be: Update Statement
The query needs to be processed as a block
BEGIN
SQL Statement
END;
There are specific SQL structures that can't be executed as a block but still this enables having legit SQL code within the request and enhances having several statements in the same request.
If you are using JDBC_Request Sampler, you should NOT keep semi-colon as a trailing at the end of a line for SQL query,
Do not enter a trailing semi-colon.
so, without semi-colon, it should work properly and no need to include that.
Reference:
http://jmeter.apache.org/usermanual/component_reference.html#JDBC_Request

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

Generating SQL*Plus script using SQL*Plus

I want to generate a whole lot of SQL*Plus scripts by querying the data dictionary, but I'm hitting some problems and suspect I'm missing something obvious.
For example, when I execute the following in SQL*Plus I get ORA-01756: quoted string not properly terminated:
SQL> SPOOL myscript.sql
SQL> SELECT q'[SPOOL log
2 SELECT COUNT(*) FROM DUAL;
ERROR:
ORA-01756: quoted string not properly terminated
I tried using the line continuation character to avoid this error, but it puts the continuation character into the output:
SQL> SELECT q'[SPOOL log
2 SELECT COUNT(*) FROM DUAL; -
3 PROMPT Done.
4 ]' FROM DUAL;
SPOOL log
SELECT COUNT(*) FROM DUAL; -
PROMPT Done.
Notice how the output has the - after DUAL;? I don't want that in the generated script.
One way I can get around this is to concatenate a lot of CHR() function calls to generate semicolons and linefeeds; but I hope I don't have to because these scripts being generated are very long, and having bits like ]'||CHR(59)||CHR(10)||q'[ scattered throughout the code makes it look very ugly and a pain to troubleshoot.
(I'm using SQL*Plus Release 11.2.0.1.0 Production, connecting to an 11gR2 instance.)
The problem is that SQL*Plus is interpreting your first ; as the terminator for the command. You may have noticed that if you write your commands to a text file and execute that (or edit it in a text editor from with SQL*Plus) it works.
To make it work with live typing, if you really want to do that (seems unlikely if they're going to be very long!), you can turn off the automatic detection of the terminator with SET SQLTERMINATOR off. Note that you'll have to tell SQL*Plus that you're done and that it should execute with the / instruction as the second ; is ignored as well.
SQL> SPOOL myscript.sql
SQL> SET SQLTERMINATOR off
SQL> SELECT q'[SPOOL log
2 SELECT COUNT(*) FROM DUAL;
3 PROMPT Done.
4 ]' FROM DUAL
5 /
SPOOL log
SELECT COUNT(*) FROM DUAL;
PROMPT Done.
If you're building these from the data dictionary, another option is to use PL/SQL to do the queries and manipulations and dbms_output to produce the output you're gong to spool, as long as the final file size won't exceed the buffer limits.
When I want to create a script from within the DB I tend to prefer writing a file using the UTL_FILE package instead of spooling the output of SQL*Plus. It isn't exactly what you want, but I find the control to be far less troublesome than trying to write sql scripts that format properly.
You can use getddl in dbms_metada package or mine package:
http://github.com/xtender/XT_SVN
You need to see http://download.oracle.com/docs/cd/A97630_01/server.920/a90842/ch13.htm
SET CMDS[EP] {;|c|ON|OFF}
Sets the non-alphanumeric character used to separate multiple SQL*Plus commands entered on one line to c. ON or OFF controls whether you can enter multiple commands on a line. ON automatically sets the command separator character to a semicolon (;).
For future reference for myself, instead of messing around with SET SQLTERMINATOR off when using sql plus use the following bellow so you don't need to worry about the any special sql terminator character inside the string literal body.
BEGIN
INSERT INTO SOME_TABLE (q'[
Now;
You;
Can '
Do "'"';' ;;;
any character? *
]');
END;
/

How do I debug Oracle dynamic sql in sqlplus?

I have a PL/SQL statement that uses EXECUTE IMMEDIATE to execute a query. However, I'm having difficulty figuring out how to even get the text of the query that's being executed. I can't use dbms_output as the query is greater than 255 characters. Is there any way to make sqlplus echo the string that's passed in to EXECUTE IMMEDIATE?
What version of Oracle are you using? 255 is the default line length for DBMS_OUTPUT.PUT_LINE(). Before 10g we could display 1048 characters in a single call. Since then it is 32K.
Alternatively you should consider using an IDE which supports DBMS_DEBUG. For instance, SQL Developer does so, and it is free from Oracle. Find out more.
You can try to attach a profiler to the database (honestly I have only done that for SqlServer) and run the procedure since the profiler will show any query made to the DB you will be able to pick it up there and do the necessary debugging.
Hope it helps..
How to print large strings N characters at a time.
Modify to suit your needs.
FOR i IN 0..10 LOOP
dbms_output.put_line(substr(my_very_long_string,i*100+1,100));
END LOOP;
You could insert the string into a logging/temporary table and examine it.

Resources