Oracle 数据库/SQL 速查表
此“速查表”涵盖了 Oracle DBA 运行基本查询和执行基本任务所需的大部分基本功能。它还包含 PL/SQL 程序员经常用来编写存储过程的信息。该资源可作为 Oracle 新手的入门指南,或作为有经验的 Oracle 用户的参考。
网络上存在大量有关 Oracle 的信息。我们开发了此资源,以便程序员和 DBA 更容易在一个地方找到大多数基础知识。超出“速查表”范围的主题通常会提供指向进一步研究的链接。
其他 Oracle 参考资料
- Oracle XML 参考资料 - XML 参考资料仍处于起步阶段,但发展顺利。
SELECT
[edit | edit source]SELECT 语句用于检索从一个或多个表、对象表、视图、对象视图或物化视图中选择的行。
SELECT *
FROM beverages
WHERE field1 = 'Kona'
AND field2 = 'coffee'
AND field3 = 122;
SELECT INTO
[edit | edit source]Select into 将name、address 和phone number 的值从employee 表中取出,并将其放入v_employee_name、v_employee_address 和v_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] 一位维基教科书用户建议将此书籍或章节与Oracle 数据库/表 合并。 请在讨论页面 上讨论是否应该进行此合并。 |
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 b、length c、length 2 和 length 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 工具更合适。
此命令用于从 '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);
- 加法:+
- 减法:-
标量类型(在包 STANDARD 中定义):NUMBER、CHAR、VARCHAR2、BOOLEAN、BINARY_INTEGER、LONG\LONG RAW、DATE、TIMESTAMP 及其包含间隔的家族)
复合类型(用户定义类型):TABLE、RECORD、NESTED TABLE 和 VARRAY
LOB 数据类型 : 用于存储大量非结构化数据
锚定类型声明的语法为
<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' */
注意
- 锚定变量允许在 <obj> 类型发生变化时,自动同步锚定变量的类型与 <obj> 的类型。
- 锚定类型在编译时进行评估,因此请重新编译程序以反映锚定变量中 <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]。
- 集合得到了改进,包括集合相等性比较和对嵌套表的集合操作的支持。
- ↑ http://www.psoug.org/reference/constraints.html
- ↑ 有关此问题的更多信息,请参阅 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];
创建过程或函数时,可以定义参数。可以声明三种类型的参数
- IN – 过程或函数可以引用该参数。参数的值不能被过程或函数覆盖。
- OUT – 过程或函数不能引用该参数,但参数的值可以被过程或函数覆盖。
- 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 [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.