Oracle 数据库/SQL 速查表
这份“速查表”涵盖了 Oracle DBA 运行基本查询和执行基本任务所需的大部分基本功能。它还包含 PL/SQL 程序员编写存储过程时经常使用的信息。该资源对于刚接触 Oracle 的个人来说是一个有用的入门指南,对于那些有经验的 Oracle 用户来说也是一个有用的参考。
网络上存在大量关于 Oracle 的信息。我们开发了这份资源,使程序员和 DBA 更容易在一个地方找到大部分基本知识。超出“速查表”范围的主题通常会提供链接以供进一步研究。
其他 Oracle 参考资料
- Oracle XML 参考资料——XML 参考资料仍处于起步阶段,但进展良好。
SELECT 语句用于检索从一个或多个表、对象表、视图、对象视图或物化视图中选择的行。
SELECT *
FROM beverages
WHERE field1 = 'Kona'
AND field2 = 'coffee'
AND field3 = 122;
Select into 从 employee 表中取出 name、address 和 phone number 值,并将它们放入 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;
一位维基教科书作者建议将本书或章节与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 语句用于删除表中的行。
删除与条件匹配的行
DELETE FROM table_name WHERE some_column=some_value
DELETE FROM customer WHERE sold = 0;
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;
序列是数据库对象,多个用户可以使用它们生成唯一的整数。序列生成器生成顺序号,可以帮助自动生成唯一的主键,并在多行或多个表中协调主键。
序列的语法是
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;
按一定量递增序列
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;
有时需要从字符串创建查询。也就是说,如果程序员想要根据特定的一组情况等在运行时创建查询(动态生成 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;
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 (在字符串中) 返回一个整数,指定子字符串在字符串中的位置。程序员可以指定他们想要检测的字符串的哪个外观,以及起始位置。不成功的搜索返回 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
Replace 在字符串中查找,用另一个字符串替换一个字符串。如果没有指定其他字符串,它会删除替换字符串参数中指定的字符串。
replace( string1, string_to_replace, [ replacement_string ] ); replace('i am here','am','am not'); this returns "i am not here"
Substr (子字符串) 返回给定字符串的一部分。“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 个位置(从 “oracle” 中的 “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。
这些函数可用于从字符串中过滤掉不需要的字符。默认情况下,它们会删除空格,但也可以指定要删除的字符集。
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"
创建表的语法是
CREATE TABLE [table name] ( [column name] [datatype], ... );
例如
CREATE TABLE employee
(id int, name varchar(20));
添加列的语法是
ALTER TABLE [table name] ADD ( [column name] [datatype], ... );
例如
ALTER TABLE employee
ADD (id int);
修改列的语法是
ALTER TABLE [table name] MODIFY ( [column name] [new datatype] );
ALTER table 语法和示例
例如
ALTER TABLE employee
MODIFY( sickHours s float );
删除列的语法是
ALTER TABLE [table name] DROP COLUMN [column name];
例如
ALTER TABLE employee
DROP COLUMN vacationPay;
类型 代码 | 类型描述 | 作用于 层级 |
C | 表上的检查 | 列 |
O | 视图上的只读 | 对象 |
P | 主键 | 对象 |
R | 引用 AKA 外键 | 列 |
U | 唯一键 | 列 |
V | 视图上的检查选项 | 对象 |
以下语句显示系统中的所有约束
SELECT
table_name,
constraint_name,
constraint_type
FROM user_constraints;
以下语句显示所有引用约束(外键),包括源表/列和目标表/列对
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'
使用 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)
);
使用 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 表上创建了一个名为 customer_idx 的索引。它只包含 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,是在 Oracle 数据库上运行的基于 Web 的软件开发环境。
- 在 SQL 中: :VARIABLE
- 在 PL/SQL 中: V('VARIABLE') 或 NV('VARIABLE')
- 在文本中: &VARIABLE.