文档库 最新最全的文档下载
当前位置:文档库 › 第七章 控制PL-SQL错误 - PL-SQL用户指南与参考

第七章 控制PL-SQL错误 - PL-SQL用户指南与参考

第七章 控制PL-SQL错误 - PL-SQL用户指南与参考
第七章 控制PL-SQL错误 - PL-SQL用户指南与参考

第七章 控制 PL/SQL 错误
第七章 控制 PL/SQL 错误 一、错误控制一览 在 PL/SQL 中,警告或错误被称为异常。异常可以是内部(运行时系统)定义的或是用户定义的。内部定义的案例包括除零操作和内 存溢出等。一些常见的内部异常都有一个预定义的名字,如 ZERO_DIVIDE 和 STORAGE_ERROR 等。对于其它的内部异常,我 们可以手动为它们命名。 我们可以在 PL/SQL 块、子程序或包的声明部分自定义异常。例如,我们可以定义一个名为 insufficient_funds 的异常来标示帐户 透支的情况。与内部异常不同的是,用户自定义异常必须有一个名字。 错误发生时,异常就会被抛出。也就是说,正常的执行语句会被终止,控制权被转到 PL/SQL 块的异常控制部分或子程序的异常控 制部分。内部异常会由运行时系统隐式地抛出,而用户定义异常必须显式地用 RAISE 语句抛出,RAISE 语句也可以抛出预定义异 常。 为了控制被抛出的异常,我们需要单独编写被称为"exception handler"的异常控制程序。异常控制程序运行后,当前块就会停止 执行,封闭块继续执行下一条语句。如果没有封闭块,控制权会直接交给主环境。 下例中,我们为一家股票代码(Ticker Symbol)为 XYZ 的公司计算并保存市盈率(price-to-earning)。如果公司的收入为零,预定 义异常 ZERO_DIVIDE 就会被抛出。这将导致正常的执行被终止,控制权被交给异常控制程序。可选的 OTHERS 处理器可以捕获 所有的未命名异常。
DECLARE pe_ratio BEGIN SELECT price / earnings INTO pe_ratio FROM stocks WHERE symbol = 'XYZ'; -- might cause division-by-zero error INSERT INTO stats (symbol, ratio) VALUES ('XYZ', pe_ratio); COMMIT; EXCEPTION -- exception handlers begin -- handles 'division by zero' error WHEN ZERO_DIVIDE THEN VALUES ('XYZ', NULL); COMMIT; ... WHEN OTHERS THEN ROLLBACK; END; -- exception handlers and block end here -- handles all other errors NUMBER (3, 1);
INSERT INTO stats (symbol, ratio)
上面的例子演示了异常控制,但对于 INSERT 语句的使用就有些低效了。使用下面的语句就要好一些:

INSERT INTO stats (symbol, ratio) SELECT symbol, DECODE (earnings, 0, NULL, price / earnings) FROM stocks WHERE symbol = 'XYZ'; 在下面这个例子中,子查询为 INSERT 语句提供了数据。如果 earnings 是零的话,函数 DECODE 就会返回空,否则 DECODE 就 会返回 price 与 earnings 的比值。 二、异常的优点 使用异常来控制错误有几个优点。如果没有异常控制的话,每次执行一条语句,我们都必须进行错误检查:
BEGIN SELECT ... -- check for ’no data found’ error SELECT ... -- check for ’no data found’ error SELECT ... -- check for ’no data found’ error 错误处理和正常的处理内容界限不明显,导致代码混乱。如果我们不编写错误检查代码,一个错误就可能引起其它错误,有时还可 能是一些无关错误。 但有了异常后,我们就能很方便的控制错误,而且不需要编写多个检查代码:
BEGIN SELECT ... SELECT ... SELECT ... ... EXCEPTION WHEN NO_DATA_FOUND THEN -- catches all 'no data found' errors 异常能把错误控制程序单独分离出来,改善可读性,主要的算法不会受到错误恢复算法影响。异常还可以提高可靠性。我们不需要 在每一个可能出现错误的地方编写错误检查代码了,只要在 PL/SQL 块中添加一个异常控制代码即可。这样,如果有异常被抛出, 我们就可以确保它能够被捕获并处理。 三、预定义 PL/SQL 异常 当我们的 PL/SQL 程序与 Oracle 规则相冲突或超过系统相关(system-dependent)的限制时, 内部异常就会被抛出。 每个 Oracle 错误都有一个错误编号,但异常只能按名称捕获,然后被处理。所以,PL/SQL 把一些常见 Oracle 错误定义为异常。例如,如果 SELECT INTO 语句查询不到数据时,PL/SQL 就会抛出预定义异常 NO_DATA_FOUND。 要控制其它 Oracle 异常,我们可以使用 OTHERS 处理器。函数 SQLCODE 和 SQLERRM 在 OTHERS 处理器中特别有用,因为 它们能返回 Oracle 错误编号和消息。 另外, 我们还可以使用编译指示(pragma)EXCEPTION_INIT 把一个异常名称和一个 Oracle

错误编号关联起来。PL/SQL 在 STANDARD 包中声明了全局预定义异常。所以,我们不需要自己声明它们。我们可以为下面列表 中命名的预定义异常编写处理程序: 异常 ACCESS_INTO_NULL CASE_NOT_FOUND COLLECTION_IS_NULL CURSOR_ALREADY_OPEN DUP_VAL_ON_INDEX INVALID_CURSOR INVALID_NUMBER LOGIN_DENIED NO_DATA_FOUND NOT_LOGGED_ON PROGRAM_ERROR ROWTYPE_MISMATCH SELF_IS_NULL STORAGE_ERROR Oracle 错误号 SQLCODE 值 ORA-06530 ORA-06592 ORA-06531 ORA-06511 ORA-00001 ORA-01001 ORA-01722 ORA-01017 ORA-01403 ORA-01012 ORA-06501 ORA-06504 ORA-30625 ORA-06500 -6530 -6592 -6531 -6511 -1 -1001 -1722 -1017 100 -1012 -6501 -6504 -30625 -6500 -6533 -6532 -1410 -51 -1422 -6502 -1476
SUBSCRIPT_BEYOND_COUNT ORA-06533 SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 SYS_INVALID_ROWID TIMEOUT_ON_RESOURCE TOO_MANY_ROWS VALUE_ERROR ZERO_DIVIDE 预定义异常的简要描述: 异常 ACCESS_INTO_NULL CASE_NOT_FOUND COLLECTION_IS_NULL ORA-01410 ORA-00051 ORA-01422 ORA-06502 ORA-01476
抛出时机 程序尝试为一个未初始化(自动赋为 null)对象的属性赋值。 CASE 语句中没有任何 WHEN 子句满足条件,并且没有编写 ELSE 子句。 程序尝试调用一个未初始化(自动赋为 null)嵌套表或变长数组的集合方法(不包括 EXISTS), 或 者是程序尝试为一个未初始化嵌套表或变长数组的元素赋值。
CURSOR_ALREADY_OPEN
程序尝试打开一个已经打开的游标。一个游标在重新打开之前必须关闭。一个游标 FOR 循环会 自动打开它所引用的游标。所以,我们的程序不能在循环内部打开游标。
DUP_VAL_ON_INDEX INVALID_CURSOR INVALID_NUMBER
程序尝试向一个有着唯一约束条件的数据库字段中保存重复值。 程序尝试操作一个不合法的游标,例如关闭一个未打开的游标。 在一个 SQL 语句中,由于字符串并不代表一个有效的数字,导致字符串向数字转换时会发生错 误。(在过程化语句中,会抛出异常 VALUE_ERROR。)当 FETCH 语句的 LIMIT 子句表达式后

面不是一个正数时,这个异常也会被抛出。 LOGIN_DENIED NO_DATA_FOUND 程序尝试使用无效的用户名和/或密码来登录 Oracle。 SELECT INTO 语句没有返回数据, 或者是我们的程序引用了一个嵌套表中被删除了的元素或是 索引表中未初始化的元素。SQL 聚合函数,如 AVG 和 SUM,总是能返回一个值或空。所以, 一个调用聚合函数的 SELECT INTO 语句从来不会抛出 NO_DATA_FOUND 异常。FETCH 语 句最终会取不到数据,当这种情况发生时,不会有异常抛出的。 NOT_LOGGED_ON PROGRAM_ERROR ROWTYPE_MISMATCH 程序没有连接到 Oracle 就要调用数据库。 PL/SQL 程序发生内部错误。 赋值语句中使用的主游标变量和 PL/SQL 游标变量的类型不兼容。例如,当一个打开的主游标 变量传递到一个存储子程序时,实参的返回类型和形参的必须一致。 SELF_IS_NULL 程序尝试调用一个空实例的 MEMBER 方法。也就是内置参数 SELF(它总是第一个传递到 MEMBER 方法的参数)是空。 STORAGE_ERROR PL/SQL 运行时内存溢出或内存不足。
SUBSCRIPT_BEYOND_COUNT 程序引用一个嵌套表或变长数组元素,但使用的下标索引超过嵌套表或变长数组元素总个数。 SUBSCRIPT_OUTSIDE_LIMIT 程序引用一个嵌套表或变长数组,但使用的下标索引不在合法的范围内(如-1)。 SYS_INVALID_ROWID TIMEOUT_ON_RESOURCE TOO_MANY_ROWS VALUE_ERROR 从字符串向 ROWID 转换发生错误,因为字符串并不代表一个有效的 ROWID。 当 Oracle 等待资源时,发生超时现象。 SELECT INTO 语句返回多行数据。 发生算术、转换、截位或长度约束错误。例如,当我们的程序把一个字段的值放到一个字符变量 中时, 如果值的长度大于变量的长度, PL/SQL 就会终止赋值操作并抛出异常 VALUE_ERROR。 在过程化语句中,如果字符串向数字转换失败,异常 VALUE_ERROR 就会被抛出。(在 SQL 语 句中,异常 INVALID_NUMBER 会被抛出。) ZERO_DIVIDE 四、自定义 PL/SQL 异常 PL/SQL 允许我们定义自己的异常。与预定义异常不同的是,用户自定义异常必须声明,并且需要用 RAISE 语句显式地抛出。 1、声明 PL/SQL 异常 异常只能在 PL/SQL 块、子程序或包的声明部分声明。下例中,我们声明一个名为 past_due 的异常: 程序尝试除以 0。
DECLARE past_due EXCEPTION; 异常和变量的声明是相似的。但是要记住,异常是一种错误情况(error condition),而不是数据项。与变量不同的是,异常不能出 现在赋值语句或是 SQL 语句中。但是,变量的作用域规则也适用于异常。 2、PL/SQL 异常的作用域规则 在同一个块内,异常不能声明两次。但可以在不同的块声明相同的异常。

块中声明的异常对于当前块来说是本地的,但对于当前块的所有子块来说是全局的。因为块只能引用本地或全局的异常,所以封闭 块不能引用声明在子块中的异常。 如果我们在子块中重新声明了一个全局的异常,本地声明的异常的优先级是要高于全局的。所以,子块就不能引用全局的异常,除 非全局异常在它的所在块中用标签作了标记,这种情况下可以使用下面的语法来引用全局异常:
block_label.exception_name 下例中演示了作用范围规则:
DECLARE past_due acct_num BEGIN DECLARE past_due acct_num BEGIN ... IF ... THEN RAISE past_due; END IF; END; -- sub-block ends -- does not handle RAISEd exception EXCEPTION WHEN past_due THEN ... END; 上例中的封闭块并不能捕获抛出来的异常,因为在子块中声明的 past_due 优先级要高于封闭块声明的异常。虽然它们的名字相同, 但实际上是两个不同的 past_due 异常, 就像两个 acct_num 变量只是共享着相同的名字一样, 实际上它们是完全不同的两个变量。 因此,RAISE 语句和 WHEN 子句所引用的是不同的异常。如果想让封闭块能捕获到子块中的 past_due 异常,我们就必须从子块 中删除声明,或是在封闭块中添加 OTHERS 处理器。 3、把 PL/SQL 异常与编号关联:编译指示 EXCEPTION_INIT 要想控制没有预定义名称的错误(通常为 ORA- 消息),我们就必须使用 OTHERS 处理器或编译指示 EXCEPTION_INIT。编译指 示就是能在编译期而非运行时进行处理的编译指令。 在 PL/SQL 中,编译指示 EXCPTION_INIT 能告诉编译器把异常名称和错误编号关联起来。这就能让我们按名称来引用所有的内部 异常,并为它编写特定的处理程序。在我们看到的错误栈或是错误消息序列中,最顶层的就是我们能捕获和处理的信息。 我们可以把编译指示 EXCEPTION_INIT 写在 PL/SQL 块、子程序或包的声明部分,语法如下: -- this is not handled -- sub-block begins EXCEPTION; NUMBER; -- this declaration prevails EXCEPTION; NUMBER;
PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);

其中 exception_name 是已经声明过的异常名称,Oracle_error_number 是 Oracle 错误编号。编译指示必须和异常声明处于同 一个声明中,并且只能在异常声明之后出现。如下例所示:
DECLARE deadlock_detected BEGIN ... -- Some operation that causes an ORA-00060 error EXCEPTION WHEN deadlock_detected THEN -- handle the error ... END; EXCEPTION; PRAGMA EXCEPTION_INIT (deadlock_detected, -60);
4、自定我们自己的错误消息:过程 RAISE_APPLICATION_ERROR 过程 RAISE_APPLICATION_ERROR 能帮助我们从存储子程序中抛出用户自定义的错误消息。这样,我们就能把错误消息报告给 应用程序而避免返回未捕获异常。 调用 RAISE_APPLICATION_ERROR 的语法如下:
raise_application_error(error_number, message[, {TRUE | FALSE}]); error_number 是一个范围在-20000 至-20999 之间的负整数, message 是最大长度为 2048 字节的字符串。 如果第三个可选参 数为 TRUE 的话,错误就会被放到前面错误的栈顶。如果为 FALSE(默认值),错误就会替代前面所有的错误。 RAISE_APPLICATION_ERROR 是包 DBMS_STANDARD 的一部分,所以,我们对它的引用不需要添加限定修饰词。 应用程序只能从一个正在执行的存储子程序或方法中调用 raise_application_error。在调用时, raise_application_error 会结 束子程序并把用户定义的错误编号和消息返回给应用程序。错误编号和消息可以像其它的 Oracle 错误一样被捕获。 在下面的例子中,我们在雇员工资栏的内容为空的情况下调用 raise_application_error:
CREATE PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER) AS curr_sal BEGIN SELECT sal INTO curr_sal FROM emp WHERE empno = emp_id; IF curr_sal IS NULL THEN /* Issue user-defined error message. */ raise_application_error (-20101, 'Salary is missing'); NUMBER;

ELSE UPDATE emp SET sal = curr_sal + amount WHERE empno = emp_id; END IF; END raise_salary; 调用程序会得到一个 PL/SQL 异常,它能在 OTHERS 处理器中使用错误报告函数 SQLCODE 和 SQLERRM 来进行处理。同样,我 们也可以使用编译指示 EXCEPTION_INIT 把 raise_application_error 返回的错误编号映射到异常本身。 如下面的 Pro*C 例子所 示:
EXEC SQL EXECUTE /* Execute embedded PL/SQL block using host variables my_emp_id and my_amount, which were assigned values in the host environment. */ DECLARE null_salary EXCEPTION; /* Map error number returned by raise_application_error to user-defined exception. */ PRAGMA EXCEPTION_INIT (null_salary, -20101); BEGIN raise_salary (:my_emp_id, :my_amount); EXCEPTION WHEN null_salary THEN INSERT INTO emp_audit VALUES (:my_emp_id, ...); END; END-EXEC; 这项技术能让调用程序在特定的异常处理程序中控制错误。 5、重新声明预定义异常 请记住,PL/SQL 把预定义的异常作为全局内容声明在包 STANDARD 中,所以,我们没有必要重新声明它们。重新声明预定义异 常是错误的做法,因为我们的本地声明会覆盖掉全局声明。例如,如果我们声明了一个 invalid_number,当 PL/SQL 抛出预定义 异常 INVALID_NUMBER 时,我们为异常 INVALID_NUMBER 编写的异常控制程序就无法正确地捕获到它了。这种情况下,我们 必须像下面这样使用点标志来指定预定义异常:
EXCEPTION WHEN INVALID_NUMBER OR STANDARD.INVALID_NUMBER THEN -- handle the error END;

五、如何抛出 PL/SQL 异常 内部异常会由运行时系统隐式地抛出,其中也包括使用编译指示 EXCEPTION_INIT 与 Oracle 错误编号关联起来的用户自定义异 常。但是,用户自定义的异常就必须显式地用 RAISE 语句抛出。 1、使用 RAISE 语句抛出异常 PL/SQL 块和子程序应该只在错误发生或无法完成正常程序处理的时候才抛出异常。下例中,我们用 RAISE 语句抛出一个用户自定 义的 out_of_stack 异常:
DECLARE out_of_stock BEGIN ... IF number_on_hand < 1 THEN RAISE out_of_stock; END IF; EXCEPTION WHEN out_of_stock THEN -- handle the error END; 我们也可以显式地抛出预定义异常。这样,为预定义异常编写的处理程序也就能够处理其它错误了,示例如下: EXCEPTION; NUMBER (4); number_on_hand
DECLARE acct_type BEGIN IF acct_type NOT IN (1, 2, 3) THEN RAISE INVALID_NUMBER; END IF; EXCEPTION WHEN INVALID_NUMBER THEN ROLLBACK; END; 六、PL/SQL 异常的传递 异常被抛出时,如果 PL/SQL 在当前块或子程序中没有找到对应的异常控制程序,异常就会被继续向上一级传递。也就是说异常会 把它自身传递到后继的封闭块直到找到异常处理程序或是再也没有可以搜索到的块为止。在后一种情况下,PL/SQL 会向主环境抛 出一个未捕获异常。 但是,异常是不能通过远程过程调用(RPC)来传递的。因此,PL/SQL 块不能捕获由远程子程序抛出的异常。下面三幅图演示了异常 基本的传递规则。 -- raise predefined exception INTEGER := 7;

异常可以跨作用域传递,也就是说,它能够超越声明它的块的范围而存在。如下例所示:

BEGIN ... DECLARE past_due BEGIN ... IF ... THEN RAISE past_due; END IF; END; ... WHEN OTHERS THEN ROLLBACK; END; 因为异常 past_due 所在的块并没有专门针对它的处理程序,所以异常就被传递到封闭块。但是,按照作用域规则,封闭块是不能 引用子块声明的异常。所以,只有 OTHERS 处理器才能捕获到这个异常。如果没有用户定义异常的处理程序,调用这个程序就会得 到下面的错误: -- sub-block ends EXCEPTION -- sub-block begins EXCEPTION;
ORA-06510: PL/SQL: unhandled user-defined exception 七、重新抛出 PL/SQL 异常 有时我们需要重新抛出捕获到异常,也就是说,我们想在本地处理之后再把它传递到封闭块。比如,在异常发生的时候,我们可能 需要回滚事务,然后在封闭块中写下错误日志。 要重新抛出异常,只要在本地处理程序中放置一个 RAISE 语句即可,示例如下:
DECLARE out_of_balance BEGIN ... BEGIN ... IF ... THEN RAISE out_of_balance; END IF; EXCEPTION WHEN out_of_balance THEN -- handle the error RAISE; END; EXCEPTION -- reraise the current exception -- sub-block ends -- raise the exception -- sub-block begins EXCEPTION;

WHEN out_of_balance THEN -- handle the error differently ... END; 如果在 RAISE 语句中省略了异常名称——只允许在异常处理程序中这样做——程序就会把当前的异常重新抛出。 八、处理 PL/SQL 异常 异常抛出时,PL/SQL 块或子程序的正常执行就会停止,控制权转到块或子程序的异常处理部分,语法如下:
EXCEPTION WHEN exception_name1 THEN sequence_of_statements1 WHEN exception_name2 THEN sequence_of_statements2 ... WHEN OTHERS THEN END; 为捕获抛出的异常,我们需要编写异常处理程序。每个处理程序都由一个 WHEN 子句和语句序列组成。这些语句执行完毕后,块或 子程序就会结束,控制权不再返回异常被抛起的地方。换句话说,也就是我们不能再次返回异常发生的地方继续执行我们的程序。 可选的 OTHERS 处理器总是块或子程序的最后一个处理程序,它可以用于捕获所有的未命名异常。因此,块或子程序只能有一个 OTHERS 处理器。如下例所示,OTHERS 处理器能够保证所有的异常都会被控制: -- optional handler sequence_of_statements3 -- another handler -- handler
EXCEPTION WHEN ... THEN -- handle the error WHEN ... THEN -- handle the error WHEN OTHERS THEN -- handle all other errors END; 如果我们想让两个或更多的异常执行同样的语句序列,只需把异常名称用关键字 OR 隔开,放在同一个 WHEN 子句中即可,如下例 所示:
EXCEPTION WHEN over_limit OR under_limit OR VALUE_ERROR THEN -- handle the error 只要在 WHEN 子句的异常列表中有一项与被抛出异常相匹配,相关的语句序列就会被执行。关键字 OTHERS 不能出现在异常名称

列表中;它只能单独使用。我们可以有任意数量的异常处理程序,而且每个处理程序都与一个异常列表及其对应的语句序列相关联。 但是,异常名称只能在块或子程序的异常处理部分出现一次。 变量作用范围的规则在这里也同样适用,所以我们可以在异常处理程序中引用本地或全局变量。但是,当游标 FOR 循环中有异常抛 出时,游标就会在异常处理程序调用之前被隐式地关闭。因此,显式游标的属性值在异常处理程序中就不再可用了。 1、声明中控制异常 如果在声明时使用了错误的初始化表达式也有可能引发异常。例如,下面的声明就是因常量 credit_limit 不能存储超过 999 的数字 而抛出了异常:
DECLARE credit_limit CONSTANT NUMBER(3) := 5000; BEGIN ... EXCEPTION WHEN OTHERS THEN ... END; 当前块中的处理程序并不能捕获到抛出的异常,这是因为声明时抛出的异常会被立即传递到最近的封闭块中去。 2、异常句柄中控制异常 在一个块或子程序中,一次只能有一个异常被激活。所以,一个被异常处理程序抛出的异常会被立即传递到封闭块,在那儿,封闭 块会为它查找新的处理程序。从那一刻起,异常传递才开始正常化。参考下面的例子: -- cannot catch the exception -- raises an exception
EXCEPTION WHEN INVALID_NUMBER THEN INSERT INTO ... END; -- might raise DUP_VAL_ON_INDEX -- cannot catch the exception WHEN DUP_VAL_ON_INDEX THEN ...
3、异常分支 GOTO 语句不能跳转到异常控制程序。同样,GOTO 语句也不能从异常控制程序跳转到当前块。例如,下面的 GOTO 语句就是非 法的:
DECLARE pe_ratio BEGIN DELETE FROM stats WHERE symbol = 'xyz'; SELECT price / NVL (earnings, 0) NUMBER (3, 1);

INTO pe_ratio FROM stocks WHERE symbol = 'xyz'; <> INSERT INTO stats (symbol, ratio) VALUES ('xyz', pe_ratio); EXCEPTION WHEN ZERO_DIVIDE THEN pe_ratio := 0; GOTO my_label; END; 但是,GOTO 语句可以从一个异常控制程序中跳转到一个封闭块。 4、获取错误代号与消息:SQLCODE 和 SQLERRM 在异常处理程序中,我们可以使用内置函数 SQLCODE 和 SQLERRM 来查出到底发生了什么错误,并能够获取相关的错误信息。对 于内部异常来说, SQLCODE 会返回 Oracle 错误编号。SQLCODE 返回的总是一个负数,除非发生的 Oracle 错误是没有找到数 据,这时返回的是+100。 SQLERRM 会返回对应的错误消息。消息是以 Oracle 错误编号开头的。 如果我们没有使用编译指令 EXCEPTION_INIT 把异常与编号关联的话, SQLCODE 和 SQLERRM 就会分别返回+1 和消息"UserDefined Exception"。Oracle 错误消息最大长度是 512 个字符,其中包括错误编号、嵌套消息和具体表和字段的名称。 如果没有异常抛出,SQLCODE 返回 0,SQLERRM 返回消息"ORA-0000: normal, successful completion"。 我们可以把错误编号传递给 SQLERRM,让它返回对应的错误消息。但是,一定要保证我们传递给 SQLERRM 的错误编号是负数。 下例中,我们把一个正数传递给 SQLERRM,结果就不是我们想要的那样的了: -- illegal branch into current block
DECLARE err_msg BEGIN /* Get all Oracle error messages. */ FOR err_num IN 1 .. 9999 LOOP err_msg := SQLERRM(err_num); -- wrong; should be -err_num VARCHAR2(100);
INSERT INTO ERRORS VALUES (err_msg); END LOOP; END; 把正数传给 SQLERRM 时,如果传递的是+100,返回的结果是"no data found",其他情况总是会返回消息"user-defined exception"。把 0 传递给 SQLERRM,就会返回消息"normal, successful completion"。 我们不能直接在 SQL 语句中使用 SQLCODE 或 SQLERRM。我们必须先把它们的值赋给本地变量,然后再在 SQL 中使用变量,如

下例所示:
DECLARE err_num err_msg BEGIN ... EXCEPTION WHEN OTHERS THEN err_num err_msg := SQLCODE; := SUBSTR(SQLERRM, 1, 100); NUMBER; VARCHAR2(100);
INSERT INTO ERRORS VALUES (err_num, err_msg); END; 字符串函数 SUBSTR 可以保证用 SQLERRM 为 err_msg 赋值时不会引起 VALUE_ERROR 异常。函数 SQLCODE 和 SQLERRM 在 OTHERS 异常处理程序中特别有用,因为它们能让我们知道哪个内部异常被抛出。 注意:在使用编译指示 RESTRICT_REFERENCES 判断存储函数的纯度时,如果函数调用了 SQLCODE 和 SQLERRM,我们就不 能指定约束为 WNPS 和 RNPS 了。 5、捕获未控制异常 记住,如果被抛出的异常找不到合适的异常控制程序,PL/SQL 会向主环境抛出一个未捕获的异常错误,然后由主环境决定如何处 理。例如,在 Oracle 预编译程序环境中,任何一个执行失败的 SQL 语句或 PL/SQL 块所涉及到的改动都会被回滚。 未捕获也能影响到子程序。如果我们成功地从子程序中退出,PL/SQL 就会把值赋给 OUT 参数。但是,如果我们因未捕获异常而退 出程序,PL/SQL 就不会为 OUT 参数进行赋值。同样,如果一个存储子程序因异常而执行失败,PL/SQL 也不会回滚子程序所做的 数据变化。 我们可以在每个 PL/SQL 程序的顶级使用 OTHERS 句柄来捕获那些没有被子程序捕捉到的异常。 九、PL/SQL 错误控制技巧 这里,我们将学习三个提高程序灵活性的技巧。 1、模拟 TRY..CATCH..块 异常控制程序能让我们在退出一个块之前做一些恢复操作。但是在异常程序完成后,语句块就会终止。我们不能从异常句柄再重新 回到当前块。例如,如果下面的 SELECT INTO 语句引起了 ZERO_DIVIDE 异常,我们就不能执行 INSERT 语句了:
DECLARE pe_ratio BEGIN NUMBER(3, 1);

DELETE FROM stats WHERE symbol = 'XYZ'; SELECT price / NVL(earnings, 0) INTO pe_ratio FROM stocks WHERE symbol = 'XYZ'; INSERT INTO stats(symbol, ratio) VALUES ('XYZ', pe_ratio); EXCEPTION WHEN ZERO_DIVIDE THEN ... END; 其实我们可以控制某一条语句引起的异常,然后继续下一条语句。只要把可能引起异常的语句放到它自己的子块中,并编写对应的 异常控制程序。一旦在子块中有错误发生,它的本地异常处理程序就能捕获并处理异常。当子块结束时,封闭块程序会继续执行紧 接着的下一条语句。如下例:
DECLARE pe_ratio BEGIN DELETE FROM stats WHERE symbol = 'XYZ'; BEGIN -- sub-block begins NUMBER(3, 1);
SELECT price / NVL(earnings, 0) INTO pe_ratio FROM stocks WHERE symbol = 'XYZ'; EXCEPTION WHEN ZERO_DIVIDE THEN pe_ratio END; := 0; -- sub-block ends
INSERT INTO stats(symbol, ratio) VALUES ('XYZ', pe_ratio); EXCEPTION WHEN OTHERS THEN ... END; 在上面这个例子中,如果 SELECT INTO 语句抛出了 ZERO_DIVIDE 异常,本地异常处理程序就会捕捉到它并把 pe_ratio 赋值为 0。当处理程序完成时,子块也就终止,INSERT 语句就会被执行。

2、反复执行的事务 异常发生后,我们也许还不想放弃我们事务,仍想重新尝试一次。这项技术的实现方法就是: 1. 把事务装入一个子块中。 2. 把子块放入一个循环,然后反复执行事务 3. 在开始事务之前标记一个保存点。如果事务执行成功的话,就提交事务并退出循环。如果事务执行失败,控制权就会交给 异常处理程序,事务回滚到保存点,然后重新尝试执行事务。 如下例所示。当异常处理程序完成时,子块终止,控制权被交给外围块的 LOOP 语句,子块再次重新开始执行。而且,我们还可以 用 FOR 或 WHILE 语句来限制重做的次数。
DECLARE NAME ans1 ans2 ans3 suffix BEGIN ... LOOP -- could be FOR i IN 1..10 LOOP to allow ten tries -- sub-block begins -- mark a savepoint BEGIN VARCHAR2(20); VARCHAR2(3); VARCHAR2(3); VARCHAR2(3); NUMBER := 1;
SAVEPOINT start_transaction;
/* Remove rows from a table of survey results. */ DELETE FROM results WHERE answer1 = ’no’; /* Add a survey respondent’s name and answers. */ INSERT INTO results VALUES (NAME, ans1, ans2, ans3); -- raises DUP_VAL_ON_INDEX if two respondents have the same name COMMIT; EXIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK TO start_transaction; suffix NAME END; END; END LOOP; := suffix + 1; -- undo changes -- try to fix problem
:= NAME || TO_CHAR(suffix);
-- sub-block ends

3、使用定位变量标记异常发生点 只用一个异常句柄来捕获一系列语句的话,可能无法知道到底是哪一条语句产生了错误:
BEGIN SELECT ... SELECT ... EXCEPTION WHEN NO_DATA_FOUND THEN ... -- Which SELECT statement caused the error? END; 要想解决这个问题,我们可以使用一个定位变量来跟踪执行语句,例如: DECLARE stmt INTEGER := 1; BEGIN SELECT ... stmt := 2; SELECT ... EXCEPTION WHEN NO_DATA_FOUND THEN INSERT INTO errors VALUES ('Error in statement ' || stmt); END; -- designates 2nd SELECT statement -- designates 1st SELECT statement

服务器系统管理

服务器系统管理 一、服务器硬件知识 1.服务器主板 服务器主板概述 对于服务器而言,稳定性才是首要,服务器必须承担长年累月高负荷的工作要求,而且不能像台式机一样随意的重起,为了提高起可靠性普遍的做法都是部件的冗余技术,而这一切的支持都落在主板的肩上。下面我就来看看有关服务器主板的一些特性: 1、首先,服务器的可扩展性决定着它们的专用板型为较大的ATX,EATX或WATX。 2、中高端服务器主板一般都支持多个处理器,所采用的CPU也是专用的CPU。 3、主板的芯片组也是采用专用的服务器/工作站芯片组,比方IntelE7520、ServerWorksGC-HE等等,不过像入门级的服务器主板,一般都采用高端的台式机芯片组(比如Intel875P芯片组) 4、服务器通常要扩展板卡(比如如网卡,SCSI卡等),因此我们通常都会发现服务器主板上会有较多的PCI、PCI-X、PCI—E插槽。 5、服务器主板同时承载了管理功能。一般都会在服务器主板上集成了各种传感器,用于检测服务器上的各种硬件设备,同时配合相应管理软件,可以远程检测服务器,从而使网络管理员对服务器系统进行及时有效的管理。 6、在内存支持方面。由于服务器要适应长时间,大流量的高速数据处理任务,因此其能支持高达十几GB甚至几十GB的内存容量,而且大多支持ECC内存以提高可靠性(ECC 内存是一种具有自动纠错功能的内存,由于其优越的性能使造价也相当高)。 7、存储设备接口方面。中高端服务器主板多采用SCSI接口、SATA接口而非IDE接口,并且支持RAID方式以提高数据处理能力和数据安全性。 8、在显示设备方面。服务器与工作站有很大不同,服务器对显示设备要求不高,一般多采用整合显卡的芯片组,例如在许多服务器芯片组中都整合有ATI的RAGEXL显示芯片,

差错控制编码

第九章差错控制编码 9.1引言 一、信源编码与信道编码 数字通信中,根据不同的目的,编码分为信源编码与信道编码二大类。 信源编码~ 提高数字信号的有效性,如,PCM编码,M 编码,图象数据压缩编码等。 信道编码~ 提高传输的可靠性,又称抗干扰编码,纠错编码。 由于数字通信传输过程中,受到干扰,乘性干扰引起的码间干扰,可用均衡办法解决。 加性干扰解决的办法有:选择调制解码,提高发射功率。 如果上述措施难以满足要求,则要考虑本章讨论的信道编码技术,对误码(可能或已经出现)进行差错控制。 从差错控制角度看:信道分三类:(信道编码技术) ①随机信道:由加性白噪声引起的误码,错码是随机的,错码间统计独立。 ②突发信道:错码成串,由脉冲噪声干扰引起。 ③混合信道:既存在随机错误,又存在突发错码,那一种都不能忽略不计的信道。 信道编码(差错控制编码)是使不带规律性的原始数字信号,带上规律性(或加强规律性,或规律性不强)的数字信号,信道译码器则利用这些规律性来鉴别是否发生错误,或进而纠错。 需要说明的是信道编码是用增加数码,增加冗余来提高抗干扰能力。二:差错控制的工作方式 (1) 检错重发 (2) 前向纠错,不要反向信道 (3) 反馈校验法,双向信道 这三种差错控制的工作方式见下图所示: 检错重发 前向纠错 反馈校验法 检错误 判决信号 纠错码 信息信号 发 发 收 信息信号 152

153 9.2 纠错编码的基本原理 举例说明纠错编码的基本原理。 用三位二进制编码表示8种不同天气。 ???????? ?????雹 雾霜雪雨阴云 晴1 11 011101001 110010100000???→?种 许使用种中只准 48码组许用码组,其它为禁用雨阴云晴 0 11101110000 ??? ? ??? 许用码组中,只要错一位(不管哪位错),就是禁用码组,故这种编码能 发现任何一位出错,但不能发现的二位出错,二位出错后又产生许用码。 上述这种编码只能检测错误,不能纠正错误。 因为晴雨阴错一位,都变成1 0 0。 要想纠错,可以把8种组合(3位编码)中,只取2种为许用码,其它6种为禁用码。 例如: 0 0 0 晴 1 1 1 雨 这时,接收端能检测两个以下的错误,或者能纠正一个错码。 例:收到禁用码组1 0 0时,如认为只有一位错,则可判断此错码发生在第1位,从而纠正为0 0 0(晴),因为1 1 1(雨)发生任何一个错误都不会变成1 0 0。 若上述接收码组种的错码数认为不超过二个,则存在两种可能性: 位错) (位错)(21111000/变成(1 1 1)或(1 0 0), 因为只能检出错误,但不能纠正。 一:分组码,码重,码距 (见樊书P282 表9-1) 将码组分段:分成信息位段和监督位段,称为分组码,记为(n, k ) n ~ 编码组的总位数,简称码长(码组的长度) k ~ 每组二进制信息码元数目,(信息位段) r k n =- ~ 监督码元数目,(监督位段)(见樊书P282,图9-2) 一组码共计8种

域服务器管理

要想让服务器按需运行,就需要对其进行正确管理与维护。作为网络管理员,在与服务器长时间亲密“接触”之后,或多或少地会积累一些服务器管理方面的经验;在这些经验的指导下,服务器的管理效率的确能够在一定程度上得到提高。可是,这些管理经验也不是万能的,如果我们片面地依赖它们的话,反而会在日后的管理维护中受到框框限制;为此,面对一些特殊的管理需求,我们有时需要另僻蹊径,跳出之前管理服务器的各种框框,只有这样才能享受异想不到的管理效果! 1、删除主机名无须到现场 在局域网域环境中,当普通计算机第一次进入指定的Windows Server 2000 系统域后,该计算机的主机名称就会被域控制器自动保存在对应的活动目录中 了,那样的话局域网中的其他计算机就能及时看到新登录域目标计算机中的共享 信息了。虽然域控制器的这一智能存储操作会给大家带来不小的方便与快捷,但 是在某些时候该智能功能也会给大家带来烦恼;比方说,要是局域网中的某一计 算机系统由于意外原因发生崩溃,在对它重装系统并设置了相同的主机名称之 后,我们发现该计算机不能使用原来的主机名称登录域控制器了,这是什么原因 呢,我们是否需要换名进行域控制器登录操作呢? 其实,重装系统的计算机之所以不能使用之前的主机名称登录局域网域控制 器,是因为域控制器系统的活动目录中已经有了该主机名称的记录,只有想办法 将活动目录中对应的主机名称记录删除掉,那么重装系统的计算机才能继续使用 原来的主机名称正确登陆域控制器。一般来说,我们只要在域控制器现场以系统 管理员帐号登录服务器系统,之后进入活动目录窗口,找到之前生成的主机名称 记录,然后将它从域控制器中删除掉,就能解决重装系统的计算机不能以原来主 机名称登录局域网域控制器的故障;不过,要是我们无法赶到域控制器服务器现 场,是否能在本地计算机通过远程控制方式进入域控制器系统,并将其中的旧主 机名记录删除掉呢?答案是肯定的,我们只要按照如下步骤进行操作就可以了: 为了能够通过远程控制方式来管理域控制器服务器中的活动目录,我们首先需要在服务器系统中做一些准备工作。先以特权帐号登录进局域网域控制器系统,在该系统中执行网上搜索操作,将Windows Server 2000系统的SP4补丁包下载到本地服务器硬盘中,之后通过专业的解压缩程序将SP4补丁包解压到系统中的一个临时文件夹中;再打开对应系统的资源管理器窗口,从中找到临时文件夹并用鼠标右键单击该文件夹图标,从弹出的快捷菜单中选择“共享”命令,在其后界面中将SP4的解压文件夹设置为共享状态。 完成上面的准备工作后,我们可以在局域网的任意一台能够访问域控制器的计算机系统中,双击桌面上的“网上邻居”图标,进入对应的“网上邻居”窗口,从中找出域控制器服务器的主机名称,再用鼠标双击该主机名称,之后在弹出的身

樊昌信《通信原理》(第6版)-第11章 差错控制编码【圣才出品】

第11章 差错控制编码 11.1 本章要点详解 本章要点 ■概述 ■纠错编码的基本原理 ■纠错编码的性能 ■简单的实用编码 ■线性分组码 ■循环码 ■卷积码 ■Turbo码 ■低密度奇偶校验码 ■网络编码调制 重难点导学

一、概述 1.分类 从差错控制角度看,按加性干扰引起的错码分布规律的不同,信道可分为三类:随机信道、突发信道和混合信道。 根据差错控制方式的不同,可分为四类:检错重发法(ARQ)、前向纠错法(FEe)、反馈检验法和检错删除。 2.自动要求重发系统(ARQ) (1)停止等待ARQ系统 数据按分组发送。每发送一组数据后发送端等待接收端的确认(ACK)答复,然后再发送下一组数据。 系统是工作在半双工状态,时间没有得到充分利用,传输效率较低 (2)拉后ARQ系统 发送端连续发送数据组,接收端对于每个接收到的数据组都发回确认(ACK)或否认(NAK)答复。

在这种系统中需要对发送的数据组和答复进行编号,以便识别。显然,这种系统需要双工信道。 (3)选择重发ARQ系统 它只重发出错的数据组,因此进一步提高了传输效率。 二、纠错编码的基本原理 在信息码元中按一定规则增加一些监督码元,并利用信息码元与监督码元间的关系来发现、纠正误码的方法。监督位越多,检(纠)错能力越强,但传输速率越高,要求带宽越大。 为每组信息码元附加若干监督码的编码称为分组码。分组码中,码组中“1”的数目称为码组的重量,简称码重;把两个码组中对应位置上数字不同的位数称为码组的距离,简称码距;某种编码中各个码组之间距离的最小值称为最小码距,记为d0。一种编码的最小码距的大小直接关系着这种编码的检错和纠错能力。关系如下: (1)为了检测e个错码,要求最小码距:d o≥e+1; (2)为了纠正t个错码,要求最小码距:d o≥2t+1;

服务器管理规范

服务器管理规范 Document number【980KGB-6898YT-769T8CB-246UT-18GG08】

服务器管理制度 v1.0 编写人: 审核人: 批准人: 修订记录:

目录

公司内部服务器的安全是关系到公司数据保密和安全的一件大事,是保证各个业务系统正常工作的前提条件,因此必须进行科学、有效地管理。为了保证网络系统安全、高效运行,结合现有网络结构情况,特制定如下制度,请遵照执行: 服务器的管理和维护 1.维护目标是保证中心机房设备与信息的安全,保障机房具有良好的运行环境和工作环境。 2.安排专人负责服务器的日常操作维护工作,其它人不得私自操作服务器;如果确实需要操作服务器,应征得管理人员许可,并报部门主管同意后方可进行。 3.服务器必须建立完整的技术文档和维护方案。 4.服务器必须定期进行双机热备份。 5.每次更新服务器网站程序前,必须把相关内容备份到移动硬盘中,再进行操作,防止造成不可挽回的损失。 6.服务器管理员应每周对服务器及外围设备进行1次例行检查和维护。 7.如发现服务器故障应及时向部门主管报告,并负责计算机及外设的日常维护与排除故障,在遇到电脑公司三包范围内的故障时,应及时催促电脑公司上门或将机器送至供应商处维修。 机房安全管理制度 1.机房应防尘、防静电,保持清洁、整齐,设备无尘、排列正规、工具就位、资料齐全。

2.机房门内外、通道、设备前后和窗口附近,均不得堆放物品和杂物,做到无垃圾、无污水,以免妨碍通行和工作。 3.机房内严禁烟火,严禁存放和使用易燃易爆物品,严禁使用大功率电器、严禁从事危险性高的工作。如需施工,必须取得领导、消防、安保等相关部门的许可方可施工。 4.外来人员进入机房应严格遵照机房进出管理制度规定,填写人员进出机房登记表,在相关部门及领导核准后,在值班人员陪同下进出,机房进出应换穿拖鞋或鞋套。 5.进入机房人员服装必须整洁,保持机房设备和环境清洁。外来人员不得随意进行拍照,严禁将水及食物带入机房。 6.进入机房人员只能在授权区域与其工作内容相关的设备上工作,不得随意进入和触动未经授权以外的区域及设备。 7.任何设备出入机房,经办人必须填写设备出入机房登记表,经相关部门及领导批准后方可进入或搬出。 云服务器管理制度 为了加强公司云服务器的安全管理工作,保障信息系统安全、稳定运行,充分发挥系统效用,特制定本管理制度。本制度规定了公司云服务器维护管理和故障处理办法。适用于公司云服务器日常管理工作。 系统管理员负责服务器的日常操作维护,登录权限的管理。 具体内容如下: 1用户管理

服务器管理器 使用方法

服务器管理器使用方法 创建房间: 点击创建房间,打开窗口中选择你要创建的游戏DLL. 打开后进入 第一步.服务配置界面 从上至下填写内容. 1.常规配置-房间标识.这里填写只查看下面组件属性中的类型标识.他们必需一至 2.常规配置-桌子数目.这里填写你在这房间的桌子数.程序会为你计算出这房间最大进入人 数.基数为100.最多请不要超过150张桌子每个房间 3.常规配置-游戏类型.这里除了金币类游戏外基本要选择只有点值类型.金币类和点值类, 前者是连接数据库计算金币,后者计算积分. 4.类型标识.站点标识.房间人数这三项不会人手填写. 5.房间名子.这是服务器对应客户端标识,如没有特别需要不要改动 第二.网络配置 1.网络配置-监听端口.这里填写开放端口. 2.网络配置-服务器地址.这里填写游戏服务器连接服务器地址. 第三.数据库配置: 1.数据库配置-数据库名子.填写对应的游戏数据库名子(注:分大少写).默认不一定正确,请 手动填写. 2.数据库配置-数据库地址.填写对应的数据库IP.现在用的是本地IP(注:127.0.0.1). 第四.组件属性: 为方便管理和维护.这些都是在写游戏服务器中注入代码的,不能在管理器中改动. 第二步:保存配置 每次新创建房间都需要保存提供下次打开使用.点击保存后写上游戏管理脚本名称.

第三步:启动服务 更换服务文件或维护前停止服务,重新上线前请启动服务. 以上三步,是每次新建游戏服务器一定要进行的.下面是简略说明还末提过的功能. 停止服务 关服务器前必需点击.它会断开于中心服务器和数据库连接. 打开房间 当已经有游戏管理器脚本后,双击管理器.用打开房间,点击你要打开的游戏就可直接启动服务器. 配置房间 当你需要改动已经填写好的配置后或重写已经启动的游戏服务器.只有按停止服务器后,再点击配置房间进行修改,最后要点击保存更新你改动的内容. 系统配置 信息数据库配置: 信息数据库配置-数据库地址.填写这游戏管理器读取的数据库IP. 信息数据库配置-数据库端口.现用1433为端口,也是游戏服务器读取数据库端口. 信息数据库配置-数据库用户.因为本程序可以在A服务器读B数据库同样正常运行,这里需要填写你要读取数据库用户是否正确. 信息数据库配置-数据库密码.填写正确数据库密码. 信息数据库配置-数据库名字.这里是默认.读取这里填写的库. 其它配置 中心服务器:因为可以多开中心服务器进行数据压力分流功能(注:最好不要在同一服务器上开多于一个中心服务器,这样将得不到分流作用),可以在不同服务器上安装中心服务器.这里填写你需要的安装在中心服务器IP. 注意:同一游戏开多于一个以上房间只需要,房间标识和监听端口新开一个就可以完成. 每次新建游戏服务器,需要重启中心服务器才会获取新建服务器信息.

服务器的维护和管理

服务器的维护和管理 *服务器的定义 *服务器的设计思想 *服务器的分类 *服务器的结构 *服务器的维护 *服务器的常见问题 一、服务器的定义: 在网络环境中的一台终端,负责侦听网络上客户端的服务请求并提供响应的服务。 服务器定义的两种含义 1、服务器是生存在网络计算环境中的 2、服务器向网络的其他计算机提供服务。 服务器必须具有承担服务并保障服务质量的能力 服务器与PC的区别:PC是个人使用,而服务器要为他人提供服务 二、服务器的设计思想 1、可靠性可用性可扩展性易用性可管理性 稳定安全高性能可升级易于提供服务管理方便 2、服务器与PC的区别: A.生产的工业标准不同服务器要求超长时间工作对待机时间电源功率散热和电子器件的要求都比较高 B.定位不同 核心应用专业应用成本不菲 C.安全等级不同 实现主要部件双冗余,硬盘热插拔技术多种安全策略 三、服务器的分类 1.按架构分 塔式机架式刀片 2.按处理性能 单路双路多路服务器

四、服务器的结构组成: 包括处理器内存硬盘备份策略网络接口供电 1、处理器分类: 2、硬盘分类:SCSI SAS SA TA 4、常用双机热备和互备介绍 五、服务器日常需要注意的问题: 1.开关机次序服务器-存储–切换器 2. 日常维护:A.硬件保持恒温恒湿防静电防雷除尘 B.空间释放杀毒日志管理 六、服务器日常维护的九个关键点 服务器的应用已经普及,但对于服务器的养护大家可能或多或少的知道,在此跟大家分享一下服务器维护的几个关系,一是希望给大家作一个基础的参考,二是企盼能够引起大家对于服务器养护的意识。 1、电力控制 一部服务器虽然比不上电磁炉的凶猛,但相对普通PC机的柔弱,它还是一个重量级的用电大户的。 服务器硬件应用最基本的要点的就是要实现运行的稳定性与持续性,而要保持硬件系统的运行稳定,电力稳定是基础。这样,我们在布置机房内部的电力系统时,除了服务器机房市电的足够供应外,还要配备能够应付突发停电事故的现象。 假定一个机房放置了100部平均额定功率为500瓦的服务器,那么配备一部安置96块UPS专用高规格电池的大型UPS配电柜,基本可以保障市电停止后,机器照常运转8小时(理想状态,实际应用中是6.5小时左右)。

差错控制编码

2.差错控制编码 2.1. 引言 什么是差错控制编码(纠错编码、信道编码)? 为什么要引入差错控制编码? 差错控制编码的3种方式? 本章主要讲述:前向纠错编码(FEC)、常用的简单编码、线性分组码(汉明码、循环码)、简单介绍RS码*、BCH码*、FIRE码*、交织码,卷积码极其译码、TCM编码*。 一、什么是差错控制编码及为什么引入差错控制编码? 在实际信道上传输数字信号时,由于信道传输特性不理想及加性噪声的影响,接收 端所收到的数字信号不可避免地会发生错误。为了在已知信噪比情况下达到一定的 误比特率指标,首先应该合理设计基带信号,选择调制解调方式,采用时域、频域 均衡,使误比特率尽可能降低。但若误比特率仍不能满足要求,则必须采用信道编 码(即差错控制编码),将误比特率进一步降低,以满足系统指标要求。 随着差错控制编码理论的完善和数字电路技术的发展,信道编码已经成功地应用于 各种通信系统中,并且在计算机、磁记录与存储中也得到日益广泛的应用。 差错控制编码的基本思路:在发送端将被传输的信息附上一些监督码元,这些多余 的码元与信息码元之间以某种确定的规则相互关联(约束)。接收端按照既定的规 则校验信息码元与监督码元之间的关系,一旦传输发生差错,则信息码元与监督码 元的关系就受到破坏,从而接收端可以发现错误乃至纠正错误。 研究各种编码和译码方法是差错控制编码所要解决的问题。 二、差错控制的三种方式 1、检错重发(ARQ) 检错重发:在接收端根据编码规则进行检查,如果发现规则被破坏,则通过反向 信道要求发送端重新发送,直到接收端检查无误为止。 ARQ系统具有各种不同的重发机制:如可以停发等候重发、X.25协议的滑动窗 口选择重发等。 ARQ系统需要反馈信道,效率较低,但是能达到很好的性能。 2、前向纠错 前向纠错(FEC):发送端发送能纠正错误的编码,在接收端根据接收到的码和 编码规则,能自动纠正传输中的错误。 不需要反馈信道,实时性好,但是随着纠错能力的提高,编译码设备复杂。

第七章 差错控制编码 习题解答

8-1 某码字的集合为 00000000 1000111 0101011 0011101 1101100 1011010 0110110 1110001 求:(1)该码字集合的最小汉明距离;(2)根据最小汉明距离确定其检错和纠错能力。 解: (1)通过两两比较每个码字,可知该码字集的最小汉明距离为4; (2)因为检错能力与最小码距的关系为:1min +=e d ,所以检错能力为 3141min =-=-=d e 又因为纠错能力与最小码距的关系为:12min +=t d ,所以纠错能力为 5.12 1 421min =-=-= d t 取整后可得,纠错能力为1=t 。 8-2 已知二进制对称信道的差错率为2 10-=P 。(1)(5,1)重复码通过此信道传输,不可纠正错误的出现概率是多少?(2)(4,3)偶校验码通过此信道传输,不可检出错误的出现概率是多少? 解: (1)当(5,1)重复码发生3个或3个以上的错误时不可纠正,此时不可纠正的错误出现的概率为 ( )()()60 5 551 4452 3351085.9111-?≈-+-+-=P P C P P C P P C P e (2)当(4,3)偶校验码发生偶数个错误时这些错误不可检出,这些错误出现的概率 为 ( )()40 4 442 2241088.511-?≈-+-=P P C P P C P e 8-3 等重码是一种所有码字具有相同汉明重量的码,请分析等重码是否线性码? 解: 因为该码字集中所有的码字均有相同的码重,因此全零码字不包括在内,而线性码在输入信息位均为零时,输出也全为零,因此一定包含全零码。因此等重码不是线性码。 8-4 对于一个码长为15,可纠正2个随机错误的线性分组码,需要多少个不同的校正子?至少需要多少位监督码元? 解:对于一个码长为15的线性码,1个及2个随机错误的图样数为 120215115=+C C

Windows服务器配置与管理

连云港职业技术学院 信息工程学院《Windows服务器配置与管理》 大作业文档 题目:终端服务的管理与配置 姓名: 学号: 29号 专业:计算机网络技术 导师: 连云港职业技术学院信息工程学院 2010 年12 月

摘要 客户端通过终端服务客户端软件连接到终端服务器,在客户端的显示器上将显示出终端服务器使用的操作系统的界面。客户端软件讲客户鼠标和键盘的操作传送给服务器,然后将服务器显示的界面传送给客户端。对客户端而言,就像操作本地计算机一样。 Windows server 2003终端服务器可用来管理每个客户远程登录的资源,它提供了一个基于远程桌面协议的服务,使windows server 2003成为真正的多会话环境操作系统,并让用户能使用服务器上的各种合法资源。也可以让使用配置较低计算机的用户,通过终端服务使用服务器上最新的操作系统或者软件。 【关键字】终端服务器远程桌面远程协助配置

目录 摘要 (2) 第1章引言 (4) 第2章系统实现 (5) 2.1 安装终端服务器 (5) 2.2 windows XP的设置 (11) 2.3 终端服务器的连接配置 (15) 2.4 配置和使用“远程桌面” (20) 2.5 配置远程协助 (25) 2.6使用基于HTTP协议的终端服务器 (32) 2.6.1远程管理(html) (32) 2.6.2远程桌面web连接 (34) 第3章总结 (38) 参考文献 (39)

第1章引言 Windows server 2003操作系统提供了可用于从远程位置管理服务器的工具。这些工具包括“远程桌面”管理单元、终端服务器、远程协助、Telnet服务等远程管理工具。了解每种工具的优点和安全性需要后,就可以为远程管理和管理任务选择最合适的工具了。 终端服务器是通过网路服务器来提供一种有效和可靠的方法,分发基于windows的程序。它通过网络处理从客户端远程桌面传递的命令,运行后将结果传回远程桌面。通过终端服务器,可允许多个用户同时访问运行windows server 2003家族操作系统之一的服务器上的桌面。可以运行程序、保存文件和使用网络资源,就像坐在那台计算机前一样。 远程桌面是安装在网络中的客户端上的一种瘦客户端软件,它授权远程访问运行windows server 2003家族操作之一的任何计算机桌面,而并不对管理员下达的指令进行任何处理。允许用户实际通过网络中的任何计算机管理服务器——甚至是Microsoft Windows Server 2003服务器。 使用终端服务的优点是:将windows server 2003家族操作系统更快的引入桌面;充分利用已有的硬件;可以使用终端服务器集中部署程序;使用终端服务器远程桌面。 Windows server 2003终端服务新增功能:程序的集中部署;对应用程序的远程访问;单应用程序访问;终端服务管理器;远程控制;音频重定向;组策略集成;分辨率和颜色增强功能。

第9章 差错控制编码习题解答

第9章 差错控制编码习题解答 9-1 (1) 写出),(k n 循环码的码多项式的一般表达式; (2) 已知)3,7(循环码的生成多项式为1)(24+++=x x x x g ,若)(x m 分别为2x 和1, 求循环码的码字。 解: : ,1)()()(:,,)(1)(:,4,3,)3,7()2()(),()1(36 242 24012211过程如下的余式为得根据编码规则若信息码生成多项式循环码式为系统码码字的一般表达++÷===+++===++++=----x x x g x m x x x x x m x x x m x x x x g r k a x a x a x a x A k n r r n n n n x x x x x x x 1001011 1 1011 11 1 10123456233242342 3466 24=++++++++++++++++a a a a a a a x x x x x x x x x x x x 最后得系统码码字为对应码为得余多项式为 x x x x x x 0010111 1 0111 111 1012345622244 24=++++++++++a a a a a a a x x x x x x x 最后得系统码码字为对应码为得余多项式: ,1)()()(:,1)(24 过程如下的余式为则有若信息码++÷==x x x g x m x m x x m r r 9-2 (5,1)重复码若用于检错,能检测几位错?若用于纠错,能纠正几位错?,若同时用 于检错与纠错,情况又如何?

. 31,2,4,5)1,5(:1,)(,)2(1 2,)2(1,)1(0000位错位错和检并同时能纠位错纠位错故能检重复码由上述公式得则要求随机错误个同时检测个纠则要求个随机错误纠则要求个随机错误检测=++≥>+≥+≥d e t d t e e t t d t e d e 9-3 已知八个码字分别为000000、001110、010101、011011、100011、101101、110110、 111000,试求其最小码距0d 。 解: . 3,1,1,0:.,,,.:. ,,:111000 110110, 101101, 100011,011011, ,010101 ,001110 ,00000080=d 故得的个数为最小汉明距离该码中少的码的个数为最找出码外除全具体方法是是类似的性这和实数运算具有封闭属于该码组中的一个码仍然算的结果码组中任意两组异或运闭性是指所谓封性来判断利用码组是否具有封闭方法二码组大时较麻烦这种方法在可得最小汉明距离两两比较方法一个码组为 已知 9-4 上题所给的码组若用于检错,能检测几位错?用于纠错,能纠正几位错?,若同时用 于检错与纠错,情况又如何? 解: ). 3?(,2,1:1 ,)(,)3(12,)2(1,)1(: .30000条不满足第为什么同时用于纠错和检错但不能位错检位错能纠由上述公式得要求则随机错误个同时检测个纠则要求个随机错误纠则要求个随机错误检测利用公式得++≥>+≥+≥=e t d t e e t t d t e d e d 9-5 汉明码(7,4)循环码的1)(3++=x x x g ,若输入信息组0111,试设计该码的编码电路, 并求出对应的输出码字。

Windows Server 2012服务器管理器详解

Windows Server 2012服务器管理器详解 作为技术人员来说我们对Windows Server的关注始终是在系统本身包括能不能够更好管理好服务器或者在功能方面更加强大操作上更加简单在Windows Server 中服务器管理器发生了非常大的变化在诸多方面做了非常大的改进 首先是Windows Server 的启动界面相比Windows Server R感觉更加的专业和简洁如下启动完成后可以看到全新的服务器管理器的完整界面 相对于传统的界面来说Windows Server 的服务器管理器更容易让使用者将焦点放在服务器需要完成的任务上这样的设计并不是空穴来风而是从微软设计系统的观念上发生了变化 在Windows Server 中存在两种不同的理念 沉浸式 Windows Server具有旧版本系统的所有功能但这些功能似乎并不会直接展示在技术员面前而是当技术员需要它的时候出现并且迅速的完成任务使得需要技术员操作的地方更加简单快捷 更加睿智 Windows Server 相比旧的系统更加的智能并且技术人员在使用的时候可以非常明显的感觉到Windows Server 真正需要“操心”的地方变得更少比如在完成Server“”安装的时候会自动启动服务器管理器面板的“仪表盘”面板并提供欢迎界面(包括快速开始新功能学习三个模块) 在上面的图中已经可以看到Windows Server 的服务器管理器的整个界面那现在再来对比一下以前的Windows Server R的服务器管理器 Windows Server R中的服务器管理器几乎没有顶部导航栏这个概念并且从上图右上角的工具栏可以看出在旧版本是完全没有任何内容的即使是这样的情况在左侧导航栏收缩的情况下整个界面仍然显示了如此多的内容 其实这些内容很多都是不常用或者说技术员不太关心在无关紧要时显示出来反而会造成混乱影响就拿右侧的日志来举例虽然日志对系统很重要但也不并不是所有日志都需要显示在管理员的眼帘比如服务器运行正常的时候完全没必要去注意系统自动完成的操作记录而仅当系统出现了问题错误以及警告时所记录的日志才是真正有价值的 Windows Server 的顶部显得非常简洁但内容非常丰富顶部右侧的工具栏分别有管理工具查看以及帮助可以完成旧版本服务器管理器中的绝大多数任务 管理这里可以添加删除角色和功能添加服务器及创建服务器组 工具这里的东西非常多不知道各位朋友是否觉得眼熟这非常类似旧版本Server里的“管理工具”虽然没有了图标但显得更加的简洁相信熟练使用Windows Server的技术员对“管理工具”中的文字更加熟悉而不是小图标 查看在查看里我们可以调整整个面板的显示大小可以更加方便的在不同设备上切换比如平板和高分辨率的显示器之间 帮助这里主要显示服务器管理器的帮助信息比如帮助文件https://www.wendangku.net/doc/cb683226.html, TechCenterTechNet Forum等 在来看下四个菜单栏左边的小旗子这就有点类似于“操作中心”的提示在正常情况下

服务器管理规范

服务器维护管理规范 公司内部网络服务器的安全是关系到公司数据保密和安全的一件大事,是保证各个业务系统正常工作的前提条件,因此必须进行科学、有效地管理。为了保证网络系统安全、高效运行,结合现有网络结构情况,特制定如下制度,请遵照执行: 1.服务器的管理和维护 ●维护目标是保证中心机房设备与信息的安全,保障机房具有良好的运行环境和工作 环境。 ●安排专人负责服务器的日常操作维护工作,其它人不得私自操作服务器;如果确实 需要操作服务器,应征得管理人员许可,并报部门主管同意后方可进行。 ●服务器必须建立完整的技术文档和维护方案。 ●服务器必须定期进行双机热备份。 ●每次更新服务器网站程序前,必须把相关内容备份到移动硬盘中,再进行操作,防 止造成不可挽回的损失。 ●服务器管理员应每周对服务器及外围设备进行1次例行检查和维护。 ●如发现服务器故障应及时向部门主管报告,并负责计算机及外设的日常维护与排除 故障,在遇到电脑公司三包范围内的故障时,应及时催促电脑公司上门或将机器送 至供应商处维修。 2.环境要求 ●服务器机房内必须保持整洁,不得放置无关的设备、物品。 ●每日检查服务器机房的温度和湿度,一般情况下必须保持恒温、恒湿。 ●服务器机房不能放置食品和水,不得在服务器机房内就餐。 ●一般情况下,无关人员不得进入服务器机房。 3.软件环境 为了保证服务器的最大优化,除了安装解压缩、杀毒软件等必要的应用软件外,一般不安装其他非必要的软件,包括OFFICE等,平时最好不设置壁纸、屏幕保护等。严禁安装游戏、聊天工具。 4.杀毒和系统安全 ●需要拷贝到服务器上的程序和数据,必须经过检测确认无病毒后方可进行传入。

服务器管理文档

1.为科学有效地管理机房服务器,促进网络系统安全的应用、高效运行,特制定本规章制 度,请遵照执行。 一、服务器管理制度 1.1服务器是公司的关键设备,须放置在机房内,不得自行配置或更换,更不能挪作它 用。 1.2服务器机房要保持清洁、卫生,并由专人负责管理和维护(包括温度、湿度、电力系 统、网络设备等),除系统维护时间外,要保障服务器24小时正常运行。 1.3不得在服务器上使用带有病毒和木马的软件、光盘和可移动存储设备,使用上述设 备前一定要先做好病毒检测;不得利用服务器从事工作以外的事情,无工作需要不得擅自拆卸服务器零部件,严禁更换服务器配套设备。不得擅自删除、移动、更改服务器数据;不得故意破坏服务器系统;不得擅自修改服务器系统时间。 1.4服务器系统必须及时升级安装安全补丁,弥补系统漏洞;必须为服务器系统做好病 毒及木马的实时监测,及时升级病毒库。 1.5管理员对超级账户口令应严格保密、定期修改,以保证系统安全,防止对系统的非 法入侵。同时可对服务器上的管理权限、进行更新设置,防止恶意破译。 1.6建立服务器登记制度,需要在服务器架设项目的员工要先通知项目经理,项目经理 审批后以书面的形式通知网络管理员对架设的项目、安装过程和结果等做好详细登记。 1.7无关人员未经管理人员批准严禁进入机房。严禁易燃易爆和强磁物品及其它与机房 工作无关的物品进入机房。 1.8所有人员不得随意下载软件,避免占用带宽过大。如需下载软件提前通知网络管理 员,由网络管理员统一下载。 1.9制定数据管理制度。对数据实施严格的安全与保密管理,防止系统数据的非法生成、 变更、泄露、丢失及破坏。管理人员应在数据库的系统认证、系统授权、系统完整性、补丁和修正程序方面实时修改。 1.10及时处理服务器软硬软件系统运行中出现的各种错误,对所有工作中出现故障需重 启时,要提前通知人员做好备份保存 二、计算机病毒防范制度 2.1所有人员应有较强的病毒防范意识,定期进行病毒检测,发现病毒立即处理并通知 网管。 2.2采用防病毒软件并及时更新软件版本。 2.3监控网络上的数据流,从中检测出攻击的行为并给予响应和处理。 2.4经远程通信传送的程序或数据,必须经过检测确认无病毒后方可使用。 2.5电脑出现病毒,操作人员不能杀除的,须及时报告网管处理。

服务器配置与管理

《服务器配置与管理》课程标准 一、概述 (一)课程性质 本课程为计算机网络技术专业的专业必修课,是一门实践性很强的理论实践一体化课程。 本课程以计算机应用基础作为前期基础课程,通过本课程的学习,让学生掌握计算机网络的基本理论,让学生掌握构建局域网的能力,并为学生将来进一步学习网络知识打下基础。同时使学生养成对常用的计算机网 工作“连接网络之联网设备”“认识计算机网络之网络协议”“连接网络之网络寻址”,最后,学习“组建小型交换网络-配置交换机”“连接互联网之配置路由器”,由浅到深,一步步学习组建局域网及管理。

,培 总结计算机网络的概念和主要组成部分;会使用计算机网络所能提供的各种服务(www/mail/ftp等);简单描述各种不同的网络环境。 2.进行网络的物理连接 按需要选择网络传输介质,并制作、测试网络线,把计算机与网络设备连接起来,并能根据设备面板的批示灯,确定网络的工作状态。能利用无线设备组建无线网络。 3.网络逻辑连接 根据小型网络的特点,规划网络的IP地址,并按照子网隔离的要求,

进行子网划分。知道MAC地址在局域网通信中的作用,并能实现MAC地址与IP地址的绑定。 4.交换机的配置 利用交换机连接网络,并对交换机进行基本的配置、测试,初步掌握IOS命令的使用及交换机的工作过程,为构建交换式网络打下基础。 5.互联网连接 根据小型网络的特点,选择宽带路由器,并对宽带路由器进行基本配置,实现互联网的接入,对宽带路由器进行高级配置,实现互联网接入的

(一)教学建议 由于本课程的主要教学内容涉及家庭及办公网络调研,网络的组建连

差错控制编码

差错控制编码的设计与仿真 学生:陈琪,长江大学文理学院 指导教师:黄金平,长江大学电信学院 一、题目来源 来源于通信过程中所遇到的实际的问题 二、研究目的和意义 通信系统必须具备发现(即检测)差错的能力,并采取措施纠正之,使差错控制在所能允许的尽可能小的范围内,这就是差错控制过程,也是数据链路层的主要功能之一。 接收方通过对差错编码(奇偶校验码或CRC码)的检查,可以判定一帧在传输过程中是否发生了差错。一旦发现差错,一般可以采用反馈重发的方法来纠正。这就要求接受方收完一帧后,向发送方反柜一个接收是否正确的信息,使发送方据此做出是否需要重新发送的决定。发送方仅当收到接收方以正确接收的反馈信号后才能认为该帧已经正确发送完毕,否则需要重发直至正确为止。 物理信道的突发噪声可能完全“淹没”一帧,即使得整个数据帧或反馈信息帧丢失,这将导致发送方永远收不到接受方发来的信息,从而使传输过程停滞。为了避免出现这种情况,通常引入计时器(Timer)来限定接收方发回方反柜消息的时间间隔,当发送方发送一帧的同时也启动计时器,若在限定时间间隔内未能收到接收方的反柜信息,即计时器超时(Timeout),则可认为传出的帧以出错或丢失,就要重新发送。由于同一帧数据可能被重复发送多次,就可能引起接收方多次收到同一帧并将其递交给网络层的危险。为了防止防止发生这种危险,可以采用对发送的帧编号的方法,即赋予每帧一个序号,从而使接收方能从该序号来区分是新发送来的帧还是已经接受但又重发来的帧,以此来确定要不要将接收到的帧递交给网络层。数据链路层通过使用计数器和序号来保证每帧最终都能被正确地递交给目标网络层一次。

使用Windows Server 2008服务器管理器配置角色操作系统专栏

概览: 角色和功能之间的差别 使用服务器管理器可以做些什么 使用向导 从命令行管理角色和功能 贯穿在 Windows Server 2008 中的主题之一就是“简约”。这并不意味着不必要地去除一些功能。相反,这是简化和澄清角色和工具的一种策略,以便于您只安装所需的内容,多余的一概不安装。服务器管理器 是Windows Server? 2008 中这一概念的重要组成部分。 它包含两方面的内容。首先是有关服务器角色和功能的最重要的概念,它们是 Window s Server 2008 的构建块。其次是“服务器管理器”工具本身。此工具不仅将取代 Window s Server 2003 中使用的多个工具,而且还在一个位置引入了多个功能,从而使得像您这样忙碌的管理员能够更快捷、更容易地完成更多工作。 角色和功能 如果您曾阅读过有关 Windows Server 2008 的文章,则很可能会遇到一些以前在 Win dows? 上下文中没有听说过的术语,例如“工作负荷”和“角色”等。首先我将解释这些术语对 IT 专业人员意味着什么。 在 Windows Server 2008 的开发周期伊始,我们花费了很多时间试图了解用户是如何使用我们的服务器产品的。(顺便说一句,这种努力目前仍在继续。)总的来说,我们发现人们部署我们的服务器一般都是做一些特定的事情。这听起来可能并不是很难理解,但是对于我们中的一些人而言,当了解到人们没有使所购买的服务器充分发挥功效时,一定会感到惊奇不已。更为重要的是,他们并不部署服务器来完成数量庞大的任务。相反,他们希望一个服务器只执行特定的任务。当然,也有一些例外情况,但是在大多数情况下,都是置备一个服务器来执行特定的功能。

服务器配置与管理

服务器配置与管理

《服务器配置与管理》课程标准 一、概述 (一)课程性质 本课程为计算机网络技术专业的专业必修课,是一门实践性很强的理论实践一体化课程。 本课程以计算机应用基础作为前期基础课程,通过本课程的学习,让学生掌握计算机网络的基本理论,让学生掌握构建局域网的能力,并为学生将来进一步学习网络知识打下基础。同时使学生养成对常用的计算机网络的关注兴趣,并能够把所学的知识应用到具体的应用情境中去发现、分析、解决问题。 (二)课程基本理念 课程立足于实际能力培养,对课程内容的选择标准作了根本性改革,打破以知识传授为主要特征的传统学科课程模式,转变为以工作任务为中心组织课程内容和课程教学,让学生在完成具体项目的过程中来构建相关理论知识,并发展职业能力。本课程确定了以网络系统设计和实施的一般步骤:用户网络需求分析、网络结构设计、网络物理连接、网络逻辑连接、设备配置等过程任务组织课程内容,首先避免了从概念、理论、定义入手的理论课程组织模式,而是从与学生生活紧密相关的家庭、办公室网络应用入手,展开网络连接及维护网络的工作任务型课程模式。课程内容突出对学生职业能力的训练,理论知识的选取紧紧围绕“组建小型网络”工作任务完成的需要来进行,同时又充分考虑了高等职业教育对理论知识学习的需要,注重对知识、技能和态度的要求。 (三)课程设计思路 本课程针对本校学生的特点,在项目及模块设计上,依据“组建小型局域网”工作任务的过程进行,课程本身就是一个完整的项目。本课程从最基本的的“初识计算机网络”“连接网络之传输介质”“无线网络”到“连接网络之联网设备”“认识计算机网络之网络协议”“连接网络之网络寻址”,最后,学习“组建小型交换网络-配置交换机”“连接互联网之配置路由器”,由浅到深,一步步学习组建局域网及管理。

服务器管理制度

. 服务器管理制度 v1.0

目录 一、服务器的管理和维护 (2) 二、机房安全管理制度 (2) 三、云服务器管理制度 (3) 四、网络安全管理制度 (5) 五、安全及保密管理制度 (6) 六、操作系统日常维护要求 (7) 七、软件环境 (14) 八、杀毒和系统安全 (14) 九、操作系统补丁 (14) 十、开关机和重启 (15) 十一、文件、磁盘检查 (16) 十二、日志检查 (16) 十三、故障管理 (16) 十四、保密制度 (17) 附1:服务器管理员职责 (17)

公司内部服务器的安全是关系到公司数据保密和安全的一件大事,是保证各个业务系统正常工作的前提条件,因此必须进行科学、有效地管理。为了保证网络系统安全、高效运行,结合现有网络结构情况,特制定如下制度,请遵照执行: 一、服务器的管理和维护 1.维护目标是保证中心机房设备与信息的安全,保障机房具有良好的运行环境和工作环境。 2.安排专人负责服务器的日常操作维护工作,其它人不得私自操作服务器;如果确实需要操作服务器,应征得管理人员许可,并报部门主管同意后方可进行。 3.服务器必须建立完整的技术文档和维护方案。 4.服务器必须定期进行双机热备份。 5.每次更新服务器网站程序前,必须把相关内容备份到移动硬盘中,再进行操作,防止造成不可挽回的损失。 6.服务器管理员应每周对服务器及外围设备进行1次例行检查和维护。 7.如发现服务器故障应及时向部门主管报告,并负责计算机及外设的日常维护与排除故障,在遇到电脑公司三包范围内的故障时,应及时催促电脑公司上门或将机器送至供应商处维修。 二、机房安全管理制度 1.机房应防尘、防静电,保持清洁、整齐,设备无尘、排列正规、工

相关文档
相关文档 最新文档