SQLcl 方便、有趣又好玩,来了解一下吧
大家好,我是 JiekeXu,很高兴又和大家见面了,今天和大家聊聊 甲骨文云技术,欢迎点击上方蓝字关注我,标星或置顶,更多干货第一时间到达!
无论是 Oracle 的新手还是专家,几乎每天都在使用 SQL*Plus,因为这个工具是 Oracle Database 原生的,无需额外安装就可使用,并且这是一个命令行工具,只要能访问到操作系统,无论是 Linux,Windows,AIX 还是其他系统,都可以方便地使用。但用了这么多年的SQL*Plus,对这个工具总是有点小困扰,比如在 Linux 当中不支持通过上下方向键进行历史命令的检索、如果 SQL 语句比较长,一旦在前几行有错误,只能重新输入无法修改,SQL*Plus 也不提供代码补全等功能。
其实在 2015 年开始的教学过程中,我们已经使用了新一代的 Oracle Database命令行工具,叫做 SQLcl(Oracle SQL Developer Command Line),它不但提供了原来 SQL*Plus 的功能,还提供了强大的编辑功能,同时也提供代码补全、更美观的输出等功能。今天我们就和大家一起来了解一下这个可爱的小工具是如何使用的吧。
首先我们了解一下今天使用的实验环境:
操作系统:Linux x86-64
数据库:Oracle Database 19c(19.8)
1、SQLcl 的安装
SQLcl 是一个依赖 Java 运行环境的小工具,所以请确保您要运行 SQLcl 的操作系统无论是Windows 还是 Linux 事先安装了 Java 环境并配置了相应的环境变量。
[oracle@henry ~]$ java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
[oracle@henry ~]$
然后来到 https://www.oracle.com/database/technologies/appdev/sqlcl.html 下载SQLcl,点击下图中红色框指出的下载按钮即可下载,
无论您使用的是 Windows 操作系统还是 Linux,都可以下载统一的安装包,和 SQL Developer 一样,在安装包当中包含 exe 文件和 Linux 系统使用的可执行脚本。
下载之后,解压压缩包,并且将 SQLcl 的路径放入环境变量 PATH 当中,比如在今天的实验中,我们将 sqlcl 解压到 /opt/sqlcl 下面,于是将 /opt/sqlcl/bin 放入 PATH 就可以。如果您由于各种原因无法下载,则在本公众号[JiekeXu DBA之路]后台回复【SQLcl】获取百度云链接。
[root@JiekeXu]# su - oracle
Last login: Sat Oct 17 02:58:45 GMT 2020 on pts/1
[oracle@JiekeXu ~]$ cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
export ORACLE_HOME=/opt/oracle/product/19c/dbhome_1
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/opt/oracle/product/19c/dbhome_1/bin:/opt/sqlcl/bin
export ORACLE_SID=JiekeXu
export PATH
[oracle@JiekeXu ~]$
2、使用 SQLcl 连接 Oracle Database
使用 SQLcl 连接 Oracle 数据库和之前使用的 SQL*Plus 非常相似,甚至可以说没什么不同。只是之前使用的是 sqlplus,现在只要写 sql 就可以了。
[oracle@JiekeXu ~]$ sql hr/hr@localhost:1521/JiekeXupdb1
SQLcl: Release 19.1 Production on Sat Oct 17 03:13:33 2020
Copyright (c) 1982, 2020, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.8.0.0.0
SQL>
然后我们可以使用 help 来查询一下都有哪些命令可以使用。
SQL>help
SQL> helpFor help on a topic type help <topic>
List of Help topics available:
/
@
@@
ACCEPT
ALIAS*
APEX*
APPEND
ARCHIVE_LOG
BREAK
BRIDGE*
BTITLE
CD*
CHANGE
CLEAR
COLUMN
COMPUTE
CONNECT
COPY
CTAS*
DDL*
DEFINE
DEL
DESCRIBE
DISCONNECT
EDIT
EXECUTE
EXIT
FIND*
FORMAT*
GET
HISTORY*
HOST
INFORMATION*
INPUT
LIQUIBASE*
LIST
LOAD*
NET*
OERR*
PASSWORD
PAUSE
PRINT
PROMPT
QUIT
REMARK
REPEAT*
RESERVED_WORDS
REST*
RUN
SAVE
SCRIPT*
SET
SETERRORL
SHOW
SHUTDOWN
SODA*
SPOOL
SSHTUNNEL*
START
STARTUP
STORE
TIMING
TNSPING*
TTITLE
UNDEFINE
VARIABLE
VAULT*
WHENEVER
WHICH*
XQUERY
SQL>
3、NET 命令
以前我们在 SQL*Plus 当中连接特定数据库使用的是 tnsnames.ora 当中的命名,在 SQLcl 当中,可以通过 NET 命令非常方便地随时创建数据库连接别名。需要注意的是 NET 功能默认被关闭了,要在 SQLcl 当中通过 set net on 将它打开。
在下面的例子当中,我们创建一个连接别名叫做ora,去连接本地的orclpdb1数据库,监听端口1521。
SQL> show net
net: ON
SQL> set net off
SQL> show net
net: OFF
SQL> set net on
SQL> net ora=localhost:1521/JiekeXupdb1;
SQL> conn hr/hr@ora
Connected.
SQL>
4、使用 Tab 键进行代码补齐
在输入语句的时候,可以通过按 Tab 键来补全语句关键字(比如 select)、table 的名字,column 的名字等,当有些 table 当中的 column name 非常长的时候,这项功能就极为高效。
大家通过观察下面的视频,当我按Tab键的时候,自动补全的部分会使用大写来显示。
5、多行编辑功能
我们在写比较长的 SQL 语句的时候,为了保持美观及增强可读性,我们经常使用换行,但是大家在使用 SQL*Plus 的时候,如果有一行写错了,就得重新将整个语句都重写,非常不方便。我们之前使用的技术是将 SQL 语句写在一个文件当中,然后来执行这个文件。但总觉得不是很方便。在 SQLcl 当中,通过按方向键左键来移动光标进行修改,请不要按方向键上下键,因为上下键是用来查找我们之前执行的语句历史的。
6、使用 HISTORY 命令查看执行历史
我们在 Linux 当中使用 SQL*Plus 的时候,总是羡慕在 Windows 环境的 cmd 当中执行SQL*Plus,可以使用方向键上下键来查找之前执行过的语句。在 SQLcl 当中,无论是在 Linux 还是 Windows 环境下,都支持使用方向键上下键对之前执行过的语句进行滚动查找并执行。此外,可以使用 SQLcl 的 history 命令来查看之前执行过的语句和命令。history 命令有如下几个参数:full、usage(执行次数)、time(执行时间),clear(清除历史)以及使用具体的语句序号。大家可以观察一下直接使用 history 和 history full 的区别。
7、使用 CD 命令直接在 SQLcl 当中更换目录
我们在执行本地脚本的时候,如果启动 SQL*Plus 的时候,不是在脚本所在的路径,我们经常要使用全路径名来执行脚本,而在 SQLcl 当中可以像在命令行中一样,使用 cd 命令进行路径的切换。
比如,我们现在 /opt 路径下启动 SQLcl,在 /opt/henry 路径下有一个 h.sql 脚本要执行。我们在 SQLcl 当中可以直接使用 cd 命令进行路径切换。
8、使用 ALIAS 命令创建语句或者程序块的快捷方式
在测试程序或者调试数据库的时候,我们经常要反复执行一段代码,比如查看当前数据文件大小。之前我们的做法是将这些语句写成一个 SQL 脚本,然后每次来执行,或者写在一个记事本当中进行复制粘贴。在 SQLcl 当中,可以将这些语句临时定义成一个 ALIAS,使用起来更加轻松方便。比如,我们在下面的例子当中,将一个 SQL 语句定义成一个 ALIAS 叫做 tbs,来查询 user_tables 当中的记录数量。我们也可以通过 alias list 来查询当前已经定义好的ALIAS,大家通过观察发现,系统中已经为大家预定义了一些 ALIAS。
9、使用 SQLFORMAT 设定输出格式
这是一项非常有用的功能,之前我们想将数据表中的数据,以 JSON 或者 CSV 的格式输出,一般要使用编程语言,比如 Python。而在 SQLcl 当中,只要通过 SQLFORMAT 设定一下输出格式就可以了,不再依赖编程语言就可以方便输出 JSON 或者 CSV 格式的结果。SQLFORMAT 还提供更多有趣的功能,大家可以查询官方文档挖掘更多的应用场景。
在 set sqlformat 当中可以使用如下设定,下面的例子中使用的是 csv
default
ansiconsole
csv
insert – lists resuts as an insert statement
loader – pipe-delimited
delimited – same as csv
xml
html
fixed – fixed width
text
json
10、使用 INFORMATION 获取更多资讯
在 SQL*Plus 当中,我们经常使用 describe 命令来获取 table 的信息,在 SQLcl 当中,我们可以使用 information 或者 info 来获取更多的讯息。可以显示基本的 column 信息、index 信息以及主外键讯息。
INFORMATION 不只可以获得 table 的信息,也可以用来获取程序包的信息。
11、使用 DDL 命令获取数据对象 ddl 信息
有时候我们想获取一个表或者其他数据对象的 DDL 信息,以前我们都是使用程序包来实现,调用起来相对比较麻烦,在 SQLcl 当中我们可以使用 DDL 命令方便地获取这些数据对象的 DDL 信息。
SQL> ddl employees
CREATE TABLE "HR"."EMPLOYEES"
( "EMPLOYEE_ID" NUMBER(6,0),
"FIRST_NAME" VARCHAR2(20),
"LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE,
"EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE,
"PHONE_NUMBER" VARCHAR2(20),
"HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE,
"JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE,
"SALARY" NUMBER(8,2),
"COMMISSION_PCT" NUMBER(2,2),
"MANAGER_ID" NUMBER(6,0),
"DEPARTMENT_ID" NUMBER(4,0),
CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE,
CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ENABLE,
CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY ("DEPARTMENT_ID")
REFERENCES "HR"."DEPARTMENTS" ("DEPARTMENT_ID") ENABLE,
CONSTRAINT "EMP_JOB_FK" FOREIGN KEY ("JOB_ID")
REFERENCES "HR"."JOBS" ("JOB_ID") ENABLE,
CONSTRAINT "EMP_MANAGER_FK" FOREIGN KEY ("MANAGER_ID")
REFERENCES "HR"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE UNIQUE INDEX "HR"."EMP_EMP_ID_PK" ON "HR"."EMPLOYEES" ("EMPLOYEE_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
ALTER TABLE "HR"."EMPLOYEES" ADD CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID")
USING INDEX "HR"."EMP_EMP_ID_PK" ENABLE;
COMMENT ON COLUMN "HR"."EMPLOYEES"."EMPLOYEE_ID" IS 'Primary key of employees table.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."FIRST_NAME" IS 'First name of the employee. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."LAST_NAME" IS 'Last name of the employee. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."EMAIL" IS 'Email id of the employee';
COMMENT ON COLUMN "HR"."EMPLOYEES"."PHONE_NUMBER" IS 'Phone number of the employee; includes country code and area code';
COMMENT ON COLUMN "HR"."EMPLOYEES"."HIRE_DATE" IS 'Date when the employee started on this job. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."JOB_ID" IS 'Current job of the employee; foreign key to job_id column of the
jobs table. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."SALARY" IS 'Monthly salary of the employee. Must be greater
than zero (enforced by constraint emp_salary_min)';
COMMENT ON COLUMN "HR"."EMPLOYEES"."COMMISSION_PCT" IS 'Commission percentage of the employee; Only employees in sales
department elgible for commission percentage';
COMMENT ON COLUMN "HR"."EMPLOYEES"."MANAGER_ID" IS 'Manager id of the employee; has same domain as manager_id in
departments table. Foreign key to employee_id column of employees table.
(useful for reflexive joins and CONNECT BY query)';
COMMENT ON COLUMN "HR"."EMPLOYEES"."DEPARTMENT_ID" IS 'Department id where employee works; foreign key to department_id
column of the departments table';
COMMENT ON TABLE "HR"."EMPLOYEES" IS 'employees table. Contains 107 rows. References with departments,
jobs, job_history tables. Contains a self reference.';
CREATE INDEX "HR"."EMP_DEPARTMENT_IX" ON "HR"."EMPLOYEES" ("DEPARTMENT_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "HR"."EMP_JOB_IX" ON "HR"."EMPLOYEES" ("JOB_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "HR"."EMP_MANAGER_IX" ON "HR"."EMPLOYEES" ("MANAGER_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "HR"."EMP_NAME_IX" ON "HR"."EMPLOYEES" ("LAST_NAME", "FIRST_NAME")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."SECURE_EMPLOYEES"
BEFORE INSERT OR UPDATE OR DELETE ON employees
BEGIN
secure_dml;
END secure_employees;
/
ALTER TRIGGER "HR"."SECURE_EMPLOYEES" DISABLE;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."UPDATE_JOB_HISTORY"
AFTER UPDATE OF job_id, department_id ON employees
FOR EACH ROW
BEGIN
add_job_history(:old.employee_id, :old.hire_date, sysdate,
:old.job_id, :old.department_id);
END;
/
ALTER TRIGGER "HR"."UPDATE_JOB_HISTORY" ENABLE;
SQL>
我们也可以将生成的 DDL 信息保存到文件当中,如下所示:
SQL> ddl employees save emp.sql
SQL> !cat emp.sql
CREATE TABLE "HR"."EMPLOYEES"
( "EMPLOYEE_ID" NUMBER(6,0),
"FIRST_NAME" VARCHAR2(20),
"LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE,
"EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE,
"PHONE_NUMBER" VARCHAR2(20),
"HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE,
"JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE,
"SALARY" NUMBER(8,2),
"COMMISSION_PCT" NUMBER(2,2),
"MANAGER_ID" NUMBER(6,0),
"DEPARTMENT_ID" NUMBER(4,0),
CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE,
CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ENABLE,
CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY ("DEPARTMENT_ID")
REFERENCES "HR"."DEPARTMENTS" ("DEPARTMENT_ID") ENABLE,
CONSTRAINT "EMP_JOB_FK" FOREIGN KEY ("JOB_ID")
REFERENCES "HR"."JOBS" ("JOB_ID") ENABLE,
CONSTRAINT "EMP_MANAGER_FK" FOREIGN KEY ("MANAGER_ID")
REFERENCES "HR"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE UNIQUE INDEX "HR"."EMP_EMP_ID_PK" ON "HR"."EMPLOYEES" ("EMPLOYEE_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
ALTER TABLE "HR"."EMPLOYEES" ADD CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID")
USING INDEX "HR"."EMP_EMP_ID_PK" ENABLE;
COMMENT ON COLUMN "HR"."EMPLOYEES"."EMPLOYEE_ID" IS 'Primary key of employees table.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."FIRST_NAME" IS 'First name of the employee. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."LAST_NAME" IS 'Last name of the employee. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."EMAIL" IS 'Email id of the employee';
COMMENT ON COLUMN "HR"."EMPLOYEES"."PHONE_NUMBER" IS 'Phone number of the employee; includes country code and area code';
COMMENT ON COLUMN "HR"."EMPLOYEES"."HIRE_DATE" IS 'Date when the employee started on this job. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."JOB_ID" IS 'Current job of the employee; foreign key to job_id column of the
jobs table. A not null column.';
COMMENT ON COLUMN "HR"."EMPLOYEES"."SALARY" IS 'Monthly salary of the employee. Must be greater
than zero (enforced by constraint emp_salary_min)';
COMMENT ON COLUMN "HR"."EMPLOYEES"."COMMISSION_PCT" IS 'Commission percentage of the employee; Only employees in sales
department elgible for commission percentage';
COMMENT ON COLUMN "HR"."EMPLOYEES"."MANAGER_ID" IS 'Manager id of the employee; has same domain as manager_id in
departments table. Foreign key to employee_id column of employees table.
(useful for reflexive joins and CONNECT BY query)';
COMMENT ON COLUMN "HR"."EMPLOYEES"."DEPARTMENT_ID" IS 'Department id where employee works; foreign key to department_id
column of the departments table';
COMMENT ON TABLE "HR"."EMPLOYEES" IS 'employees table. Contains 107 rows. References with departments,
jobs, job_history tables. Contains a self reference.';
CREATE INDEX "HR"."EMP_DEPARTMENT_IX" ON "HR"."EMPLOYEES" ("DEPARTMENT_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "HR"."EMP_JOB_IX" ON "HR"."EMPLOYEES" ("JOB_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "HR"."EMP_MANAGER_IX" ON "HR"."EMPLOYEES" ("MANAGER_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE INDEX "HR"."EMP_NAME_IX" ON "HR"."EMPLOYEES" ("LAST_NAME", "FIRST_NAME")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS" ;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."SECURE_EMPLOYEES"
BEFORE INSERT OR UPDATE OR DELETE ON employees
BEGIN
secure_dml;
END secure_employees;
/
ALTER TRIGGER "HR"."SECURE_EMPLOYEES" DISABLE;
CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."UPDATE_JOB_HISTORY"
AFTER UPDATE OF job_id, department_id ON employees
FOR EACH ROW
BEGIN
add_job_history(:old.employee_id, :old.hire_date, sysdate,
:old.job_id, :old.department_id);
END;
/
ALTER TRIGGER "HR"."UPDATE_JOB_HISTORY" ENABLE;
12、使用 LOAD 载入数据
如果大家有一个 csv 文件,想将里面的数据加载到 table 当中,要使用 sql loader,但有些同学对写 sql loader 的 control file 感到比较头疼,在 SQLcl 当中,只需要简单的一个 LOAD 命令就可以。在下面的例子中,我们有一个 csv 文件叫做 dt1.csv,我们想将这个文件中的数据载入到 dt1 这个 table 当中。需要注意的是,我们在创建 csv 文件的时候,第一行是使用大写字母定义的 column names。
SQL> info dt1
TABLE: DT1
LAST ANALYZED:
ROWS :
SAMPLE SIZE :
INMEMORY :DISABLED
COMMENTS :
Columns
NAME DATA TYPE NULL DEFAULT COMMENTS
NAME VARCHAR2(20 BYTE) Yes
AGE NUMBER Yes
SQL> !cat dt1.csv
NAME,AGE
Bob,25
Jerry,26
SQL> load dt1 dt1.csv
--Number of rows processed: 2
--Number of rows in error: 0
0 - SUCCESS: Load processed without errors
SQL> select * from dt1;
NAME AGE
-------------------- ----------
Bob 25
Jerry 26
13、使用 FORMAT 对 buffer 中的 SQL 语句进行格式化
我们有时候从外面复制过来好长一段代码到 SQL*Plus 当中执行,或者我们自己敲了好长一段代码,这些代码可读性也许会很差,在 SQLcl 当中可以使用 format buffer 对 buffer 中的SQL 语句进行格式化,提升可读性。
SQL> select dept.department_name, emp.first_name||' '||emp.last_name as empname
2 from employees emp
3 join departments dept
4 on emp.department_id = dept.department_id and dept.department_id=10
5 order by 1,2;
DEPARTMENT_NAME EMPNAME
------------------------------ ----------------------------------------------
Administration Jennifer Whalen
SQL> format buffer
1 SELECT
2 dept.department_name,
3 emp.first_name
4 || ' '
5 || emp.last_name AS empname
6 FROM
7 employees emp
8 JOIN departments dept ON emp.department_id = dept.department_id
9 AND dept.department_id = 10
10 ORDER BY
11 1,
12* 2;
14、使用 bridge 创建 “Database Link”
Database Link 是什么,相信大家都了解,需要在 Database 当中创建之后才能使用。而SQLcl 提供 bridge 功能,其实就是在 SQLcl 当中使用 jdbc 创建一个在 SQLcl 当中使用的数据库连接,使用起来非常方便。
SQL> bridge emp_tb as "jdbc:oracle:thin:hr/hr@localhost:1521/JiekeXupdb1"(select first_name,last_name from employees);
Created table emp_tb and inserted 107 row(s)
SQL> select count(*) from emp_tb;
COUNT(*)
----------
107
SQLcl 还有好多有趣的功能,小伙伴们可以点击“阅读原文”参考官方文档,获取更多实用技巧。
转文至此,分享学习之。那么小伙伴们今天就到这里了,以下地址均可找到我,因本公众号没有留言互动功能,可添加我个人微信【JiekeXu_DBA】一起交流学习。
————————————————————————————
公众号:JiekeXu DBA之路
墨天轮:https://www.modb.pro/u/4347
CSDN :https://blog.csdn.net/JiekeXu
腾讯云:https://cloud.tencent.com/developer/user/5645107
————————————————————————————