跳转到内容

Oracle 数据库/SQL 速查表

来自维基教科书,开放世界中的开放书籍

此“速查表”涵盖了 Oracle DBA 运行基本查询和执行基本任务所需的大部分基本功能。它还包含 PL/SQL 程序员经常用来编写存储过程的信息。该资源可作为 Oracle 新手的入门指南,或作为有经验的 Oracle 用户的参考。

网络上存在大量有关 Oracle 的信息。我们开发了此资源,以便程序员和 DBA 更容易在一个地方找到大多数基础知识。超出“速查表”范围的主题通常会提供指向进一步研究的链接。

其他 Oracle 参考资料

SELECT

[edit | edit source]

SELECT 语句用于检索从一个或多个表、对象表、视图、对象视图或物化视图中选择的行。

   SELECT *
   FROM beverages
   WHERE field1 = 'Kona'
   AND field2 = 'coffee'
   AND field3 = 122;

SELECT INTO

[edit | edit source]

Select into 将nameaddressphone number 的值从employee 表中取出,并将其放入v_employee_namev_employee_addressv_employee_phone_number 变量中。

在查询匹配单个项目时有效。如果查询未返回任何行,则会引发NO_DATA_FOUND 内置异常。如果查询返回多行,则 Oracle 会引发异常TOO_MANY_ROWS

 SELECT name,address,phone_number
 INTO v_employee_name,v_employee_address,v_employee_phone_number
 FROM employee
 WHERE employee_id = 6;

INSERT

[edit | edit source]

INSERT 语句用于向数据库表中添加一行或多行新数据。

使用 VALUES 关键字插入

 INSERT INTO table_name VALUES ('Value1', 'Value2', ... );
 INSERT INTO table_name( Column1, Column2, ... ) VALUES ( 'Value1', 'Value2', ... );

使用 SELECT 语句插入

 INSERT INTO table_name( SELECT Value1, Value2, ... from table_name );
 INSERT INTO table_name( Column1, Column2, ... ) ( SELECT Value1, Value2, ... from table_name );

DELETE

[edit | edit source]

DELETE 语句用于删除表中的行。

删除与条件匹配的行

 DELETE FROM table_name WHERE some_column=some_value
 DELETE FROM customer WHERE sold = 0;

UPDATE

[edit | edit source]

UPDATE 语句用于更新表中的行。

更新该表的整列

 UPDATE customer SET state='CA';

更新表的特定记录,例如

 UPDATE customer SET name='Joe' WHERE customer_id=10;

当 paid 列大于零时,将 invoice 列更新为已支付。

 UPDATE movies SET invoice='paid' WHERE paid > 0;

序列

[edit | edit source]

序列是多个用户可以用来生成唯一整数的数据库对象。序列生成器生成顺序编号,这可以帮助自动生成唯一的主键,并在多行或多表之间协调键。

创建序列

[edit | edit source]

序列的语法是

 CREATE SEQUENCE sequence_name
     MINVALUE value
     MAXVALUE value
     START WITH value
     INCREMENT BY value
     CACHE value;

例如

 CREATE SEQUENCE supplier_seq
     MINVALUE 1
     MAXVALUE 999999999999999999999999999
     START WITH 1
     INCREMENT BY 1
     CACHE 20;

修改序列

[edit | edit source]

按一定量递增序列

 ALTER SEQUENCE <sequence_name> INCREMENT BY <integer>;
 ALTER SEQUENCE seq_inc_by_ten  INCREMENT BY 10;

更改序列的最大值

 ALTER SEQUENCE <sequence_name> MAXVALUE <integer>;
 ALTER SEQUENCE seq_maxval  MAXVALUE  10;

设置序列循环或不循环

 ALTER SEQUENCE <sequence_name> <CYCLE | NOCYCLE>;
 ALTER SEQUENCE seq_cycle NOCYCLE;

配置序列以缓存值

 ALTER SEQUENCE <sequence_name> CACHE <integer> | NOCACHE;
 ALTER SEQUENCE seq_cache NOCACHE;

设置是否按顺序返回值

 ALTER SEQUENCE <sequence_name> <ORDER | NOORDER>;
 ALTER SEQUENCE seq_order NOORDER;
 ALTER SEQUENCE seq_order;

从字符串生成查询

[edit | edit source]

有时需要从字符串创建查询。也就是说,如果程序员想要在运行时(动态生成 Oracle 查询)创建查询,基于特定的一组情况等等。

应注意不要将用户提供的数据直接插入到动态查询字符串中,而没有首先严格审查数据中的 SQL 转义字符;否则,您将面临数据注入攻击的重大风险。

这是一个非常简单的动态查询示例。当然,还有很多不同的方法可以做到这一点;这只是一个功能示例。

 PROCEDURE oracle_runtime_query_pcd IS
     TYPE ref_cursor IS REF CURSOR;
     l_cursor        ref_cursor;

     v_query         varchar2(5000);
     v_name          varchar2(64);
 BEGIN
     v_query := 'SELECT name FROM employee WHERE employee_id=5';
     OPEN l_cursor FOR v_query;
     LOOP
        FETCH l_cursor INTO v_name;
        EXIT WHEN l_cursor%NOTFOUND;
     END LOOP;
     CLOSE l_cursor;
 END;

字符串操作

[edit | edit source]

长度

[edit | edit source]

Length 返回一个整数,表示给定字符串的长度。它可以称为:length blength clength 2length 4

length( string1 );
SELECT length('hello world') FROM dual;
this returns 11, since the argument is made up of 11 characters including the space
SELECT lengthb('hello world') FROM dual;
SELECT lengthc('hello world') FROM dual;
SELECT length2('hello world') FROM dual;
SELECT length4('hello world') FROM dual;
these also return 11, since the functions called are equivalent

Instr

[edit | edit source]

Instr (in string) 返回一个整数,指定子字符串在字符串中的位置。程序员可以指定他们要检测的字符串的哪个出现,以及起始位置。不成功的搜索返回 0。

instr( string1, string2, [ start_position ], [ nth_appearance ] )
instr( 'oracle pl/sql cheatsheet', '/');
this returns 10, since the first occurrence of "/" is the tenth character
instr( 'oracle pl/sql cheatsheet', 'e', 1, 2);
this returns 17, since the second occurrence of "e" is the seventeenth character
instr( 'oracle pl/sql cheatsheet', '/', 12, 1);
this returns 0, since the first occurrence of "/" is before the starting point, which is the 12th character

替换

[edit | edit source]

Replace 在字符串中查找,将一个字符串替换为另一个字符串。如果没有指定其他字符串,则会删除替换字符串参数中指定的字符串。

replace( string1, string_to_replace, [ replacement_string ] );
replace('i am here','am','am not');
this returns "i am not here"

子字符串

[edit | edit source]

Substr (substring) 返回给定字符串的一部分。"start_position" 基于 1,而不是基于 0。如果 "start_position" 为负数,则 substr 从字符串末尾开始计数。如果没有给出 "length",则 substr 默认为字符串的剩余长度。

substr( string, start_position [, length])

SELECT substr( 'oracle pl/sql cheatsheet', 8, 6) FROM dual;
返回 "pl/sql" 因为 "pl/sql" 中的 "p" 在字符串中处于第 8 个位置(从字符串中的 "o" 开始计数为 1)
SELECT substr( 'oracle pl/sql cheatsheet', 15) FROM dual;
返回 "cheatsheet" 因为 "c" 在字符串中处于第 15 个位置,而 "t" 是字符串中的最后一个字符。
SELECT substr('oracle pl/sql cheatsheet', -10, 5) FROM dual;
返回 "cheat" 因为 "c" 是字符串中的第 10 个字符,从字符串的末尾开始计数,"t" 为位置 1。

修剪

[edit | edit source]

这些函数可用于从字符串中过滤不需要的字符。默认情况下,它们会删除空格,但也可以指定一个字符集进行删除。

trim ( [ leading | trailing | both ] [ trim-char ] from string-to-be-trimmed );
trim ('   removing spaces at both sides     ');
this returns "removing spaces at both sides"
ltrim ( string-to-be-trimmed [, trimming-char-set ] );
ltrim ('   removing spaces at the left side     ');
this returns "removing spaces at the left side     "
rtrim ( string-to-be-trimmed [, trimming-char-set ] );
rtrim ('   removing spaces at the right side     ');
this returns "   removing spaces at the right side"

DDL SQL

[edit | edit source]

表格

[edit | edit source]

创建表格

[edit | edit source]

创建表格的语法如下

CREATE TABLE [table name]
      ( [column name] [datatype], ... );

例如

 CREATE TABLE employee
       (id int, name varchar(20));

添加列

[edit | edit source]

添加列的语法如下

ALTER TABLE [table name]
      ADD ( [column name] [datatype], ... );

例如

 ALTER TABLE employee
       ADD (id int);

修改列

[edit | edit source]

修改列的语法如下

ALTER TABLE [table name]
      MODIFY ( [column name] [new datatype] );

ALTER table 语法和示例

例如

 ALTER TABLE employee
       MODIFY( sickHours s float );

删除列

[edit | edit source]

删除列的语法如下

ALTER TABLE [table name]
      DROP COLUMN [column name];

例如

 ALTER TABLE employee
       DROP COLUMN vacationPay;

约束

[edit | edit source]
约束类型和代码
[edit | edit source]
类型 代码 类型描述 作用于级别
C 表格上的检查
O 视图上的只读 对象
P 主键 对象
R 引用 AKA 外键
U 唯一键
V 视图上的检查选项 对象
显示约束
[edit | edit source]

以下语句显示系统中的所有约束

 SELECT
 	table_name,
 	constraint_name,
 	constraint_type
 FROM user_constraints;
选择引用约束
[edit | edit source]

以下语句显示所有引用约束(外键),包括源表和目标表/列对

 SELECT
 	c_list.CONSTRAINT_NAME as NAME,
 	c_src.TABLE_NAME as SRC_TABLE,
 	c_src.COLUMN_NAME as SRC_COLUMN,
 	c_dest.TABLE_NAME as DEST_TABLE,
 	c_dest.COLUMN_NAME as DEST_COLUMN
 FROM ALL_CONSTRAINTS c_list,
      ALL_CONS_COLUMNS c_src,
      ALL_CONS_COLUMNS c_dest
 WHERE c_list.CONSTRAINT_NAME = c_src.CONSTRAINT_NAME
   AND c_list.R_CONSTRAINT_NAME = c_dest.CONSTRAINT_NAME
   AND c_list.CONSTRAINT_TYPE = 'R'
在表格上设置约束
[edit | edit source]

使用 CREATE TABLE 语句创建检查约束的语法如下

CREATE TABLE table_name
(
    column1 datatype null/not null,
    column2 datatype null/not null,
    ...
    CONSTRAINT constraint_name CHECK (column_name condition) [DISABLE]
);

例如

 CREATE TABLE suppliers
 (
     supplier_id  numeric(4),
     supplier_name  varchar2(50),
     CONSTRAINT check_supplier_id
     CHECK (supplier_id BETWEEN 100 and 9999)
 );
表格上的唯一索引
[edit | edit source]

使用 CREATE TABLE 语句创建唯一约束的语法如下

CREATE TABLE table_name
(
    column1 datatype null/not null,
    column2 datatype null/not null,
    ...
    CONSTRAINT constraint_name UNIQUE (column1, column2, column_n)
);

例如

 CREATE TABLE customer
 (
     id   integer not null,
     name varchar2(20),
     CONSTRAINT customer_id_constraint UNIQUE (id)
 );
添加唯一约束
[编辑 | 编辑源代码]

唯一约束的语法是

ALTER TABLE [table name]
      ADD CONSTRAINT [constraint name] UNIQUE( [column name] ) USING INDEX [index name];

例如

 ALTER TABLE employee
       ADD CONSTRAINT uniqueEmployeeId UNIQUE(employeeId) USING INDEX ourcompanyIndx_tbs;
添加外键约束
[编辑 | 编辑源代码]

外键约束的语法是

ALTER TABLE [table name]
      ADD CONSTRAINT [constraint name] FOREIGN KEY (column,...) REFERENCES table [(column,...)] [ON DELETE {CASCADE | SET NULL}]

例如

 ALTER TABLE employee
       ADD CONSTRAINT fk_departament FOREIGN KEY (departmentId) REFERENCES departments(Id);
删除约束
[编辑 | 编辑源代码]

删除 (移除) 约束的语法是:[1]

ALTER TABLE [table name]
      DROP CONSTRAINT [constraint name];

例如

 ALTER TABLE employee
       DROP CONSTRAINT uniqueEmployeeId;

索引是一种以更高效率检索记录的方法。索引为索引列中出现的每个值创建一个条目。默认情况下,Oracle 创建B 树 索引。

创建索引

[编辑 | 编辑源代码]

创建索引的语法是

CREATE [UNIQUE] INDEX index_name
    ON table_name (column1, column2, . column_n)
    [ COMPUTE STATISTICS ];

UNIQUE 指示索引列中的值组合必须唯一。

COMPUTE STATISTICS 指示 Oracle 在创建索引期间收集统计信息。然后,优化器将使用这些统计信息来选择执行语句时的最佳执行计划。

例如

 CREATE INDEX customer_idx
     ON customer (customer_name);

在此示例中,已在名为 customer_idx 的 customer 表上创建了一个索引。它仅包含 customer_name 字段。

以下代码创建了包含多个字段的索引

 CREATE INDEX customer_idx
     ON supplier (customer_name, country);

以下代码在创建索引时收集统计信息

 CREATE INDEX customer_idx
     ON supplier (customer_name, country)
     COMPUTE STATISTICS;

创建基于函数的索引

[编辑 | 编辑源代码]

在 Oracle 中,您不仅可以为列创建索引。您还可以创建基于函数的索引。

创建基于函数的索引的语法是

CREATE [UNIQUE] INDEX index_name
    ON table_name (function1, function2, . function_n)
    [ COMPUTE STATISTICS ];

例如

 CREATE INDEX customer_idx
     ON customer (UPPER(customer_name));

已创建了一个基于 customer_name 字段大写评估的索引。

为了确保 Oracle 优化器在执行您的 SQL 语句时使用此索引,请确保 UPPER(customer_name) 不评估为 NULL 值。为此,请将 UPPER(customer_name) IS NOT NULL 添加到您的 WHERE 子句,如下所示

 SELECT customer_id, customer_name, UPPER(customer_name)
 FROM customer
 WHERE UPPER(customer_name) IS NOT NULL
 ORDER BY UPPER(customer_name);

重命名索引

[编辑 | 编辑源代码]

重命名索引的语法是

ALTER INDEX index_name
    RENAME TO new_index_name;

例如

 ALTER INDEX customer_id
     RENAME TO new_customer_id;

在此示例中,customer_id 重命名为 new_customer_id

收集索引上的统计信息

[编辑 | 编辑源代码]

如果需要在首次创建索引后收集统计信息,或者想要更新统计信息,始终可以使用 ALTER INDEX 命令来收集统计信息。您收集统计信息是为了让 Oracle 能有效地使用索引。这将重新计算表大小、行数、块数、段数并更新字典表,以便 Oracle 在选择执行计划时能够有效地使用数据。

在索引上收集统计信息的语法是

ALTER INDEX index_name
    REBUILD COMPUTE STATISTICS;

例如

 ALTER INDEX customer_idx
     REBUILD COMPUTE STATISTICS;

在此示例中,为名为 customer_idx 的索引收集了统计信息。

删除索引

[编辑 | 编辑源代码]

删除索引的语法是

   DROP INDEX index_name;

例如

    DROP INDEX customer_idx;

在此示例中,customer_idx 被删除了。

[编辑 | 编辑源代码]

用户管理

[编辑 | 编辑源代码]

创建用户

[编辑 | 编辑源代码]

创建用户的语法是

   CREATE USER username IDENTIFIED BY password;

例如

   CREATE USER brian IDENTIFIED BY brianpass;

授予权限

[编辑 | 编辑源代码]

授予权限的语法是

   GRANT privilege TO user;

例如

   GRANT dba TO brian;

更改密码

[编辑 | 编辑源代码]

更改用户密码的语法是

   ALTER USER username IDENTIFIED BY password;

例如

   ALTER USER brian IDENTIFIED BY brianpassword;

导入和导出

[编辑 | 编辑源代码]

有两种方法可以备份和还原数据库表和数据。'exp' 和 'imp' 工具是更简单的工具,适用于较小的数据库。如果数据库结构变得更加复杂或非常大(例如大于 50 GB),则使用 RMAN 工具更合适。

使用 IMP 导入转储文件

[编辑 | 编辑源代码]

此命令用于从 'exp' 工具创建的 *.dmp 文件中导入 Oracle 表和表数据。请记住,这是一个从命令行通过 $ORACLE_HOME/bin 执行的命令,而不是在 SQL*Plus 中执行的命令。

导入转储文件的语法是

   imp KEYWORD=value

您可以为关键字使用许多参数。

要查看所有关键字,请执行以下操作

   imp HELP=yes

示例

   imp brian/brianpassword FILE=mydump.dmp FULL=yes

运算符

[编辑 | 编辑源代码]

算术运算符

[编辑 | 编辑源代码]
  • 加法:+
  • 减法:-
  • 乘法:*
  • 除法:/
  • 幂 (仅限 PL/SQL):**

为客户 ID 为 5 的所有员工加薪 5%

UPDATE employee SET salary = salary * 1.05
                  WHERE customer_id = 5;

确定所有员工的税后工资

SELECT wage – tax FROM employee;

比较运算符

[编辑 | 编辑源代码]
  • 大于:>
  • 大于或等于:>=
  • 小于:<
  • 小于或等于:<=
  • 等效:=
  • 不等式: != ^= <> ¬= (取决于平台)
SELECT name, salary, email FROM employees WHERE salary > 40000;
SELECT name FROM customers WHERE customer_id < 6;

字符串运算符

[编辑 | 编辑源代码]
  • 连接:||

create or replace procedure addtest( a in varchar2(100), b in varchar2(100), c out varchar2(200) ) IS begin C:=concat(a,'-',b);

日期运算符

[编辑 | 编辑源代码]
  • 加法:+
  • 减法:-

基本 PL/SQL 类型

[编辑 | 编辑源代码]

标量类型(在包 STANDARD 中定义):NUMBER、CHAR、VARCHAR2、BOOLEAN、BINARY_INTEGER、LONG\LONG RAW、DATE、TIMESTAMP 及其包含间隔的家族)

复合类型(用户定义类型):TABLE、RECORD、NESTED TABLE 和 VARRAY

LOB 数据类型 : 用于存储大量非结构化数据

%TYPE – 锚定类型变量声明

[编辑 | 编辑源代码]

锚定类型声明的语法为

<var_name> <obj>%type [not null][:= <init-val>];

例如

name Books.title%type;   /*  name is defined as the same type as column 'title' of table  Books */
commission number(5,2) := 12.5;
x commission%type;   /*  x is defined as the same type as variable 'commission' */

注意

  1. 锚定变量允许在 <obj> 类型发生变化时,自动同步锚定变量的类型与 <obj> 的类型。
  2. 锚定类型在编译时进行评估,因此请重新编译程序以反映锚定变量中 <obj> 类型发生的变化。

集合是相同类型元素的有序组。它是一个通用概念,涵盖列表、数组和其他熟悉的类型。每个元素都有一个唯一的下标,确定其在集合中的位置。

--Define a PL/SQL record type representing a book:
TYPE book_rec IS RECORD
   (title                   book.title%TYPE,
    author                  book.author_last_name%TYPE,
    year_published          book.published_date%TYPE);
--define a PL/SQL table containing entries of type book_rec:
Type book_rec_tab IS TABLE OF book_rec
     INDEX BY BINARY_INTEGER;
my_book_rec  book_rec%TYPE;
my_book_rec_tab book_rec_tab%TYPE;
...
my_book_rec := my_book_rec_tab(5);
find_authors_books(my_book_rec.author);
...

使用集合有很多很好的理由。

  • 显著提高执行速度,这得益于透明的性能提升,包括新的优化编译器、更好地集成的本地编译以及帮助数字密集型应用程序的新数据类型。
  • FORALL 语句变得更加灵活和有用。例如,FORALL 现在支持非连续索引。
  • 正则表达式以三种新函数(REGEXP_INSTR、REGEXP_REPLACE 和 REGEXP_SUBSTR)和用于比较的 REGEXP_LIKE 运算符的形式在 PL/SQL 中可用[2]
  • 集合得到了改进,包括集合相等性比较和对嵌套表的集合操作的支持。

参考资料

[编辑 | 编辑源代码]
  1. http://www.psoug.org/reference/constraints.html
  2. 有关此问题的更多信息,请参阅 Jonathan Gennick 的“First Expressions”

存储逻辑

[编辑 | 编辑源代码]

函数必须向调用者返回值。

函数的语法为

CREATE [OR REPLACE] FUNCTION function_name [ (parameter [,parameter]) ]
RETURN [return_datatype]
IS
    [declaration_section]
BEGIN
    executable_section
    return [return_value]
    [EXCEPTION
        exception_section]
END [function_name];

例如

CREATE OR REPLACE  FUNCTION to_date_check_null(dateString IN VARCHAR2, dateFormat IN VARCHAR2)
RETURN DATE IS
BEGIN
    IF dateString IS NULL THEN
        return NULL;
    ELSE
        return to_date(dateString, dateFormat);
    END IF;
END;

过程与函数的区别在于,它不能向调用者返回值。

过程的语法为

CREATE [OR REPLACE] PROCEDURE procedure_name [ (parameter [,parameter]) ]
IS
    [declaration_section]
BEGIN
    executable_section
    [EXCEPTION
        exception_section]
END [procedure_name];

创建过程或函数时,可以定义参数。可以声明三种类型的参数

  1. IN – 过程或函数可以引用该参数。参数的值不能被过程或函数覆盖。
  2. OUT – 过程或函数不能引用该参数,但参数的值可以被过程或函数覆盖。
  3. IN OUT – 过程或函数可以引用该参数,并且参数的值可以被过程或函数覆盖。

您还可以声明一个 DEFAULT 值;

CREATE [OR REPLACE] PROCEDURE procedure_name [ (parameter [IN|OUT|IN OUT] [DEFAULT value] [,parameter]) ]

以下是一个简单的过程示例

   /* purpose: shows the students in the course specified by courseId */
   CREATE OR REPLACE Procedure GetNumberOfStudents
      ( courseId IN number, numberOfStudents OUT number )
   IS
       /* although there are better ways to compute the number of students,
          this is a good opportunity to show a cursor in action            */
       cursor student_cur is
       select studentId, studentName
           from course
           where course.courseId = courseId;
       student_rec    student_cur%ROWTYPE;
   BEGIN
       OPEN student_cur;
       LOOP
           FETCH student_cur INTO student_rec;
           EXIT WHEN student_cur%NOTFOUND;
           numberOfStudents := numberOfStudents + 1;
       END LOOP;
       CLOSE student_cur;
   EXCEPTION
   WHEN OTHERS THEN
         raise_application_error(-20001,'An error was encountered – '||SQLCODE||' -ERROR- '||SQLERRM);
   END GetNumberOfStudents;

匿名块

[编辑 | 编辑源代码]
DECLARE
 x NUMBER(4) := 0;
BEGIN
  x := 1000;
  BEGIN
    x := x + 100;
  EXCEPTION
    WHEN OTHERS THEN
      x := x + 2;
  END;
  x := x + 10;
  dbms_output.put_line(x);
EXCEPTION
  WHEN OTHERS THEN
    x := x + 3;
END;

向存储逻辑传递参数

[编辑 | 编辑源代码]

向存储过程传递参数有三种基本语法:位置表示法、命名表示法和混合表示法。

以下示例针对每种基本参数传递语法调用此过程

CREATE OR REPLACE PROCEDURE create_customer( p_name IN varchar2,
                                             p_id IN number,
                                             p_address IN varchar2,
                                             p_phone IN varchar2 ) IS
BEGIN
    INSERT INTO customer ( name, id, address, phone )
    VALUES ( p_name, p_id, p_address, p_phone );
END create_customer;
位置表示法
[编辑 | 编辑源代码]

以与在过程中声明的顺序相同的顺序指定相同参数。这种表示法很简洁,但如果以错误的顺序指定参数(尤其是文字),则很难检测到错误。如果过程的参数列表发生更改,则必须更改代码。

create_customer('James Whitfield', 33, '301 Anystreet', '251-222-3154');
命名表示法
[编辑 | 编辑源代码]

为每个参数指定其名称及其值。箭头 (=>) 充当关联运算符。参数的顺序无关紧要。这种表示法更详细,但使您的代码更易于阅读和维护。如果过程的参数列表发生更改,例如参数重新排序或添加了新的可选参数,则有时可以避免更改代码。对于调用其他人的 API 或为其他人定义 API 的任何代码,命名表示法是一种很好的实践。

create_customer(p_address => '301 Anystreet', p_id => 33, p_name => 'James Whitfield', p_phone => '251-222-3154');
混合表示法
[编辑 | 编辑源代码]

使用位置表示法指定第一个参数,然后切换到对最后一个参数使用命名表示法。可以使用这种表示法调用具有某些必需参数,然后是某些可选参数的过程。

create_customer(v_name, v_id, p_address=> '301 Anystreet', p_phone => '251-222-3154');

表函数

[编辑 | 编辑源代码]
CREATE TYPE object_row_type as OBJECT (
  object_type VARCHAR(18),
  object_name VARCHAR(30)
);
CREATE TYPE object_table_type as TABLE OF object_row_type;
CREATE OR REPLACE FUNCTION get_all_objects
  RETURN object_table_type PIPELINED AS
BEGIN
    FOR cur IN (SELECT * FROM all_objects)
    LOOP
      PIPE ROW(object_row_type(cur.object_type, cur.object_name));
    END LOOP;
    RETURN;
END;
SELECT * FROM TABLE(get_all_objects);

流程控制

[编辑 | 编辑源代码]
条件运算符
[编辑 | 编辑源代码]
  • and: AND
  • or: OR
  • not: NOT

IF salary > 40000 AND salary <= 70000 THEN() ELSE IF salary>70000 AND salary<=100000 THEN() ELSE()

If/then/else

[编辑 | 编辑源代码]
IF [condition] THEN
    [statements]
ELSEIF [condition] THEN
    [statements}
ELSEIF [condition] THEN
    [statements}
ELSEIF [condition] THEN
    [statements}
ELSEIF [condition] THEN
    [statements}
ELSEIF [condition] THEN
    [statements}
ELSEIF [condition] THEN
    [statements}
ELSEIF [condition] THEN
    [statements}
ELSE
    [statements}
END IF;
关联数组
[编辑 | 编辑源代码]
  • 强类型数组,作为内存表很有用
  • 非常简单的示例,索引是访问数组的键,因此除非您打算使用数组中每一行的數據,否则无需遍历整个表。
  • 索引也可以是数值。
DECLARE
    -- Associative array indexed by string:

    -- Associative array type
    TYPE population IS TABLE OF NUMBER
        INDEX BY VARCHAR2(64);
    -- Associative array variable
    city_population  population;
    i                VARCHAR2(64);
BEGIN
    -- Add new elements to associative array:
    city_population('Smallville')  := 2000;
    city_population('Midland')     := 750000;
    city_population('Megalopolis') := 1000000;

    -- Change value associated with key 'Smallville':
    city_population('Smallville') := 2001;

    -- Print associative array by looping through it:
    i := city_population.FIRST;

    WHILE i IS NOT NULL LOOP
        DBMS_OUTPUT.PUT_LINE
            ('Population of ' || i || ' is ' || TO_CHAR(city_population(i)));
        i := city_population.NEXT(i);
    END LOOP;

    -- Print selected value from a associative array:
    DBMS_OUTPUT.PUT_LINE('Selected value');
    DBMS_OUTPUT.PUT_LINE('Population of');
END;
/

-- Printed results:
Population of Megalopolis is 1000000
Population of Midland is 750000
Population of Smallville is 2001
  • 更复杂的示例,使用记录
DECLARE
    -- Record type
    TYPE apollo_rec IS RECORD
    (
        commander   VARCHAR2(100),
        launch      DATE
    );
    -- Associative array type
    TYPE apollo_type_arr IS TABLE OF apollo_rec INDEX BY VARCHAR2(100);
    -- Associative array variable
    apollo_arr apollo_type_arr;
BEGIN
    apollo_arr('Apollo 11').commander := 'Neil Armstrong';
    apollo_arr('Apollo 11').launch :=   TO_DATE('July 16, 1969','Month dd, yyyy');
    apollo_arr('Apollo 12').commander := 'Pete Conrad';
    apollo_arr('Apollo 12').launch :=   TO_DATE('November 14, 1969','Month dd, yyyy');
    apollo_arr('Apollo 13').commander := 'James Lovell';
    apollo_arr('Apollo 13').launch :=   TO_DATE('April 11, 1970','Month dd, yyyy');
    apollo_arr('Apollo 14').commander := 'Alan Shepard';
    apollo_arr('Apollo 14').launch :=   TO_DATE('January 31, 1971','Month dd, yyyy');

    DBMS_OUTPUT.PUT_LINE(apollo_arr('Apollo 11').commander);
    DBMS_OUTPUT.PUT_LINE(apollo_arr('Apollo 11').launch);
end;
/

-- Printed results:
Neil Armstrong
16-JUL-69

Oracle Application Express 也称为 APEX,是一个基于 Web 的软件开发环境,运行在 Oracle 数据库上。

字符串替换

[编辑 | 编辑源代码]
  • 在 SQL 中: :VARIABLE
  • 在 PL/SQL 中: V('VARIABLE') 或 NV('VARIABLE')
  • 在文本中: &VARIABLE.

参考资料

[编辑 | 编辑源代码]
华夏公益教科书