In SQL*Plus, both @
and @@
are used to execute SQL scripts, but their primary distinction lies in how they resolve the file path of the script, particularly when dealing with nested scripts.
SQL*Plus provides powerful capabilities for interacting with an Oracle database, and a fundamental feature is the ability to execute external SQL scripts. The @
and @@
commands serve this purpose, allowing users to modularize their SQL code.
The fundamental difference between @
and @@
lies in their approach to resolving the script's path:
@
(Single At Sign)
When you use @
, SQL*Plus attempts to locate the script based on one of the following:
- Current Working Directory: If a relative path is provided (e.g.,
@my_script.sql
), SQLPlus searches for the script relative to the current working directory from which the SQLPlus session was launched. SQLPATH
Environment Variable: SQL*Plus also checks directories specified in theSQLPATH
environment variable.- Absolute Paths: You can provide an absolute path to the script (e.g.,
@/path/to/my_script.sql
), making its location explicit regardless of the current working directory orSQLPATH
.
Example: If you launch SQLPlus from /home/user
and execute @scripts/report.sql
, SQLPlus looks for report.sql
in /home/user/scripts/
. If you then run @/tmp/data_load.sql
, it executes the script from /tmp/data_load.sql
.
@@
(Double At Sign)
The @@
command is specifically designed for executing nested scripts within a larger script structure. Its key characteristic is that it resolves the path of the script relative to the directory of the currently running (calling) script.
- Contextual Path Resolution: This means if script A calls script B using
@@
, SQLPlus will look for script B in a path relative to script A's location, not the current working directory of the SQLPlus session. - Use Case: This behavior is extremely useful for building modular SQL*Plus applications where a main script calls several sub-scripts located in the same directory or a subdirectory relative to the main script. It allows you to move a set of related scripts without breaking their internal references.
Example:
Imagine you have a main script main_app.sql
located in /project/sql_modules/
. Inside main_app.sql
, it calls a sub-script using @@setup/init.sql
. SQLPlus will look for init.sql
in /project/sql_modules/setup/
, because main_app.sql
is located in /project/sql_modules/
. This happens regardless of the directory from which you initially launched your SQLPlus session (e.g., if you launched SQL*Plus from /tmp
and then ran @/project/sql_modules/main_app.sql
).
Practical Implications and Use Cases
The choice between @
and @@
significantly impacts script portability and modularity:
- Modular Scripting:
@@
is indispensable for creating robust, modular SQLPlus applications. You can define a main script that calls various component scripts, and as long as those component scripts are located relative to the main script, the@@
command will always find them, regardless of where SQLPlus was initially launched. - Portability: Scripts using
@@
are more portable. You can copy an entire script hierarchy to a different location on the file system, and as long as the relative paths within the scripts remain valid, they will execute correctly. - Avoiding
CD
Commands: Without@@
, you might frequently need to useCD
(change directory) commands within your scripts or manually navigate to the correct directory before executing nested scripts with@
.@@
eliminates this necessity, streamlining script execution.
Comparison Table
Feature | @ (Single At Sign) |
@@ (Double At Sign) |
---|---|---|
Path Resolution | Relative to current working directory or SQLPATH . Can use absolute paths. |
Relative to the directory of the calling script. |
Primary Use Case | Executing top-level scripts; scripts with absolute paths; simple calls. | Executing nested scripts within a modular application. |
Portability | Less portable for relative paths; depends on SQL*Plus launch directory. | Highly portable; independent of SQL*Plus launch directory. |
Modularity | Can be cumbersome for deeply nested or complex structures. | Ideal for managing complex, hierarchical script structures. |
Context | Current working directory of the SQL*Plus session. | Directory of the script that contains the @@ command. |
When to Use Which
- Use
@
when:- Executing a standalone script directly from the command line or from an absolute path.
- You are certain of the current working directory of your SQL*Plus session.
- The script does not call other scripts, or if it does, those are also referred to by absolute paths or are discoverable via
SQLPATH
.
- Use
@@
when:- You have a main script that calls several sub-scripts, and those sub-scripts are located relative to the main script's directory.
- Building modular, multi-file SQL*Plus applications that need to be robust and portable across different execution environments.
- You want to avoid issues with current working directories when executing nested scripts.
Example Illustrating the Difference
Consider the following directory structure:
/project/
├── main.sql
└── config/
└── setup_env.sql
-
Scenario: Using
@
for a nested call- You launch SQL*Plus from
/tmp
. - You execute
@/project/main.sql
. - Inside
main.sql
, you have the line:@config/setup_env.sql
- Result:
main.sql
executes. However, when it tries to run@config/setup_env.sql
, SQLPlus will search for/tmp/config/setup_env.sql
(relative to the current working directory*/tmp
), leading to an error because the file isn't there.
- You launch SQL*Plus from
-
Scenario: Using
@@
for a nested call- You launch SQL*Plus from
/tmp
. - You execute
@/project/main.sql
. - Inside
main.sql
, you have the line:@@config/setup_env.sql
- Result:
main.sql
executes. When it tries to run@@config/setup_env.sql
, SQLPlus will search for/project/config/setup_env.sql
(relative to the directory of the calling script*,main.sql
, which is in/project/
), andsetup_env.sql
will be found and executed correctly.
- You launch SQL*Plus from
This demonstrates how @@
provides a much more robust and predictable way to handle nested script execution, especially in complex project structures or shared environments where the initial launch directory of SQL*Plus might vary.