愿你如阳光,明媚不忧伤。
目録
1. SQLPLUS spool 命令详解
spool 输入中间存储是sqlplus的命令,必须在sqlplus中使用,通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得按指定方式写到文件中。用一句话来描述:就是在sqlplus中用来保存或打印查询结果。
- spool 常用设置
set colsep' '; //域输出分隔符
set echo off; //显示start启动的脚本中的每个sql命令,缺省为on
set feedback off; //回显本次sql命令处理的记录条数,缺省为on
set heading off; //输出域标题,缺省为on
set pagesize 0; //输出每页行数,缺省为24,为了避免分页,可设定为0。
set termout off; //显示脚本中的命令的执行结果,缺省为on
set trimout on; //去除标准输出每行的拖尾空格,缺省为off
set trimspool on; //去除重定向(spool)输出每行的拖尾空格,缺省为off
- 导出文本数据的建议格式
SET NEWPAGE NONE
SET HEADING OFF
SET SPACE 0
SET PAGESIZE 0
SET TRIMOUT ON
SET TRIMSPOOL ON
SET LINESIZE 2500
- SQL*PLUS SET 设置
语法:SET system_variable value
当前的会话设置一个系统变量来更改SQL*Plus环境设置,输入 “help set” 查看所有系统变量
系统变量 | 参数 | 默认值 | 说明 |
---|---|---|---|
autotrace | on,off,on explain,on statistics,traceonly1 | off | 是否允许对执行的SQL进行分析 |
colsep | char | - | 输出分隔符 |
echo | on,off | on | 是否显示脚本中正在执行的命令 |
feedback | n,on,off | 6 | 是否显示当前sql语句查询或修改的行数,只有大于n行时才会显示 |
heading | on,off | on | 输出域标题,off 以空行代替 |
linesize | n | 80 | 输出一行字符个数 |
long | n | 80 | 设置 long 类型列的在缓冲区存放的字节数 |
markup html | on,off | off | 将sqlplus的输出格式以html样式展现 |
numwidth | n | 10 | 设置 number 类型域长度 |
pagesize | n | 24 | 输出每页行数,可设定为 0 避免分页 |
serveroutput | on,off | on | 是否显示使用DBMS_OUTPUT.PUT_LINE包输出的结果,设置为on,输出的信息才能显示在屏幕中 |
termout | on,off | on | spool命令将查询的结果保存到一个文件里,设置是否同时输出在屏幕 |
timing | on,off | off | 是否显示每个sql语句执行所花费的时间 |
trimout | on,off | off | 是否去除标准输出每行的拖尾空格 |
trimspool | on,off | off | 去除spool输出结果中每行的结尾空格 |
verify | on,off | on | 设置关闭和打开提示确认信息的显示 |
warp | on,off | on | 设置折行,大于 linesize 是否显示,on 折行显示,off 切除不显示 |
2. TRANSACTION 事务
TRANSACTION 是并发控制的基本单位,所谓事务,是指在一个完整的操作序列中,序列中的操作为不可分割的工作单元,要么都执行,要么都不执行。实质就是一系列操作。
- 事务的四大特征 ACID
原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么都执行,要么都不执行
一致性(Consistency):几个并行执行的事务,其执行结果与按某一顺序串行执行的结果相一致,保证数据始终保持在一个正确的状态
隔离性(Isolation):各事务之间彼此不受影响,事务执行的中间结果对其他事务是透明的
持久性(Durability):对于任意已提交事务,即使数据库出现故障,该事务对数据库的改变也不会被丢失,事务一旦提交,将永远存在
- 事务的隔离级别
mysql 数据库查询当前事务隔离级别:select @@tx_isolation
mysql 数据库默认的事务隔离级别是:可重复读(Repeatable read)
mysql 数据库设置事务隔离级别:set transaction isolation level 隔离级别名
串行化(Serializable):可避免脏读2、不可重复读、虚读情况的发生。
可重复读(Repeatable read):可避免脏读、不可重复读情况的发生。
读已提交(Read committed):可避免脏读情况发生。
读未提交(Read uncommitted):最低级别,以上情况均无法保证。
- 事务常用处理语句
设置保存点:savepoint savepoint_name;
回滚事务:rollback to savepoint_name;
rollback;
提交事务:commit;
*****************************************************************
・【INSERT】插入数据
INSERT INTO demo_table
VALUES('IT','God','Road',2020,NOW());
*****************************************************************
・【UPDATE】更新数据
UPDATE demo_table
SET ANNUAL = ANNUAL + 1;
*****************************************************************
・【SAVEPOINT】设置保存点
SAVEPOINT SAVEPOINT_NAME;
*****************************************************************
・【DELETE】删除数据
DELETE
FROM
demo_table
WHERE
ANNUAL = 2021;
*****************************************************************
・【ROLLBACK】回滚至保存点
ROLLBACK TO SAVEPOINT SAVEPOINT_NAME;
*****************************************************************
・【SELECT】查询数据
SELECT * FROM demo_table;
*****************************************************************
・【COMMIT】提交数据
COMMIT;
*****************************************************************
3. COMPOSITE 复合数据类型
- 复合数据类型种类
1.%type:列数据类型,数据库表的某个列的数据类型
2.%rowtype:行记录数据类型,数据库表的数据结构相一致,是字段的集合
3.record:用户定义的记录数据类型,将一行数据看成一个单元,而不是将每一列单独处理
*****************************************************************
・【%type】列数据类型
-- 语法:
[ 1 ] VARIABLE_NAME DEFINITION_VARIABLE %TYPE ;
[ 2 ] VARIABLE_NAME TABLE_NAME.COLUMN_NAME %TYPE ;
-- VARIABLE_NAME:变量名
-- DEFINITION_NAME:已定义的变量名
・【%rowtype】行记录数据类型
-- 语法:
VARIABLE_NAME TABLE_NAME %ROWTYPE ;
・【RECORD】用户定义的记录数据类型
-- 语法:
[ 1 ] TYPE record_name IS RECORD (field_list); -- field_list 是用逗号分割的列表
[ 2 ] VARIABLE_NAME TABLE_NAME.COLUMN_NAME %TYPE ;
*****************************************************************
・【DECLARE TYPE】定义记录 record 的 type
DECLARE
TYPE type_name IS RECORD (
v_column_name1 % rowtype,
v_column_name2 TABLE_NAME.COLUMN_NAME %TYPE,
v_column_name3 varchar(9)
);
-- 声明一个该类型的记录作为标识符
v_record type_name;
-- 使用
BEGIN
SELECT
* INTO v_record
FROM
table_name tbn
WHERE
tbn.column_name = ( SELECT max(column_name) FROM table_another_name);
dbms_output.put_line ( v_record .column_name1||' '||v_record .column_name2 );
END;
*****************************************************************
4. Stored Procedure 存储过程
Stored Procedure 存储过程是在大型数据库系统中,一组为了完成特定功能的SQL语句集,它存储在数据库中, 一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程集成于数据库服务器中,是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升。
*****************************************************************
・【CREATE PROCEDURE】创建存储过程
CREATE [ OR REPLACE ] PROCEDURE PROCEDURE_NAME
[(
@PARAMENTER_NAME [ IN ] DATA_TYPE , -- 输入参数
@PARAMANTER_NAME [ IN ] DATA_TYPE : = DEFAULT_VALUE , -- 默认值输入参数
@PARAMETER_NAME OUT DATA_TYPE -- 输出参数
......
)]
AS
[ DECLARE_STATEMENTS ; ] --声明部分
BEGIN
EXECUTE_STATEMENTS ; --执行语句
[ EXCEPTION EXCEPTION_STATEMENTS ; ] --处理异常语句
END ;
*****************************************************************
・【CREATE PROCEDURE】存储过程示例
CREATE OR REPLACE PROCEDURE PROCEDURE_NAME
[(
@PARAMENTER_NAME [ IN ] DATA_TYPE , -- 输入参数
@PARAMANTER_NAME [ IN ] DATA_TYPE : = DEFAULT_VALUE , -- 默认值输入参数
@PARAMANTER_NAME [ IN ] DATA_TYPE : = &VARIABLE_NUMBER, -- 替换变量,要求输入为数值,而且不能为空
@PARAMANTER_NAME [ IN ] DATA_TYPE : = '&VARIABLE_CHAR' , -- 默认值输入参数,无论输入空还是字符都可以正常赋值
@PARAMETER_NAME OUT DATA_TYPE -- 输出参数
......
)]
-- 宣言部
DECLARE
name VARCHAR2 ( 10 );
message VARCHAR2 ( 50 );
noNameException EXCEPTION;
date_time VARCHAR2 ( 50 );
-- 処理部
BEGIN
-- := 赋值运算符
name := '';
message := 'ITGodRoad';
DBMS_OUTPUT.PUT_LINE ( message );
SELECT SYSDATE INTO
date_time
FROM
DUAL;
DBMS_OUTPUT.PUT_LINE ( date_time );
FOR i IN 1..12 LOOP
IF (i IN (2, 4, 6, 9, 11)) THEN
DBMS_OUTPUT.PUT_LINE(i || '月は「小の月」です');
ELSE
DBMS_OUTPUT.PUT_LINE(i || '月は「大の月」です');
END IF;
END LOOP;
IF
( name IS NOT NULL ) THEN
DBMS_OUTPUT.PUT_LINE ( '名前は' || name || 'です。' );
-- raise 抛出异常
ELSE RAISE noNameException;
END IF;
-- 例外処理部
EXCEPTION
WHEN noNameException THEN
DBMS_OUTPUT.PUT_LINE ( '名前がありません。' );
END;
................................................................
・【RESULT】実行結果
ITGodRoad
21-01-08
1月は「大の月」です
2月は「小の月」です
3月は「大の月」です
4月は「小の月」です
5月は「大の月」です
6月は「小の月」です
7月は「大の月」です
8月は「大の月」です
9月は「小の月」です
10月は「大の月」です
11月は「小の月」です
12月は「大の月」です
名前がありません。
*****************************************************************
・【EXECUTE】执行存储过程(三种方式)
[ 1 ]
SET SERVEROUTPUT ON --设置输出服务开启
EXEC PROCEDURE_NAME [PARAMETER_NAME] ; -- command命令下:执行sqlplus命令
[ 2 ]
CALL PROCEDURE_NAME [PARAMETER_NAME] ; -- SQL环境下:呼叫/调用
[ 3 ]
BEGIN
PROCEDURE_NAME [PARAMETER_NAME] ; -- PLSQL环境下:调用存储过程
END ;
*****************************************************************
・【DROP】删除存储过程
DROP PROCEDURE PROCEDURE_NAME
*****************************************************************
・【SHOW】显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等
SHOW PROCEDURE STATUS
*****************************************************************
・【SHOW】显示某一个存储过程的详细信息
SHOW CREATE PROCEDURE PROCEDURE_NAME
*****************************************************************
・【EXEC】显示存储过程对象创建文本
EXEC SP_HELPTEXT PROCEDURE_NAME
*****************************************************************
5. TRIGGER 触发器
TRIGGER 触发器是一类特殊的存储过程,对表进行INSERT , UPDATE , DELETE 时自动激活后而执行的一些列操作。级联删除,级联修改,比检查性约束更复杂的操作(检查性约束不能跨表),分为前触发器 before ,后触发器 after,行触发器 row
*****************************************************************
・【CREATE TRIGGER 】创建触发器
CREATE [ OR REPLACE ] TRIGGER TRIGGER_NAME
BEFORE / AFTER INSERT / UPDATE / DELETE
ON TABLE_NAME (创建索引也是ON)
[ FOR EACH ROW ]
[ WHEN ( BOOLEAN_EXPRESSION ) ]
PLSQL_STATEMENTS ;
*****************************************************************
・【DROP】删除触发器
DROP TRIGGER TRIGGER_NAME
*****************************************************************
・【TRIGGER_DEMO】游标 + 存储过程 使用示例
CREATE [ OR REPLACE ] TRIGGER trigger_name
AFTER UPDATE
ON table_name
FOR EACH ROW
WHEN ( abs( column_name ) > 10 )
BEGIN
IF
: new.column_name -: old.COLUMN.name < 0 THEN
dbms_output.put_line ( '下降了:' || abs( : new.column_name -: old.COLUMN.name ) );
ELSE
dbms_output.put_line ( '提高了:' || abs( : new.column_name -: old.COLUMN.name ) );
END IF;
END;
*****************************************************************
6. CURSOR 游标
CURSOR 游标是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据,它提供了对其查询结果逐行处理的能力。
游标存放在内存中,很费内存。游标一建立,就将相关的记录锁住,直到取消游标。如果数据量大,很容易使程序进入一个漫长的等待甚至死机;状态@fetch_status是一个全局的变量,如果两个或多个游标同时执行,会产生不可预知的错误;因为复杂和低效尽量不要使用游标。
- CURSOR 游标的优点
1、允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。
2、提供对基于游标位置的表中的行进行删除和更新的能力。
3、游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。
- CURSOR 游标的使用
1、定义游标:CURSOR CURSOR_NAME IS SELECT_STATEMENT ;
2、打开游标:OPEN CURSOR_NAME ;
3、提取记录:FETCH CURSOR_NAME INTO VARIABLE_LIST ;
4、关闭游标:CLOSE CURSOR_NAME ;
5、释放游标:DEALLOCATE CURSOR_NAME ;
*****************************************************************
・【DECLARE CURSOR】声明游标
-- INSENSITIVE 会将游标定义所选取出来的数据记录存放在一临时表内,对基本表的修改并不影响游标提取的数据,同时也无法通过游标来更新基本表。如果不使用该保留字,那么对基本表的更新、删除都会反映到游标中。
/*
当遇到以下情况发生时,游标将自动设定INSENSITIVE选项:
a.在SELECT 语句中使用DISTINCT、 GROUP BY、 HAVING UNION 语句;
b.使用OUTER JOIN;
c.所选取的任意表没有索引;
d.将实数值当作选取的列。
*/
-- SCROLL 滚动游标,表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用该保留字,那么只能进行NEXT提取操作。
/*
FETCH LAST FROM C --最后一行的数据,并将当前行为指定行
FETCH ABSOLUTE 4 FROM C --从第一行开始的第4行数据,并将当前行为指定行 这里的n可正可负,n>0 往下翻,n<0 往上翻
FETCH RELATIVE 3 FROM C --相对于当前行的后3行数据,并将当前行为指定行 这里的n可正可负
FETCH RELATIVE -2 FROM C --相对于当前行的前2行数据,并将当前行为指定行
FETCH PRIOR FROM C ----相对于当前行的前1行数据
FETCH FIRST FROM C --刚开始第一行的数据,并将当前行为指定行
FETCH NEXT FROM C --相对于当前行的后1行数据
*/
DECLARE CURSOR [INSENSITIVE] [SCROLL] CURSOR_NAME [( args args_type)] IS
SELECT_STATEMENT
[WHERE condition_expression;]
................................................................
DECLARE CURSOR cursor_name ( args NUMBER) IS SELECT
column_name1,
column_name2
FROM
table_name
WHERE
column_name1 > args;
BEGIN
FOR table_name IN cursor_name ( 2021 )
LOOP
dbms_output.put_line ( column_name1|| ' ' || column_name2);
END LOOP;
END;
*****************************************************************
・【OPEN】打开游标
OPEN CURSOR_NAME
*****************************************************************
・【FETCH】提取记录
FETCH CURSOR_NAME INTO VARIABLE_LIST
*****************************************************************
・【CLOSE】关闭游标
CLOSE CURSOR_NAME
*****************************************************************
・【DEALLOCATE】释放游标
DEALLOCATE CURSOR_NAME
*****************************************************************
・【CURSOR_DEMO】游标 + 存储过程 使用示例
define ERR_CD = 8 -- エラーコードの定義
define COMMIT_CNT = &1 -- 部分コミット件数
var RTC_CD NUMBER -- 声明返回值(pl/sql块外定义的变量)
DECLARE
ERR_MSG CHAR(255) := ' '; -- ERROR 情報
CNS_COMMIT_CNT CONSTANT NUMBER := &COMMIT_CNT; -- COMMIT 部分件数
WRK_UPD_CNT NUMBER; -- UPDATE 更新処理数
WRK_COMMIT_CNT NUMBER; -- COMMIT 件数
var_column_name1 % rowtype;
var_column_name2 TABLE_NAME.COLUMN_NAME %TYPE;
var_column_name3 varchar(9);
-- DBアクセス エラー例外
DB_ERR EXCEPTION;
-- カーソル定義
CURSOR CURSOR_NAME IS
SELECT column_name1,
column_name2,
column_name3
FROM table_name
[WHERE condition_expression;]
-- 開始処理、初期設定
BEGIN
/*
在pl/sql块外定义的绑定变量
variable x number;
然后在pl/sql块中用冒号加变量名进行引用 :x
*/
:RTC_CD := 0;
WRK_COMMIT_CNT := 0;
WRK_UPD_CNT := 0;
-- カーソルOPEN
OPEN CURSOR_NAME;
-- 抽出記録fetch
LOOP
FETCH CURSOR_NAME INTO var_column_name1,
var_column_name1,
var_column_name1;
/*
CURSOR_NAME % ISOPEN : 游标打开的为TRUE
CURSOR_NAME % FOUND : 只要FETCH语句返回一行记录,则该属性返回值为TRUE , 否则为FALSE
CURSOR_NAME % NOTFOUND : FETCH语句没有返回数据是TRUE
CURSOR_NAME % ROWCOUNT : 返回到现在为止从游标中取出的记录数目
*/
EXIT WHEN CURSOR_NAME % NOTFOUND ;
-- テーブル更新処理
BEGIN
UPDATE update_table_name
SET update_column_name1 = var_column_name1,
update_column_name2 = var_column_name2,
UPDATE_TIMESTAMP = TO_CHAR(SYSDATE,'YYYYMMDDHH24MISS')
WHERE update_column_name3 = var_column_name3
-- 異常処理
EXCEPTION
WHEN OTHERS THEN
-- SUBSTRB(c1,n1,n2) 从字符串中指定的开始位置,取得指定字节数的字符串
--【参数】c1是字符串,n1是开始位置,n2是字符/节数
ERR_MSG := SUBSTRB('** Err :テーブル更新Error ['
||var_column_name1||']-['
||var_column_name2']'
||SQLERRM(SQLCODE),1,255);
DBMS_OUTPUT.PUT_LINE(ERR_MSG);
RAISE DB_ERR;
END;
WRK_UPD_CNT := WRK_UPD_CNT + SQL%ROWCOUNT;
-- 更新件数がコミット件数に達した場合、コミットを行う
IF ( MOD( WRK_UPD_CNT, CNS_COMMIT_CNT ) = 0 ) THEN
COMMIT;
WRK_COMMIT_CNT := WRK_UPD_CNT;
END IF;
END LOOP;
CLOSE CURSOR_NAME;
COMMIT;
DBMS_OUTPUT.PUT_LINE('テーブル更新処理 END');
DBMS_OUTPUT.PUT_LINE('テーブル更新件数: '||WRK_UPD_CNT||' 件');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SUBSTRB(SQLERRM(SQLCODE),1,255));
DBMS_OUTPUT.PUT_LINE('テーブル更新処理 Error ');
DBMS_OUTPUT.PUT_LINE('テーブル更新件数: '||WRK_COMMIT_CNT||' 件');
ROLLBACK;
:RTC_CD := &ERR_CD;
END;
7. FUNCTION 自定义函数
FUNCTION 函数 可以看成一个处理某些数据的功能,类似于 java 中的方法,必须有返回值。分为标量函数(返回一个标量值)和表格值函数(返回多个数据 / 集合)。
*****************************************************************
・【CREATE FUNCTION】创建函数
CREATE FUNCTION FUNCTION_NAME (
@PARAMENTER_NAME IN DATA_TYPE , -- 输入参数
@PARAMANTER_NAME IN DATA_TYPE : = DEFAULT_VALUE , -- 默认值输入参数
@PARAMANTER_NAME IN TABLE_NAME.COLUMN_NAME %TYPE,
@PARAMANTER_NAME OUT varchar(9), -- 输出参数
@PARAMANTER_NAME INOUT varchar(9),-- 输入输出参数
) RETURNS DATA_TYPE
-- Schemabinding :将函数绑定到它引用的对象上(注:函数一旦绑定,则不能删除、修改,除非删除绑定)
[with{ Encryption | Schemabinding }]
[ AS ]
BEGIN
SQL_STATEMENTS (必须有return 变量或值)
END
*****************************************************************
・【FUNCTION】标量函数
CREATE FUNCTION functionDemo (
@fruit varchar ( 20 )
) RETURNS boolean -- 返回值类型
[AS]
BEGIN
IF SELECT count( NAME ) FROM fruits WHERE NAME = @fruit
RETURN FALSE;
END IF;
RETURN TRUE;
END
................................................................
・【FUNCTION】函数引用
SELECT coloumn FROM table_name WHERE column_name = functionDemo ('Apple');
*****************************************************************
・【FUNCTION】表格值函数( 内联 )
CREATE FUNCTION functionDemo (
@fruit varchar ( 20 )
) RETURNS table_name -- 返回数据集
[AS]
RETURN ( SELECT * FROM table_name WHERE column_name LIKE %@fruit%;
................................................................
・【FUNCTION】表格值函数( 多表 )
CREATE FUNCTION functionDemo (
@fruit varchar ( 20 )
) RETURNS @table_name -- 返回数据集
[AS]
BEGIN
INSERT @table_name (
SELECT * FROM table_name WHERE column_name LIKE %@fruit%
);
RETURN;
END
................................................................
・【FUNCTION】函数引用
SELECT * FROM functionDemo ('Apple');
*****************************************************************
・【DROP】删除函数
DROP FUNCTION FUNCTION_NAME;
*****************************************************************
・【SHOW】显示数据库中所有存储的函数基本信息,包括所属数据库,函数名称,创建时间等
SHOW FUNCTION STATUS;
*****************************************************************
・【SHOW】显示某一个函数的详细信息
SHOW CREATE FUNCTION FUNCTION_NAME;
*****************************************************************
8. EVENT 事件
EVENT 类似于定时任务,当想让mysql在指定事件或者每隔一段时间执行一些语句时,就可以创建一个事件
*****************************************************************
・【CREATE EVENT】创建事件
CREATE EVENT EVENT_NAME
ON SCHEDULE
{
AT 'point-in-time'|
EVERY 'time interval' [STARTS datetime][END datetime]
}
DO
BEGIN
SQL_STATEMENTS ;
END
*****************************************************************
・【point-in-time】在某个时间点执行
CREATE EVENT event_name
ON SCHEDULE
AT '2021-12-25 10:00:00'
DO
BEGIN
INSERT INTO test(detail, message) VALUES('圣诞快乐', '定点执行');
END
*****************************************************************
・【point-in-time】在两天后的当前时间执行
CREATE EVENT event_name
ON SCHEDULE
AT DATE_ADD(NOW(), INTERVAL 2 DAY)
DO
BEGIN
INSERT INTO test(detail, message) VALUES('ITGodRoad', '间隔执行');
END
*****************************************************************
・【point-in-time】每隔一小时执行一次
CREATE EVENT event_name
ON SCHEDULE
EVERY 1 HOUR [ STARTS '2021-01-19 15:48:54' ENDS '2021-01-20 00:00:00']
DO
BEGIN
INSERT INTO test(detail, message) VALUES('ITGodRoad', '循环执行');
END
*****************************************************************
・【SET GLOBAL】手动开启事件
SET GLOBAL event_scheduler = ON;
*****************************************************************
・【SHOW】查看所有定义的事件语句
SHOW EVENTS;
*****************************************************************
・【SHOW CREATE】查看具体事件语句
SHOW CREATE EVENT event_name;
*****************************************************************
・【DROP】删除事件
DROP EVENT event_name;
*****************************************************************
【每日一面】
复合数据类型 record 和 table 的区别
RECORD 记录是一种单行多列 的复合结构 ,将一个或多个标量封装成一个结构体进行操作。
记录可以直接赋值 ,即:RECORD1 := RECORD2;
记录不可以整体比较(整体判断为空)只可以判断记录字段 。
使用record变量类型时,如果表的结构发生改变(字段增删),需要从新定义record类型,比较麻烦。
解决方案可以用rowtype声明record变量类型
TABLE 实际上是一个数组 类型。
记录:无法存储在数据库中;不能递归引用;不能将逻辑定义为其定义的一部分。对象:可以存储为数据库表列或整行;可以使用self参数递归引用;可以使用成员方法将逻辑定义为其定义的一部分。