create large objects in oracle via sqlplus - oracle

I have a view whose DDL definition is many thousands of lines long. Part of our CI process is to drop and recreate views from DDL using SQLPlus called from a command line script.
This works for hundreds of views in the database but the very large view is never created in the target schema. I always manually paste the view creation script into Toad and run it manually after the automated process has completed. This is a drag.
There is no meaningful error message from SQLPlus when the large-view portion of the DDL script is run but I suspect that it fails because of it's size.
Is there a "set" command that I can include at the top of my DDL to tell SQLPlus that it's ok to create large views or am I forever doomed to include a stoopid manual step in the otherwise automatic CI process?

Firstly, use the most recent version of SQLPlus. Its been a long time since I had a piece of code that was too large to be executed through SQLPlus. You can use the InstantClient
I'd also look at re-factoring the view. Look at the WITH clause as that is relatively new and, if the view has evolved over a long period, there's a good chance it can be amended to make use of this

Is there an empty line in the view SQL, or does any line have more than 2499 characters? Either one of these may cause SQL*Plus to behave unexpectedly but not actually fail.
If there is an empty line, Oracle will ignore everything before it and try to run everything after it. (This only applies to SQL, not PL/SQL.) For example, if you have an empty line right after the create view line, the query will run:
SQL> create or replace view newline_in_the_middle as
2
SQL> select * from dual;
D
-
X
A line with >2499 characters will be ignored but Oracle will still try to process the statement without it. This can cause problems but may still result in a valid statement:
SQL> create or replace view long_line as
2 select '...[enter 2500 characters]...' asdf from dual union all
SP2-0027: Input is too long (> 2499 characters) - line ignored
2 select '1' asdf from dual;
View created.
You may have to check the script output very carefully to find these issues.

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.

Prevent commit if execution buffer is not empty

I am looking for a way to avoid a recurrent error of mine, working with SQL scripts that sometimes contain PL/SQL blocks. As you may know, in sqlplus, if you do not add a slash / after a PL/SQL block (Begin ... End;), the block is not executed.
But from my development tools, the lack of slash is not detected until my stuff gets deployed on the testing environment, and it adds confusion and stress to the process.
I had this issue in many places I've worked at, and with many tools. So I wonder if it is possible to configure Oracle sqlplus either to
execute the content of the "buffer" before commits, even if no / is there
raise an error message if "buffer" is not empty when exiting
Another solution would be to change the behaviour of my development tools, I know, but am also looking forward to extend my Oracle knowledge with your permission.
To fix the idea, let's say I deliver script a.sql, that is encapsulated later on into the company's deployment script dpl.sql
dpl.sql simplified (note the importance of the . that kind of hides the issue, but that I cannot change, and is THE thing to work around)
spool dpl.log
#a
.
spool off
a.sql where I forgot the / after my pl/Sql block before of personal inconsistency by design (beauty of Nature)
create table a(n number);
begin
dbms_output.put_line('coucou');
end;
insert into a select 1 from dual ;
commit ;
Result where you see no commit, and no error...
SQL> #dpl
Table dropped.
Table created.
SQL> select count(1) from a ;
COUNT(1)
----------
0
I went through these, to no avail:
When do I need to use a semicolon vs a slash in Oracle SQL?
oracle SQL plus how to end command in SQL file?

what does the "2"mean in SQL*Plus?

I am new to Oracle.
And I have come across a problem.
Firstly,I want to check the privileges of the sysman account:
SQL> select * from dba_sys_privs where grantee='sysman';
no rows selected
I know that it means there is no content in my view dba_sys_privs. But anyway,I have aready built a database. So, I try again, just shortening the statement:
SQL> select * from dba_sys_privs
2
So here are my two questions:
what happened to my database? I have already set up a database
what does the "2" mean? Does it mean the next row or something else?
You have entered a new line character (pressed return) without entering a statement termination i.e. ;. Compare your second statement with the first one you posted. So yes, the 2 means the client is awaiting further input.
To run the second statement, simply enter a slash /
As for why your first statement returned no rows, in Oracle database object names (including users) are in upper-case.
select * from dba_sys_privs where grantee='SYSMAN';
I encountered similar situaion due to my inserts did not work as expected. I used a insert statement followed by "commit;", it just says committed, but when I use sql developer to view the record, I could not find it. So I tried to run select from sqlplus and got a number.
Later DBA told me to skip the "commit", then I could see the exception thrown.

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;
/

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