Oracle数据库代码指令简介

Posted 蜀云泉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle数据库代码指令简介相关的知识,希望对你有一定的参考价值。

 

这是oracle的课后作业,弄懂这些也差不多了吧,不懂的可以去看我的SQL sever数据库的博客那个写的详细。视频以后有时间录~ 

 

登录数据库

//方法一
sqlplus 用户名

//方法二
sqlplus [email protected]   as 用户名

 

 

第一章

 1.查看当前数据库控制文件的名称与路径

select name from v$controlfile;

2.查看表空间SYSTEM对应的数据文件信息

//dba_data_files是数据字典
select file_name,tablespace_name,autoextensible  from dba_data_files   where tablespace_name=SYSTEM;

3.查看当前数据库所有数据文件信息

select file#,name,checkpoint_change#

4.查看正在使用的日志文件组

select group#,status from v$log;

5.使用DBA_TABLES数据字典查询SCOTT用户所有表的信息

 

select table_name,tablespace_name,owner
from dba_tables
where owner=SCOTT;

6.通过DESC DAB_TAB_COLUMN命令了解用户表的字段信息结构

 

desc dba_tab_columns;

7.查询EMP表中的字段ID、字段名和表名信息

 

select *from scott.emp;

8.通过DBA_INDEXES数据字典了解EMP表中的索引信息

 

select *  from  dba_indexes  where table_name=EMP;

 

第二章

1.使用SPOOL命令将SQL Plus中的输出结果复制到result.txt文件中

//spool命令是执行语句的输出结果会存到一个文件里面,输完语句之后 /执行 ,最后可以spool off 关闭spool功能
spool result.txt
 select empno,ename,job,mgr,sal,deptno
 from scott.emp
 where sal<4000
/

2.scott用户,查询工资小于某金额的员工信息。该金额具体值由&salary决定

//这里用到&salary,下面我们会复制给它,算是变量吧,我们可以看到/执行之后让我们输入值了
select empno,ename,job,sal
from scott.emp
where sal<&salary

/
salary 的值:  4000

3.为ename列起别名“雇员姓名”并设置ename列显示宽度15字符

column ename heading ‘雇员姓名’ format A15
 /

4.为列sal起别名“薪水”,使该列居中并设置此列为货币格式

column sal heading ‘薪水’ justify center format $99,999.99;

 /

5.消除sal列的属性设置

column sal clear;

 

第三章

1.创建member表,两个列一个id一个name

create table member(
Id number (4),
name varchar(10)
);

2.为member表name添加非空约束

alter table member modify name not null;

3.删除member表中的非空约束

alter table member modify name null;

4.创建member2表(结构同member),为id列添加主键约束id_pk

 

create table member2
(id number(4),
name varchar(10) not null,
Constraint  id_pk  primary key (id));

 

5.删除member2表的主键约束id_pk

 

alter table member2 drop constraint id_pk;

6.删除member2表。重新创建member2表,为id列添加列级别主键约束(不命名)

create table member2 (
id number(4) primary key ,
name varchar(10) not null);

7.使用数据字典USER_CONSTRAINTS查询member2表主键名称。删除主键。

//先查看主键名
select constraint_name,constraint
From user_constraints
Where table_name=’MEMBER2’;
//看到主键名了,可以删了
alter table member2 drop 主键名;

8.为member表id列添加主键id_pk

alter table member add constraint id_pk primary key(id);

 

第四章

1.创建student表,设置claidFOREIGN KEY约束,引用class表中的claid

//这就是一个外键约束
     create table student (
     id number(4) primary key,
     name varchar2(10),
     claid number(3) references class(claid));

2.删除studentclaid列的外键约束

alter table student drop constraint 约束名;

3.为studentclaid列添加外键约束cla_fk,引用同前,并且指定外键约束的引用类型为CASCADE

alter table student 
Add constraintcla_fk foreign key (claid)
References class (claid) on delete cascade ;

4.查看student表中所有的约束信息

select constraint_name, constraint_type,deferred, deferrable,status
From user_constraints
Where table_name=’STUDENT’;

5.将mem表中的CHECK约束设置为禁止状态

ALTER TABLE mem MODIFY CONSTRAINT id_ck  DISABLE;

6.查看mem表约束状态

select constraint_name,constraint_type,status
 from user_constraints
 where table_name=MEM;

 

第五章

去下载这个事先写好的数据库代码,执行一下,把表创建好  http://pan.baidu.com/s/1o8eAku2

 

1.从scores表中查询出课程平均成绩低于课程最高平均值的课程编号和平均成绩

select cno,avg(sscore) from scores
group by cno
having avg(sscore)<(select max(avg(sscore) ) from scores group by cno);

2.从scores表中查询性别为“女”的学生成绩信息,包括学号、课程编号和分数列,并按成绩升序排列

select sno,cno,sscore from scores 
Where sno in ( select sno from student where ssex=’女’)
order by sscore;

3.查询大于课程编号为1102中任意一个成绩的成绩信息

Select sno ,cno, sscore from scores
Where sscore>any (select sscore from scores where cno=’1102’ )

4.查询大于课程编号1102中所有成绩的成绩信息

select sno ,cno ,sscore from scores where 
Sscore>all(select sscore feom scores where cno =’1102’ );

 

 

第六章

去下载这个事先写好的数据库代码,执行一下,把表创建好  http://pan.baidu.com/s/1gfimpmN

 

1.从SCORES表中查询非“JSP课程设计”课的成绩信息

//exists是返回值为真的情况下就执行
select * from SCORES where exists(select cno from course where course.cno=scores.cno and course.cname!=JSP课程设计);

2.将北京籍学生的分数下调5%

update scores set sscore=sscore*0.95 where sno in (select sno from student where sadrs=北京);

3.使用内连接从student表和class表中查询学生学号、姓名和班级名称

select s.sno,s.sname,cl.claname from student s inner join class cl on s.claid=cl.claid;

4.使用scores表和scgrade表,查询学号、成绩和相应等级

select sno,sscore,grade from scores s inner join scgrade sc on s.sscore between sc.loscore and sc.hiscore;

5.使用自然连接查询学生信息及所在的班级名称

select * from student natural join class;

6.使用student作为主表,连接scores表,查询出学生学号、姓名和课程编号,并按课程编号降序排列

select s.sno,s.sname,s.claid from student s left outer join scores sc on (s.sno=sc.sno) order by s.claid desc;

 

第七章

1.在EMP表中,查询工资最高的第6位到第10位的员工姓名和工资信息

select * from(select Rownum rn, ENAME,SAL from(select * from emp order by SAL desc)where Rownum<=10 )where rn>=6

2.student表中sadrs为北京、天津和南京的数据添加到new_student表中

create table new_student(
sno number(6),
sname varchar2(20) not null,
ssex varchar2(3),
sbirth date,
sadrs varchar2(7),
claid number(3),
constraint nsno_pk primary key(sno),
constraint ncla_fk foreign key(claid) references class(claid)
)

3.使用MERGE语句实现以student1为基准,对student2表以sno列作为关联更新sname

merge  into student2 s2
using student1 s1
on (s2.sno=s1.sno)
when matched then
    update set s2.sname=s1.sname;

4.将两表中sno列不相同的student1表的记录添加到student2表中

merge  into student2 s2
using student1 s1
on (s2.sno=s1.sno)
when matched then
    insert values(s1.sno,s1.sname,s1.ssex,s1.sbirth,s1.sadrs);

5.将student3表中性别为“女”的学生姓名更新到student4表,将student3表中籍贯为“北京”的学生信息插入到student4

merge  into student4 s4
using student3 s3
on (s3.sno=s4.sno)
when matched then
    update set s4.sname=s3.sname
    where s3.ssex=
where not matched then
    insert values(s3.sno,s3.sname,s3.ssex,s3.sbirth,s3.sadrs)
    where s3.sadrs=北京;

6.将member1表的数据添加到member2表中,而不检查数据是否已经存在

merge  into member2 m2
using member1 m1
on (1=0)
where not matched then
    insert values(m1.id,m1.name);
 

7.使用member1表作为源表来更新member2表的姓名,同时删除member2表中id大于2的数据

merge  into member2 m2
using member1 m1
on (m1.id=m2.id)
when matched then
    update set m2.name=m1.name
    delete where m2.id>2;

 

第八章

1.创建名称为orclspace的表空间,设置数据文件mydata01.dbf初始大小10M,每次自动增长2M,最大容量为30M

create tablespace orclspace
datafile C:\oracle\files\mydata01.dbf
size 10M
autoextend on next 2M
maxsize 30M

2.通过数据字典dba_tablespaces查看orclspace表空间的属性

select
tablespace_name, 
logging, 
allocation_type, 
extent_management, 
segment_space_management
FROM dba_tablespaces
WHERE tablespace_name=ORCLSPACE;

3.为orclspace表空间增加1个新的数据文件mydata02.dbf,大小10M,不自动扩展

alter tablespace orclspace
add datafile
C:\mydata02.dbf
size 10M
AUTOEXTEND OFF;

4.修改数据文件mydata02.dbf的大小为15M

alter database
datafile
C:\mydata02.dbf
resize 15M;

5.将数据文件的原名称与路径修改为新名称与路径

alter tablespace orclspace offline
alter tablespace orclspace
rename datafile C:\orclspace.dbf
to 
C:\oraclefile\myoraclespace.dbf;

6.创建tempspace临时表空间,设置临时数据文件mytemp01.dbf初始大小10MB,每次自动增长2MB,最大容量为20MB

CREATE  TEMPORARY  TABLESPACE  tempspace
TEMPFILE  C:\mytemp01.dbf
SIZE  10M
AUTOEXTEND  ON  NEXT 2M  MAXSIZE  20M;

7.设置系统默认临时表空间为tempspace。查询结果

ALTER DATABASE  DEFAULT  TEMPORARY  TABLESPACE TEMPSPACE;

8.删除临时表空间组tempgroup1。分别删除表空间my_temp_tbs01my_temp_tbs02及其数据文件

CREATE  TEMPORARY  TABLESPACE  tempspace1
TEMPFILE  C:\tempspace1.dbf  SIZE  10m
TABLESPACE GROUP  tempgroup1;

CREATE  TEMPORARY  TABLESPACE  tempspace2
TEMPFILE  C:\tempspace2.dbf  SIZE  10m
TABLESPACE GROUP  tempgroup1;

drop tablespace tempspace1 including contents and datafiles;
drop tablespace tempspace2 including contents and datafiles;

9.将数据库的还原表空间切换为undospace。查看结果

CREATE UNDO TABLESPACE undospace
DATAFILE  C:\undospace.dbf
SIZE  10M;
show parameter undo_tablespace;

 

第九章

1.使用IF-ELSE统计表emp中部门编号为30的员工人数

DECLARE
    v_count NUMBER(4);
BEGIN
    SELECT count(*) INTO v_count FROM emp
    WHERE deptno = 30;
    IF v_count > 0 THEN
        DBMS_OUTPUT.PUT_LINE(部门编号为30的员工人数:||v_count||);
    ELSE
        DBMS_OUTPUT.PUT_LINE(不存在部门编号为30的员工信息);
    END IF;
END;

2.使用CASE条件语句判断成绩61分所处的等级

DECLARE
  score BINARY_INTEGER := 61;
BEGIN
  CASE
  WHEN  score >= 90  THEN  DBMS_OUTPUT.PUT_LINE(优秀);
  WHEN  score >= 80  THEN  DBMS_OUTPUT.PUT_LINE(良好);
  WHEN  score >= 60  THEN  DBMS_OUTPUT.PUT_LINE(及格);
  ELSE  DBMS_OUTPUT.PUT_LINE(不及格);
  END CASE;
END;

3.使用FOR循环语句输出数值1~10

BEGIN
    FOR i IN 1 .. 10  
    LOOP
        DBMS_OUTPUT.PUT_LINE(i);
    END LOOP;
END;

4.使用非系统异常处理违反完整性约束条件的错误

DECLARE
  v_deptno dept.deptno%TYPE := &dept_no;
  e_deptno EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_deptno, -2292); 
BEGIN
  DELETE FROM dept WHERE deptno = v_deptno;
EXCEPTION
  WHEN e_deptno THEN
    DBMS_OUTPUT.PUT_LINE(违反数据完整性约束);
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(sqlcode||----||sqlerrm);
END;

5.编写程序,计算1+2+3+ +30的值。在求和的过程中,如果发现结果超出了100,则抛出异常,并停止求和

DECLARE
  result INTEGER := 0;
  out_of_range EXCEPTION;
  PRAGMA EXCEPTION_INIT(out_of_range,-20001);
BEGIN
  FOR i IN 1 .. 20  LOOP
    result := result + i;
    IF result > 100 THEN
      RAISE_APPLICATION_ERROR(-20001,当前的计算结果为||result||,已经超出范围!);
    END IF;
  END LOOP;
EXCEPTION
  WHEN out_of_range THEN
    DBMS_OUTPUT.PUT_LINE(错误代码||SQLCODE);
    DBMS_OUTPUT.PUT_LINE(错误信息||SQLERRM);
END;

 

第十章

1.创建嵌套表类型stu_perf_type,存储学生在校表现,用在学生表stu_tbstu_perf

CREATE TYPE stu_perf_type IS TABLE OF VARCHAR2(20);/
CREATE TABLE stu_tb (
stu_id  NUMBER(4),
stu_name  VARCHAR2(10),
stu_score  NUMBER(6,2),
stu_perf  stu_perf_type)
NESTED TABLE stu_perf   STORE  AS  s_p_tb;

2.查询stu_tb表中2号同学的在校表现数据

DECLARE
  s_tb stu_perf_type;
BEGIN
  SELECT stu_perf INTO s_tb FROM stu_tb
    WHERE stu_id = 2; 
  FOR i IN 1..s_tb.COUNT  LOOP 
     DBMS_OUTPUT.PUT_LINE(学生在校情况:||s_tb(i));
  END LOOP;
END;

3.修改表stu_tb中的stu_id1的在校表现数据

DECLARE
  s_tb stu_perf_type := stu_perf_type(WEB班, 表现一般, C#班, 表现优异);  
BEGIN
  UPDATE stu_tb SET stu_perf = s_tb
    WHERE stu_id = 1;
END;

4.使用嵌套循环输出stu_tb2表中所有同学的在校表现信息

DECLARE
  s_tb stu_cond_type; 
BEGIN
  SELECT stu_cond INTO s_tb FROM stu_tb2
    WHERE stu_id = 2; 
  DBMS_OUTPUT.PUT_LINE(学生2表现情况:);
  FOR i IN 1..s_tb.COUNT LOOP   
    DBMS_OUTPUT.PUT_LINE(s_tb(i));
  END LOOP;
END;

5.检索EMP表。使用LOOP循环语句遍历游标,输出指定部门编号(比如10)的员工信息(empno,ename,sal,deptno)。不用输出汉字,字母就可以

DECLARE
   CURSOR cursor_emp (dept_no NUMBER := 10) 
       IS SELECT * FROM emp WHERE deptno = dept_no;
   row_emp emp%ROWTYPE;
BEGIN
  OPEN cursor_emp(10);
  LOOP
    FETCH cursor_emp INTO row_emp; 
    EXIT WHEN cursor_emp%NOTFOUND; 
    DBMS_OUTPUT.PUT_LINE(当前检索第||cursor_emp%ROWCOUNT|| 行:员工号--||row_emp.empno|| ,姓名--|| row_emp.ename|| ,工资--|| row_emp.sal|| ,部门编号--|| row_emp.deptno);
  END LOOP;
  CLOSE cursor_emp;
END;

6.使用FOR循环,实现上一题功能,输出20号部门的员工信息。体会两种循环使用的异同

DECLARE
    CURSOR cursor_emp(dept_no NUMBER := 10)
    IS SELECT * FROM emp WHERE deptno = dept_no;
BEGIN
    FOR row_emp IN cursor_emp LOOP
        DBMS_OUTPUT.PUT_LINE(员工号:||row_emp.empno||,姓名:||row_emp.ename || ,工资:|| row_emp.sal|| ,部门编号:|| row_emp.deptno);
    END LOOP;
END;

7.使用显示游标更新emp表数据,将工资低于4000元的员工工资增加100

DECLARE
  CURSOR cursor_emp IS   SELECT sal FROM emp WHERE sal < 4000
      FOR UPDATE;
  v_sal emp.sal%TYPE; 
BEGIN
  OPEN cursor_emp;
  LOOP
    FETCH cursor_emp INTO v_sal;
    EXIT WHEN cursor_emp%NOTFOUND;
    UPDATE emp SET sal=sal+100  WHERE CURRENT OF cursor_emp;
  END LOOP;
  CLOSE cursor_emp;
END;

 

 

第十一章

1.使用嵌套循环输出stu_tb表中所有同学的在校表现信息

 

DECLARE
  s_tb stu_perf_type;
BEGIN
  SELECT stu_perf INTO s_tb FROM stu_tb
    WHERE stu_id = 1; 
  FOR i IN 1..s_tb.COUNT  LOOP 
     DBMS_OUTPUT.PUT_LINE(学生在校情况:||s_tb(i));
  END LOOP;
END;

 

2.使用TO_CHAR()函数将当前日期转换为‘‘yyyy-mm-dd hh24:mi:ss‘格式的字符串

 

 

select  to_char(sysdate, yyyy-mm-dd hh24:mi:ss )  from dual;

 

3.创建带有OUT参数的get_birth_claname()函数,根据姓名返回学生出生日期和所在班级名称的功能。运行函数,返回任一名学生的出生日期和班级名称

 

 

CREATE OR REPLACE FUNCTION get_ birth_claname (name IN VARCHAR2)
RETURN NUMBER
AS
v_claid  student.claid%TYPE;   
BEGIN
SELECT claid INTO v_claid  FROM student
WHERE sname = name; 
RETURN v_claid;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20003, 该学生不存在);
END;

 

4.定义RESULT()函数计算两个数值相除结果(商和余数),使用IN-OUT参数。运行,返回30/4的结果

 

 

CREATE OR REPLACE FUNCTION result
  (num1 NUMBER, num2 IN OUT NUMBER)
RETURN NUMBER
AS
  v_result NUMBER(6);
  v_remainder NUMBER;
BEGIN
  v_result := FLOOR(num1 / num2);
  v_remainder := MOD(num1, num2);
  num2 := v_remainder;
  RETURN v_result;
EXCEPTION
  WHEN ZERO_DIVIDE THEN
    DBMS_OUTPUT.PUT_LINE(错误信息:不能除0);
END;

 

 

 

第十二章

 

 

1.使用LOOP循环游标,取student表籍贯“北京”的同学的学号和姓名

 

 

Declare
 cursor stu_cur (v_sadrs varchar2)
is select sno,sname from student where sadrs = v_sadrs;
v_sno student.sno%type;
v_sname student.sname%type;
Begin
  open stu_cur(北京);
 loop
     fetch stu_cur into v_sno,v_sname;
     Exit when stu_cur%notfound;
     dbms_output.put_line(sno=||v_sno|| ,sname=||v_sname);
  End loop;
  close stu_cur;
End;

 

2.创建BEFORE类型触发器trig_Before_Stu,要求只能由scott用户对student表数据进行删除操作(环境变量 user

 

 

CREATE OR REPLACE TRIGGER trig_Before_Stu
  BEFORE DELETE ON student
BEGIN
  IF user != SCOTT THEN
     RAISE_APPLICATION_ERROR(-20001, 权限不足,不能进行删除操作);
  END IF;
END;

 

3.创建BEFORE触发器trig_OutPutScore,更新scores分数时显示分数变化(原来分数##,现在分数##)。自行测试

 

 

CREATE OR REPLACE TRIGGER trig_OutPutScore
  BEFORE UPDATE ON scores
  FOR EACH ROW
DECLARE
  oldvalue NUMBER;
  newvalue NUMBER;
BEGIN
  oldvalue := :OLD.sscore; 
  newvalue := :NEW.sscore; 
  DBMS_OUTPUT.PUT_LINE(原来分数=||oldvalue|| ,现在分数=||newvalue);
END;

 

4.创建一个DDL触发器trig_DenyDelObjForScott,禁止scott用户使用DROP命令删除自己模式中的对象

 

 

create or replace trigger trig_DenyDelOBjForScott
before drop on scott.schema
begin
    raise_addlication_error(-20000,不能对scott用户中的对象进行删除操作);
end;

 

5.分别建立数据库启动触发器trig_startup和数据库关闭触发器trig_shutdown,跟踪数据库启动和关闭事件。发生启动和关闭库时,向表db_log中输入信息(user,SYSDATE)

 

 

CREATE OR REPLACE TRIGGER trig_startup
AFTER STARTUP
ON DATABASE
BEGIN
  INSERT INTO db_log VALUES(user,SYSDATE);
END;

 

CREATE OR REPLACE TRIGGER trig_shutdown
BEFORE SHUTDOWN
ON DATABASE
BEGIN
  INSERT INTO db_log VALUES(user,SYSDATE);
END;

 

 

第十三章

 

1.基于student表创建视图stu_v。(授予权限后返回到SCOTT用户,再创建视图)

 

 

CREATE OR REPLACE VIEW stu_v
AS   
SELECT * FROM student;

 

2.创建INSTEAD OF触发器trig_DeleteScoreBySno,当在student表中删除学生信息时,首先显示这些学生的学号和姓名,再删除这些学生信息,并从scores表删除与之相关的成绩信息

 

 

CREATE OR REPLACE TRIGGER trig_DeleteScoreBySno
  INSTEAD OF DELETE
  ON stu_v
  FOR EACH ROW
BEGIN
  DBMS_OUTPUT.PUT_LINE(要删除的信息[sno=||:OLD.sno|| , sname=||:OLD.sname|| ]);
  DELETE scores WHERE sno = :OLD.sno;
  DELETE student WHERE sno = :OLD.sno;
END;

 

3.创建一个存储过程proc_FindStudents,根据性别和籍贯返回学生编号、姓名、性别和籍贯

 

 

CREATE OR REPLACE PROCEDURE proc_FindStudents
  (sex IN VARCHAR2, adrs IN VARCHAR2)
AS
  CURSOR myCursor IS
    SELECT * FROM student WHERE ssex = sex AND sadrs = adrs;
  myrow myCursor%ROWTYPE;
BEGIN
  FOR myrow IN myCursor LOOP
    DBMS_OUTPUT.PUT_LINE(编号:||myrow.sno||,姓名:||myrow.sname||,性别:||myrow.ssex||,籍贯:||myrow.sadrs);
  END LOOP;
END;

 

4.调用存储过程,返回籍贯为天津的女同学信息

 

 

exec proc_FindStudents(,天津);

 

5.创建过程proc_GetScoresBySno,根据指定学号返回该学生总成绩

 

 

CREATE OR REPLACE PROCEDURE proc_GetScoresBySno
  (no IN NUMBER, result OUT NUMBER)
AS
BEGIN
  SELECT SUM(sscore) INTO result
  FROM scores WHERE sno = no;
END;

 

6.调用存储过程统计学号为201102的学生总成绩

 

 

VARIABLE AllScores NUMBER;
EXEC proc_GetScoresBySno(201102,:AllScores);
PRINT AllScores;

 

7.创建存储过程proc_comp,包含两个数值参数,返回两个参数和到第一个参数,返回两个参数的积到第二个参数

 

 

CREATE OR REPLACE PROCEDURE proc_comp
  (
    num1 IN OUT NUMBER,
    num2 IN OUT NUMBER
  )
AS
  v1 NUMBER;
  v2 NUMBER;
BEGIN
  v1 := num1 + num2;
  v2 := num1 * num2;
  num1 := v1;
  num2 := v2;
END;

 

8.调用proc_comp存储过程,返回206的和与积

 

 

VARIABLE num1 NUMBER;  
VARIABLE num2 NUMBER;
EXEC :num1 := 20;    
EXEC :num2 := 6;
EXEC proc_comp(:num1,:num2);
PRINT num1 num2;     

 



以上是关于Oracle数据库代码指令简介的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Toad for Oracle 中使用自定义代码片段?

这些角度电子邮件指令代码片段如何连接

sql Oracle代码片段

Oracle 数据库 - 使用UEStudio修改dmp文件版本号,解决imp命令恢复的数据库与dmp本地文件版本号不匹配导致的导入失败问题,“ORACLE error 12547”问题处理(代码片段

Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段

Client / Server Interoperability Support Matrix for Different Oracle Versions (Doc ID 207303.1)(代码片段