Use the SQL*Plus ACCEPT and PROMPT commands to get input from the user.
Prompting for SQL*Plus Input with ACCEPT and PROMPT
You can design your own prompts using the ACCEPT and PROMPT commands together. ACCEPT gets input from a user and lets you specify a short prompt alongside it. PROMPT simply displays a message, with no input collected at all, and is useful for extended explanatory text before ACCEPT asks its actual question. The diagram below covers the syntax for both:
PROMPT: displays a message to the user. May be abbreviated PRO.
message_text: the message you want PROMPT to display.
ACCEPT: prompts the user for a value and accepts a response. May be abbreviated ACC.
variable_name: the name of the substitution variable in which the user's response is stored.
[NUMBER|CHAR|DATE]: specifies a datatype. NUMBER may be abbreviated NUM.
FORMAT: introduces a format string used to validate the user's input. May be abbreviated FOR.
format_spec: a format string used to validate input, built the same way as the format models used with the COLUMN command.
DEFAULT: introduces a default value, used if the user presses ENTER without responding. May be abbreviated DEF.
default_value: the value used as a default response.
PROMPT: introduces the prompt text within ACCEPT itself.
prompt_text: the text SQL*Plus displays as the prompt.
NOPROMPT: tells SQL*Plus not to display a prompt at all.
HIDE: prevents SQL*Plus from echoing the user's response to the display; useful when prompting for a password.
Although the syntax allows for several options, it is best to write your ACCEPT commands as simply as possible; more on why shortly. Now that you know PROMPT and ACCEPT, you can revisit the previous lesson's script and make it more user-friendly by adding explanatory text and a more descriptive prompt.
Syntax for PROMPT and ACCEPT, Worked Example
PROMPT This script displays a summary of objects owned
PROMPT by a user, telling you how many the user has of
PROMPT each type, and telling you how recently an object
PROMPT of each type was modified.
PROMPT
ACCEPT user_name
PROMPT "What user are you interested in?"
SELECT owner,
object_type,
count(*) object_count,
TO_CHAR(MAX(last_ddl_time),'dd-Mon-yyyy')
last_ddl_time
FROM dba_objects
WHERE owner = '&user_name.'
GROUP BY owner, object_type
ORDER BY owner, object_type;
SQL*Plus ACCEPT and PROMPT in action
The four PROMPT commands display a message reminding the user what the script does, before it asks for anything.
ACCEPT user_name lets the user type in a username.
The quoted text after PROMPT is what ACCEPT actually displays when asking for that username.
&user_name. is replaced by whatever username was typed in when the script ran, using the same substitution mechanics covered in the previous lesson.
Running this script produces output like this:
SQL> @m5l9
This script displays a summary of objects owned
by a user, telling you how many the user has of
each type, and telling you how recently an object
of each type was modified.
What user are you interested in?SYSTEM
old 6: WHERE owner = '&user_name.'
new 6: WHERE owner = 'SYSTEM'
...
Beyond the friendlier prompt itself, ACCEPT provides a real practical benefit: it prevents any value a prior script may have left stored in a variable from being silently reused. ACCEPT guarantees you are actually prompted every time. Simply referencing a variable in a script, the way Lesson 13 covered, does not guarantee a fresh prompt; if that variable was already defined from an earlier command in the same session, SQL*Plus uses the existing value without asking again. ACCEPT always asks.
Why Simpler ACCEPT Commands Are Usually Better
Two reasons are worth understanding before you reach for every option ACCEPT offers.
First, ACCEPT's clause set has genuinely grown over successive SQL*Plus releases, with new clauses added over time. If you are writing scripts meant to run across a range of SQL*Plus versions, aim for the lowest common denominator: PROMPT and HIDE are recognized broadly and safely, while some of the more specialized clauses may not be available everywhere your script might run.
Second, and more fundamentally: the FORMAT and datatype clauses are less useful than they might first appear, because of how ACCEPT actually stores its result. Regardless of what datatype you specify for validation purposes, the value stored in the resulting substitution variable is always text. This is not a guess: Lesson 13's research into ACCEPT's DATE clause confirmed it directly from Oracle's own current documentation, which states plainly that even when ACCEPT validates a reply as a proper date, "the datatype is CHAR." The datatype clause controls what SQL*Plus is willing to accept at the prompt; it does not change what actually ends up stored.
SQL*Plus also does not handle complex format strings especially gracefully, and it is genuinely possible to write a FORMAT specification that rejects every possible input. This shows up most often with format strings containing commas, decimal points, and dollar signs together. Consider this example:
SQL> ACCEPT some_number NUMBER FORMAT 09,999 PROMPT ">"
>23
SP2-0425: "23" does not match input format "09,999"
>23,999
SP2-0425: "23,999" is not a valid number
This example shows the FORMAT and datatype clauses working against each other. Enter a plain valid number and it gets rejected for not matching the format string. Enter a number that does match the format, comma included, and the comma itself prevents SQL*Plus from recognizing it as a valid NUMBER value at all. There is genuinely nothing you can type here that satisfies both checks at once. The SP2-0425 error code and message pattern shown here are confirmed current and accurate; older material describing this exact scenario has sometimes attributed the format-mismatch case specifically to a different error code, which was not independently confirmed in this pass, so the message text above is presented with the confirmed code rather than an unverified one.
Despite this trap, the FORMAT clause remains genuinely useful when kept simple, and thoroughly tested before you rely on it. The lesson here isn't to avoid FORMAT entirely, but to test your exact format string against exactly the kind of input you expect real users to type, rather than assuming a reasonable-looking format string will behave the way you expect.