Chapter 2. Creating and Running PL/SQL Code
2.1 SQL*Plus
2.1.5 Other SQL*Plus Tasks
There are dozens of commands specific to SQL*Plus, but I only have space to mention a few more that are particularly important or particularly confusing. For a thorough treatment of this venerable product, you might want to get a copy of Jonathan Gennick's book Oracle SQL*Plus: The Definitive Guide (O'Reilly) or, for quick reference, his Oracle SQL*Plus Pocket Reference.
2.1.5.1 Setting your preferences
As with many command-line environments, you can change the behavior of SQL*Plus by changing the value of some of its built-in variables and settings. We've already seen one example, the SET SERVEROUTPUT statement. There are many options on the SQL*Plus SET command, such as SET SUFFIX (changes the default file extension) and SET LINESIZE n (sets the maximum number of characters in each displayed line before wrapping). To see all the SET values applicable to your current session, use the command:
SQL> SHOW ALL
If you're using the GUI version of SQL*Plus, you can also view and set these preferences by choosing the Options Environment menu option.
SQL*Plus also has the ability to create and manipulate its own in-memory variables, and it sets aside a few special variables that will affect its behavior. Actually, there are two separate types of variables in SQL*Plus: DEFINEs and bind variables. To assign a value to a DEFINE variable, you can use the DEFINE command:
SQL> DEFINE x = "the answer is 42"
To view the value of x, specify:
SQL> DEFINE x
DEFINE X = "the answer is 42" (CHAR)
You would refer to such a variable using an ampersand (&). SQL*Plus does a simple substitution before sending the statement to Oracle, so you may need single-quote marks around it.
SELECT '&x' FROM DUAL;
For bind variables, you firstdeclare the variable. Then you can use it in PL/SQL, and display it using the SQL*Plus PRINT command:
SQL> VARIABLE x VARCHAR2(10) SQL> BEGIN
2 :x := 'hullo';
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> PRINT :x
X
--- hullo
This can get a little bit confusing because there are now two different "x" variables, one that has been DEFINEd and one that has been declared.
SQL> SELECT :x, '&x' FROM DUAL;
old 1: SELECT :x, '&x' FROM DUAL
new 1: SELECT :x, 'the answer is 42' FROM DUAL
:X 'THEANSWERIS42' --- --- hullo the answer is 42
Just remember that DEFINEs are always character strings expanded by SQL*Plus, and declared variables are used as true bind variables in SQL and PL/SQL.
The "Current Directory" in SQL*Plus
Any time you launchSQL*Plus from an operating system command prompt, SQL*Plus treats the operating system's current directory as its own current directory. In other words, if you start up using:
C:\BILL\FILES> sqlplus
then any file operations inside SQL*Plus (like opening or running a script) will default to the directory C:\BILL\FILES.
The same is true if you start the GUI version from the operating system prompt with the command:
C:\BILL\FILES> sqlplusw
If you use a shortcut or menu option to launch SQL*Plus, the "current" directory is the one the operating system associates with the launch mechanism. So how would you change the current directory once you're inside SQL*Plus? Depends on the version. In the console program, you can't do it. You have to exit, change directories in the operating system, and restart SQL*Plus. In the GUI version, though, completing a File Open or File Save menu command will have the side effect of changing the current directory. If you're running iSQL*Plus, the concept of the current directory is relevant only in the browser's file save and retrieve dialogs, so the behavior will vary by browser.
2.1.5.2 Saving output to a file
Frequently, you will want to save output from aSQL*Plus session to a file—perhaps because you are generating a report, or because you want a record of your actions, or because you are dynamically generating commands to execute later. At any rate, an easy way to do this in SQL*Plus is to use its SPOOL command:
SQL> SPOOL report01.txt SQL> @run_report
...output scrolls past and gets written to the file report01.txt...
SQL> SPOOL OFF
The first command, SPOOL report01.txt, tells SQL*Plus to save everything from that point forward into the file report01.txt. The last command, SPOOL OFF, tells SQL*Plus to stop saving the output and to close the file.
The SPOOL command works fine in the GUI version of SQL*Plus, but it does not work explicitly when using iSQL*Plus. Instead, save output to a file by setting the iSQL*Plus "Output:" drop- down menu to "File."
2.1.5.3 Exiting SQL*Plus
To exit SQL*Plus and return to the operating system, use the EXIT command:
SQL> EXIT
If you happen to be spooling a file when you exit, SQL*Plus will stop spooling and close it.
What happens if you exit with any pending (uncommitted) changes to the database? These changes are normally caused by running SQL or PL/SQL, which manipulates data in the database but is not followed by an explicit COMMIT or ROLLBACK. So what happens to the pending transactions depends on the AUTOCOMMIT setting. The default, AUTOCOMMIT ON, will attempt to commit any uncommitted changes. If you have changed the default by using:
SQL> SET AUTOCOMMIT OFF
then Oracle will "roll back" any uncommitted changes.
To disconnect from the database but remain connected to SQL*Plus, use the command DISCONNECT, which will look something like this in action:
SQL> DISCONNECT
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options JServer Release 9.2.0.1.0 - Production
SQL>
Why might you want to use DISCONNECT? If you're writing a script that changes connections in midstream, it's safer to disconnect before reconnecting. Otherwise, if you happen to be using operating system authentication, the script might reconnect itself automatically . . . maybe to the wrong account.
2.1.5.4 Editing a statement
SQL*Plus keeps the most recently issued statement in a buffer, and you can edit this statement using either the built-in line editor (which is sort of a pain unless you're an old gray-haired programmer like me) or an external editor of your choosing. To start with, I'll show how to set and use an external editor.
Use the EDIT command to have SQL*Plus save the buffer to a file, temporarily pause SQL*Plus, and invoke the editor:
SQL> EDIT
By default, the file will be saved with the name afiedt.buf, but you can change that with SET EDITFILE. Or, if you want to edit an existing file, just supply its name as an argument to EDIT:
SQL> EDIT errpkg.pkg
Once you've saved the file and exited the editor, the SQL*Plus session will read the contents of the newly edited file into its buffer, and then resume.
The default editors that Oracle assumes are:
For Unix, Linux, and relatives ed
For Microsoft Windows variants Notepad
Although these default values are actually hardcoded into the sqlplus executable, you can easily change them by assigning your own value to the SQL*Plus _EDITOR variable. Here's an example:
SQL> DEFINE _EDITOR = /bin/vi
where /bin/v i is the full path to an editor that's popular among a handful of strange people (yes, me). I recommend using the editor's full pathname here, for security reasons.
If you really want to use the line editor (and it can be really handy), the essential commands you need to know are:
L
List the most recent statement.
n
Make the nth line of the statement the current line.
DEL
Delete the current line.
C /old/new/
In the current line, change the first occurrence of old to new. The delimiter (here a forward slash) can be any arbitrary character.
n text
Make text the current text of line n.
I
Insert a line below the current line. To insert a new line prior to line 1, use a line zero command (e.g., 0 text).
By the way, EDIT works just fine in the GUI version of SQL*Plus, or you can copy and paste as well. If you are using iSQL*Plus, EDIT won't work, but you can either copy and paste from its editing window or use the "Save Script" and "Load Script" buttons.
2.1.5.5 Loading your own custom environment automatically on startup
To customize your SQL*Plus environment and have it assign your preferences from one session to the next, you will want to edit one or both of its auto-startup scripts. The way SQL*Plus behaves on startup is:
1. It searches for the file sqlplus/admin/glogin.sql in the Oracle home directory and, if found, executes any commands it contains. This "global" login script applies to everyone who executes SQL*Plus from that Oracle home, no matter which directory they start in.
2. Next, it searches for and runs the file login.sql in the current directory.
The startup script can contain the same kinds of statements as any other SQL*Plus script: SET commands, SQL statements, column formatting commands, and the like.
Neither file is required to be present. If both files are present, both get executed; in the case of conflicting preferences or variables, the later setting prevails.
Here are a few of my favorite login.sql settings:
REM Number of lines of SELECT statement output before re- printing headers
SET PAGESIZE 999
REM Width of displayed page, expressed in characters SET LINESIZE 132
REM Enable display of DBMS_OUTPUT messages
SET SERVEROUTPUT ON SIZE 1000000 FORMAT WRAPPED
REM Change editor SQL*Plus invokes with "ed" command DEFINE _EDITOR = vi
REM Format misc columns commonly retrieved from data dictionary
COLUMN segment_name FORMAT A30 WORD_WRAP COLUMN object_name FORMAT A30 WORD_WRAP
In iSQL*Plus, there is no notion of the current directory, so there is no way to have a personal login.sql file. Only the glogin.sql on the server running iSQL*Plus has any effect.