Шпаргалка по SQL*Plus
SQL*Plus - программа для работы с СУБД Oracle посредством командной строки. Используя SQL*Plus можно выполнять команды SQL и PL/SQL в интерактивном режиме или используя сценарий.
Основное преимущество SLQ*Plus - доступность, т.к. инструмент доступен практически всегда, когда в системе установлен Oracle. При этом это достаточно мощный инструмент, используя который можно решать различные задачи на удаленных машинах.
К написанию этой статьи меня подтолкнула книга "Oracle SQL*Plus: The Definitive Guide, 2nd Edition", написанная Jonathan Gennick. Как обычно, появилось желание систематизировать информацию и представить ее в удобном виде.
При этом сразу считаю нужным оговориться, что я использую SQLplus для написания и выполнения скриптов на удаленных машинах, в этой статье описываю именно используемые для этого команды.
Область возможного использования SQLplus при этом гораздо шире, например - построение отчетов, в том числе в формате HTML.
Параметры, подключение к базе, запуск скриптов
sqlplus /nolog - запуск без интерактивного запроса логина/пароля для входа
-S - молчаливый режим
-L - только одна попытка входа в интерактиве
-V - показать версию SQLplus
-H - отобразить справку
CONNECT gennick@db01 - присоединиться к базе, запросит пароль в интерактиве
HOST - переключиться на командную строку операционной системы, не разрывая соединения с базой (exit - вернет в SQLplus)
sqlplus user/pass@db @script.sql - присоединиться к базе и выполнить скрипт
sqlplus user/pass@db @script.sql arg "arg" - выполнить скрипт с аргументами (будут доступны как &1, &2)
Выполнить несколько строк кода (не передавая отдельный файл со скриптом), unix:
sqlplus -s user/password@db_name <<+EOF
update table set value = 'foo' where id=1;
update table set value = 'bar' where id=2;
commit;
+EOF
Выполнение SQL запросов
Запрос может состоять из нескольких строк, содержать комментарии, но не может содержать внутри пустые строки.
SQL> SELECT * /* All columns */
2 FROM project;
Запрос может быть выполнен тремя способами:
- точка с запятой в конце запроса
SQL> INSERT INTO project
2 /* All columns */
3 (project_id, project_name, project_budget)
4 VALUES (1006,'Mainframe Upgrade',456789)
5 ;
- строка с слешем "/" после запроса
SQL> UPDATE project
2 SET project_budget = 1000000
3 WHERE project_id = 1006
4 /
- пустая строка после запроса (будет помещен в буфер, но не выполнен немедленно)
SQL> DELETE
2 FROM project
3 WHERE project_id = 1006
4
SQL>
SQL> /
1 row deleted.
Выполнение PL/SQL блоков
Пример PL/SQL блока:
SQL> DECLARE
2 X VARCHAR2(12) := 'Hello World!';
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE(X);
5 EXCEPTION
6 WHEN OTHERS THEN
7 DBMS_OUTPUT.PUT_LINE('An error occurred.');
8 END;
9 /
PL/SQL procedure successfully completed.
Правила выполнения PL/SQL блоков:
- Первое слово в PL/SQL блоке должно быть из списка: BEGIN, DECLARE, CREATE PROCEDURE,
CREATE FUNCTION, CREATE TRIGGER, CREATE PACKAGE, CREATE TYPE, CREATE TYPE BODY. Регистр не важен. - Блок может состоять из нескольких строк
- Можно вставлять /* комментарии */, они также могут быть на несколько строк
- Пустые строки не разрешены внутри блока
Сигнал к выполнению блока может быть подан двумя путями:
- Строка, содержащая только слеш "/" после блока - выполнить сразу
SQL> BEGIN
2 NULL;
3 END;
4 /
- Строка, содержащая точку "." после блока - поместить в буфер. Содержимое буфера может быть выведено командой LIST и выполнено, путем указания одиночного слеша "/" или команды RUN.
SQL> BEGIN
2 NULL;
3 END;
4 .
Одиночное выражение PL/SQL может быть выполнено, используя:
EXECUTE plsql_statement
Например, так:
SQL> EXECUTE DBMS_OUTPUT.ENABLE(10000)
PL/SQL procedure successfully completed.
В случае ошибок, при выполнении процедуры, можно отобразить их выполнив команду:
SHOW ERRORS
Работа с переменными
Переменные могут быть заданы двумя способами:
&variable - переменная в скрипте, будет запрошена каждый раз когда встретится в ходе выполнения
&&variable - переменная в скрипте, будет запрошена один раз и сохранена на всю сессию работы с SQLplus
Если уже была определена &&variable, то значение будет подставлено во все дальнейшие переменные как &variable так и &&variable.
Если была определена &&variable, и скрипт запущен повтороно в ходе той же сессии работы с SQLplus - будет использовано старое значение переменной. Чтобы этого избежать - можно запрашивать интерактивный ввод в скрипте принудительно, испольтзуя команду:
ACCEPT table_name CHAR PROMPT 'Enter the table name >'
ACCEPT можно использовать для валидации:
SQL> ACCEPT my_variable NUMBER FORMAT 999 PROMPT 'Enter a number >'
Enter a number >1234
"1234" does not match input format "999"
Enter a number >123
SQL>
Для ввода дат в определенном формате:
ACCEPT my_variable DATE FORMAT 'MM/DD/YY' PROMPT 'Give me a date >'
SQL*Plus поддерживает четыре типа переменных: CHAR, NUMBER, BINARY_FLOAT, and BINARY_DOUBLE. При вводе с клавиатуры переменная будет типа CHAR.
Несмотря на это, можно использовать NEW_VALUE, чтобы задать числовую переменную, полученную как результат запроса.
SQL> COLUMN x NEW_VALUE m y_age
SQL> SELECT 42 x FROM dual;
X
----------
42
SQL> DEFINE my_age
DEFINE MY_AGE = 42 (NUMBER)
Bind-переменные могут использоваться для передачи данных между PL/SQL и SQL блоками:
-- Bind-переменные могут быть определены в скрипте
VARIABLE s_table_name varchar2(30)
-- Можно ссылаться на bind-переменные в PL/SQL block.
BEGIN
:s_table_name := 'EMPLOYEE';
END;
/
-- Bind-переменные могут быть использованы и в SQL запросах.
SELECT index_name FROM user_indexes WHERE table_name = :s_table_name;
-- Bind-переменные хранятся до выхода из SQL*Plus и могут быть использованы в нескольких PL/SQL блоках.
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(:s_table_name);
END;
/
Присвоить bind-переменной значение &-переменной:
DEFINE my_sub_num = 9
VARIABLE my_bind_num NUMBER
EXECUTE :my_bind_num := &my_sub_num;
Вывести значение bind-переменной:
SQL> VAR my_bind_var VARCHAR2(35)
SQL> EXECUTE :my_bind_var := 'Brighten the corner where you are';
PL/SQL procedure successfully completed.
SQL> PRINT my_bind_var
MY_BIND_VAR
-----------------------------------------------------------------
Brighten the corner where you are
Присвоить &-переменной значение bind-переменной:
SQL> DEFINE my_sub_var = ' '
SQL> VAR my_bind_var VARCHAR2(35)
SQL> EXECUTE :my_bind_var := 'Brighten the corner where you are';
PL/SQL procedure successfully completed.
SQL> COLUMN my_bind_var NEW_VALUE my_sub_var
SQL> PRINT my_bind_var
MY_BIND_VAR
----------------------------------------------------------------------
Brighten the corner where you are
SQL> PROMPT &my_sub_var
Brighten the corner where you are
Получаем OUT-параметр процедуры в bind-переменную:
ACCEPT not_can CHAR PROMPT 'Enter a table reference >'
VARIABLE can VARCHAR2(60)
EXECUTE DBMS_UTILITY.CANONICALIZE('¬_can',:can, 60);
COLUMN can HEADING 'Canonicalized Reference IS:'
PRINT can
Условное выполнение в SQLplus:
ACCEPT s_delete_confirm PROMPT 'Delete project hours data (Y/N)?'
DELETE FROM project_hours WHERE UPPER('&&s_delete_confirm') = 'Y';
Пример скрипта, принимающего несколько переменных на вход в формате c возможностью задать дефолтные значения:
sqlplus user/pass@db @script.sql "var=foo; othervar=bar;"
prompt Define parameters
define script_param = ""
column col_script_param new_value script_param noprint
select replace(trim('&&1'), ' ') "col_script_param" from dual;
undef 1
define parse_name_parameter = "var="
select nvl(max(regexp_replace(csv,
'(.*)(&&parse_name_parameter)(.+?)(;|$)(.*)',
'define var="\3";',
1,
1,
'i')),
'define var=default;') r
from (select '&&script_param' csv from dual)
where instr(upper(csv),
upper('&&parse_name_parameter')) != 0;
define parse_name_parameter = "othervar="
select nvl(max(regexp_replace(csv,
'(.*)(&&parse_name_parameter)(.+?)(;|$)(.*)',
'define othervar="\3";',
1,
1,
'i')),
'define othervar=default_other;') r
from (select '&&script_param' csv from dual)
where instr(upper(csv),
upper('&&parse_name_parameter')) != 0;
prompt
prompt var: &&var
prompt othervar: &&othervar
prompt
Настройки выполнения скриптов
Действуют на протяжении сессии в SQLplus.
SET SERVEROUTPUT ON/OFF SIZE 1000000 FORMAT WORD_WRAPPED - отображать вывод dbms_output
(размер буфера, байт) (разделение по строкам для длинного вывода)
SET TERMOUT ON/OFF - включить/отключить вывод на экран терминала
SET ECHO ON/OFF - включить/отключить отображение команд по мере выполнения
SET VERIFY ON/OFF - включить/отключить отображение замененных переменных
например, так:
old 9: AND ui.table_name = UPPER('&table_name')
new 9: AND ui.table_name = UPPER('project_hours')
SET FEEDBACK ON/OFF - включить/отключить вывод результата выполнения команд
например, так:
6 rows selected.
Commit complete.
SET ESCAPE ON/OFF - включить/отключить поиск символов для экранирования
например: SQL> SET ESCAPE ON
SQL> DEFINE friends = "Joe \& Matt"
SET ESCAPE / - задать другой символ экранирования (по умолчанию \)
SET CONCAT ON/OFF - включить/отключить конкатенацию, символ конкатенации по умолчанию - точка "."
например: SQL> DEFINE sql_type = "PL/"
SQL> PROMPT &sql_type.SQL
PL/SQL
SET CONCAT ! - задать другой символ для конкатенации
SET DEFINE ON/OFF - включить/отключить замену переменных (&var, &&var)
Запомнить настройки перед выполнением скрипта и вернуть обратно по завершении выполнения:
STORE SET original_settings REPLACE
... script code here ...
@original_settings
Другие команды
PROMPT Show this text. - вывод текста на экран
REMARK This is a comment. - комментарий в скрипте
REM This is a comment too. - краткая форма записи REMARK
SPOOL some_file.txt - включить вывод выполнения скрипта файл some_file.txt (будет обнулен)
SPOOL some_file.txt APP - включить вывод выполнения скрипта файл some_file.txt (будет дозаписан)
SPOOL OFF - отключить вывод в файл
WHENEVER SQLERROR EXIT - выйти при ошибке SQL
WHENEVER SQLERROR EXIT ROLLBACK - откатить транзакцию и выйти при ошибке SQL
WHENEVER SQLERROR EXIT SQL.SQLCODE - выйти и вернуть код ошибки при ошибке SQL
WHENEVER OSERROR EXIT - команды аналогичны WHENEVER SQLERROR ... - но при ошибке операционной системы
Взаимодействие с unix shell
Обработать результат выполнения SQLplus-скрипта в Unix:
#!/bin/bash
if sqlplus -s user/secret @script.sql
then
echo Success
else
echo Unable to create raise table.
fi
Вернуть код ответа в Unix:
#!/bin/bash
sqlplus -s gennick/secret << EOF
COLUMN tab_count NEW_VALUE table_count
SELECT COUNT(*) tab_count FROM user_all_tables;
EXIT table_count
EOF
let "tabcount = $?"
echo You have $tabcount tables.
Вывод из скрипты в переменную командной строки unix:
#!/bin/bash
tabcount=`sqlplus -s gennick/secret << EOF
SET PAGESIZE 0
SELECT COUNT(*) FROM user_all_tables;
EXIT
EOF`
echo You have $tabcount tables.