整理的Oracle精辟问答题(8)
1.触发器和过程有什么区别?
触发器与过程的区别在于:
过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的。
---------------------------------------------------------------------------
2.写一遍创建触发器的代码。
create or replace trigger 触发器名称
[before 在执行前|after 在执行后|instead of 关于视图操作]
{insert | delete | update}
on 表名 或者 视图名
【referencing 指定新行或旧行】
【for each row 行级锁或是表级锁】
---------------------------------------------------------------------------
3.有表forum(id number(9,0),title,content,author,fjs number(8,0),pubdate)
表fj(id number,fid number(9,0),title,content,author,pubdate)
请写存储过程当向表fj插入数据成功后,修改forum表中与fid对应的id行的fjs=fjs+1.
--建表
create table forum(id number(9,0),title varchar2(50),content varchar2(200),author varchar2(80),fjs number(8,0),pubdate date);
create table fj(id number,fid number(9,0),title varchar2(50),content varchar2(200),author varchar2(80),pubdate date);
--插入数据
insert into forum values(1,'测试','我的测试触发器','Peter',19,sysdate);
insert into fj values(1,1,'回复测试','回答 我的触发器','Lisa',sysdate);
--查询
select * from forum ;
select * from fj;
--建立触发器
create or replace trigger trigger_test
after insert
on fj
referencing new as n
for each row
begin
if inserting then
dbms_output.put_line(:n.ID);
update forum set fjs=fjs+1 where id = :n.ID;
end if;
end;
---------------------------------------------------------------------------
4.instead of在创建存储过程是什么意思?
instead of 触发器是在视图上而不是在表上定义的触发器,它是用来替换所使用实际语句的触发器。
---------------------------------------------------------------------------
5.new 和old分别 是什么意思?
指定新行(即将更新)和旧行(更新前)的其他名称。
---------------------------------------------------------------------------
6.referencing是什么意思?for each row呢?
for each row
指定是否对受影响的每行都执行触发器,行几触发器,如果不用此子句,则为语句级触发器。
---------------------------------------------------------------------------
7.有表account(acct varchar2(20),acctname varchar2(50),bal number(9,2),flag varchar2(1))
分别表示帐号,户名,余额,性质(0存储,1贷款)
规则:存款户开户时必须交款10元(如一卡通)
为了防止操作员在开户时填错余额,现要求写一存储过程来防止上述问题。
--建表
create table account(acct varchar2(20),acctname varchar2(50),bal number(9,2),flag varchar2(1));
--建立是否是新用户的过程过程
create or replace procedure proc_getnum(accout varchar2,accountname varchar2,num varchar2,numflag out number) is
begin
select count(*) into numflag from account where acct=accout and acctname = accountname and flag = num;
end;
--建立是否交款10元的过程
create or replace procedure proc_num(accout varchar2,accountname varchar2,bal number,flag varchar2) is
num number;
begin
proc_getnum(accout,accountname,flag,num);
if num = 0 and bal < 10 then
dbms_output.put_line('必须交款十元!');
end if;
end;
--测试过程
begin
proc_num('1001','aaa',0.6,'1');
end;
--查询表
select * from account
------------------------------------------------------------------------------------
8.行级触发器指的是?如何定义行级触发器呢?
行级触发器对DML语句影响的每个行执行一次。
for each row;
------------------------------------------
9.有表ls(id number(9,0),acct varchar2(20),amount number(9,2),flag varchar2(1))
其中字段Id是一个自动增长的字段,并已为其建立了序列seq_id,
但程序员在为此表插入数据时并未为此字段指定值,
请问我应如何做,才能让id按照序列值插入?
--建表
create table ls(id number(9,0),acct varchar2(20),amount number(9,2),flag varchar2(1));
--建立序列
create sequence seq_test;
---建触发器
create or replace trigger trig_test
before insert
on ls
for each row
begin
if inserting then
select seq_test.nextval into :new.ID from dual;
end if;
end;
--插入数据
insert into ls(ACCT,amount,FLAG) values ('aaa',93.02,'1');
insert into ls(ACCT,amount,FLAG) values ('bbb',152.36,'1');
insert into ls(ACCT,amount,FLAG) values ('ccc',23.65,'1');
insert into ls(ACCT,amount,FLAG) values ('ddd',45.89,'1');
insert into ls(ACCT,amount,FLAG) values ('eee',78.95,'1');
--查询数据
select * from ls
------------------------------------------
10.语句级触发器指的是?主要用来实现什么?
语句级触发器对每个DML语句执行一次
------------------------------------------
11.有表student(classid,stuid,stuname,stuaddress)班号,学号,学生姓名,学生地址
表stumark(classid,stuid,clsid,mark)班号,学号,科目号,成绩
其中表stumark的stuid与表stuid相对应,classid也与student表的classid相对应。有外键联系。
现要求当删除student表中某班学生或某个学生时,先删除stumark中此班的所有或指定学生信息。
请编写触发器来实现约束检查。
--删除表
drop table stumark;
drop table student;
--建表
create table student(classid varchar2(20),stuid varchar2(20) primary key,stuname varchar2(20),stuaddress varchar2(50));
create table stumark(classid varchar2(20),stuid varchar2(20),clsid varchar2(20),mark varchar2(20));
--建约束
alter table stumark add constraint Fk_mark Foreign Key(stuid) references student(stuid);
--建触发器
create or replace trigger trig_delinfoforstumark
before delete
on student
referencing old as o
for each row
begin
if deleting then
dbms_output.put_line(:o.STUID);
delete from stumark where stuid = :o.STUID;
end if;
end;
select * from student;
select * from stumark;
--插入数据
insert into student values ('A001','001','Peter','秦皇岛');
insert into stumark values('A001','001','SQL','100');
insert into stumark values('A001','001','JAVA','89.25');
--删除测试之
delete from student where stuid = '001';
------------------------------------------
12.我们知道要在视图上执行插入,删除更新记录时需要有键保留表的限制。如果不存在此限制时,如何才能删除视图数据呢?
利用触发器 Instead Of
------------------------------------------
13.以题11中的表为例,建立视图
create view v_stu as select a.classid,a.stuid,a.stuname,b.clsid,b.mark from student a ,stumark b where a.classid=b.classid and a.stuid=b.stuid
现在要通过删除视图来实现
delete from v_stu where classid='....' and stuid='.....'
请问应如何写触发器来实现。
--建立触发器
create or replace trigger trig_forview
instead of delete on v_stu
referencing old as o
for each row
begin
delete from stumark where stuid = :o.STUID and classid = :o.classid;
delete from student where stuid = :o.stuid and classid = :o.classid;
end;
--测试DEL语句
delete from v_stu where classid = 'A001' and stuid = '001'
---------/"/"/"/"/"/"/"/"/"/"/"/"/"---------
现在要通过向视图插入数据来实现
inset into v_stu values('0123','ts287','china','.net',88)
请问应如何写触发器来实现?
--建立触发器
create or replace trigger trig_forview
instead of insert on v_stu
referencing new as n
for each row
begin
insert into student(classid,stuid,stuname) values(:n.CLASSID,:n.STUID,:n.STUNAME);
insert into stumark values (:n.CLASSID,:n.STUID,:n.CLSID,:n.MARK);
end;
--测试Insert语句
insert into v_stu values('0123','ts287','china','.net',88);
select * from student;
select * from stumark;
select * from v_stu;
select * from user_updatable_columns where TABLE_Name = 'V_STU'
------------------------------------------
14.模式触发器指的是?
如 create alter drop grant revoke 和 truncate 等DDL语句。用户可以创建触发器来防止删除自己创建的表。
模式触发器提供的主要功能是阻止DDL操作以及在发生DDL操作时提供额外的安全监控。
------------------------------------------
15.请写一触发器来记录本模式下对象创建的信息,保存内容包括(对象名,对象类型,创建日期)。
触发器名称为newobj
信息保存表为objdata(name varchar2(30),objtype varchar2(20),creatdate date)
--建表
create table objdata(name varchar2(30),objtype varchar2(20),creatdate date)
--建触发器
create or replace trigger trig_fortable
after create on schema
begin
insert into objdata values(ora_dict_obj_name,ora_dict_obj_type,sysdate);
end;
--测试语句
create table test(aa varchar2(20),bb varchar(30));
select * from objdata
create view view_tt
as select * from test
--查询objdata
select * from objdata
------------------------------------------
17.数据库触发器指的是?
--
可以创建在数据库事件上的触发器,包括启动,关闭,服务器错误,登录和注销等。
------------------------------------------
18.如何禁用触发器newobj?
alter trigger newobj enable;
alter trigger newobj disable;
------------------------------------------
19.触发器保存在哪个数据字典中?
user_triggers
------------------------------------------
20.dbms_output包中的put,put_line,new_line分别是什么意思?
put--------把文本放到缓冲区里去
put_line---把缓冲区文本打印出来
new_line---用于向缓冲区中添加换行符。
------------------------------------------
21.dbms_lob包中的read,write和substr分别是什么意思?
read----此过程从LOB数据中读取指定长度数据到缓冲区。
write---此过程用于将指定数量的数据写入LOB.
substr---此函数从LOB数据中取子串
------------------------------------------
22.调用哪个包的哪个函数可以将查询结果转换为xml格式?它的返回值是什么类型?
请写代码将student表中的数据转换为xml格式,并调用put_line显示出来?
Dbms_Xmlquery包
它的返回值是个CLOB类型
select * from student
declare
results clob;
xmlstr varchar2(32767);
line varchar(2000);
line_no integer := 1;
begin
results := dbms_xmlquery.getxml('select * from student');
xmlstr := dbms_lob.substr(results,32767);
loop
exit when xmlstr is null;
line := substr(xmlstr,1,instr(xmlstr,chr(10))-1);
dbms_output.put_line(line_no || ':'|| line);
xmlstr := substr(xmlstr,instr(xmlstr,chr(10))+1);--截取每一行一直到换行时的字符串 chr(10)是代表换行的ASCII码 instr('字符窜','要在该字符窜查找的字符')->返回一个数字
line_no := line_no + 1;
end loop;
end;
select chr(36) from dual
select instr('ssdf','s') from dual
------------------------------------------
23.如何来生成随机数与随机字符串?
--生成随机数
declare
num number;
begin
num := abs(dbms_random.random mod 100) ;
dbms_output.put_line(num);
end;
--生成随机字符串
declare
num varchar2(100);
begin
num := dbms_random.string('A',1);
dbms_output.put_line(num);
end;
------------------------------------------
24.请写过程来将表中数据读取到的xml内容写到c:"mydata"mystudent.xml文件中。
--建立一个表
drop table roster;
create table roster
(
sid varchar2(20),
sname varchar2(50),
ssex varchar2(50),
sdob varchar2(50),
smark varchar2(50),
ssub varchar2(50)
)
--插入测试数据
insert into roster values ('101','李华','男','1978.9.12','92','Java')
--建立一个过程
create or replace procedure proc_xmltotable(dir varchar,filename varchar2,errfile varchar2) is
p xmlparser.Parser;--建立一个解析器
doc xmldom.DOMDocument; --为读取XML文档
--在里面又定义了一个存储过程 需要xmldom.DOMDocument做参数
procedure readElement(doc xmldom.DOMDocument) is
dnl xmldom.DOMNodeList;
length number;
strsql varchar2(2000);
n xmldom.DOMNode;
m xmldom.DOMNode;
aname xmldom.DOMNamedNodeMap;--属性名
length1 number;
dnl1 xmldom.DOMNodeList;--读取student的子节点
begin
dnl := xmldom.getElementsByTagName(doc,'student');
length := xmldom.getLength(dnl);
for i in 0..length-1
loop
strsql := 'insert into roster values (';--
dbms_output.put_line(strsql||'1');
n := xmldom.item(dnl,i);
if xmldom.getNodeName(n)='student' then
aname := xmldom.getAttributes(n);
m := xmldom.item(aname,0);
strsql := strsql ||''''||xmldom.getNodeValue(m)||'''';
dbms_output.put_line(strsql||'2');--
end if;
dnl1 := xmldom.getChildNodes(n);
length1 := xmldom.getLength(dnl1);
for j in 0.. length1-1
loop
n := xmldom.item(dnl1,j);
strsql := strsql || ','''||xmldom.getNodeValue(xmldom.getfirstchild(n))||'''';--
dbms_output.put_line(strsql||'3');
end loop;
strsql := strsql || ')';
dbms_output.put_line(strsql||'4');
execute immediate(strsql);
end loop;
commit;
end readElement;
begin
p := xmlparser.newParser;--实例话
xmlparser.setValidationMode(p,False);--设定解析器的状态
xmlparser.setErrorLog(p,dir||'"'||errfile);--错误日志文件
xmlparser.setBaseDir(p,dir);--目录
xmlparser.parse(p,dir||'"'||filename);--设定文件的目录和文件
doc := xmlparser.getDocument(p);
readELement(doc);
xmldom.freeDocument(doc);
exception
when xmldom.INDEX_SIZE_ERR then
raise_application_error(-20120, 'Index Size error');
when xmldom.DOMSTRING_SIZE_ERR then
raise_application_error(-20120, 'String Size error');
when xmldom.HIERARCHY_REQUEST_ERR then
raise_application_error(-20120, 'Hierarchy request error');
when xmldom.WRONG_DOCUMENT_ERR then
raise_application_error(-20120, 'Wrong doc error');
when xmldom.INVALID_CHARACTER_ERR then
raise_application_error(-20120, 'Invalid Char error');
when xmldom.NO_DATA_ALLOWED_ERR then
raise_application_error(-20120, 'Nod data allowed error');
when xmldom.NO_MODIFICATION_ALLOWED_ERR then
raise_application_error(-20120, 'No mod allowed error');
when xmldom.NOT_FOUND_ERR then
raise_application_error(-20120, 'Not found error');
when xmldom.NOT_SUPPORTED_ERR then
raise_application_error(-20120, 'Not supported error');
when xmldom.INUSE_ATTRIBUTE_ERR then
raise_application_error(-20120, 'In use attr error');
end porcxmltotable;
--执行过程
begin
proc_tabletoxml('c:\mydata\','mystudent.xml','err.log');
end;
25.请写过程读取c:"mydata"mystudent.xml文件的内容并显示出来。
--建立过程
create or replace procedure proc_tableToXml(filename varchar2)
is
doc xmldom.DOMDocument; --定义全局XML文档的DOC
mainnode xmldom.DOMNode; --根元素的标签对象
rootele xmldom.DOMElement; --根元素的标签
rootnode xmldom.DOMNode; --根元素的标签的内容
brachele xmldom.DOMElement; --叶元素的标签
brachtext xmldom.DOMText; --叶元素的标签的内容
brachnode xmldom.DOMNode; --叶元素的标签的对象
student_node xmldom.DOMNode;--给根元素的标签确定为《student》
cursor getinfo is select * from roster; --定义一个游标来查询表
begin
doc := xmldom.newDOMDocument; --初始化
mainnode := xmldom.makeNode(doc);--读取主标签
rootele := xmldom.createElement(doc,'Roster');--把根标签命名为Roster
rootnode := xmldom.appendChild(mainnode,xmldom.makeNode(rootele));--把根标Roster加入子节点
for student in getinfo
loop
brachele := xmldom.createElement(doc, 'Student');
xmldom.setAttribute(brachele, 'ID', student.sid);
student_node := xmldom.appendChild(rootnode, xmldom.makeNode(brachele));
brachele := xmldom.createElement(doc, 'NAME');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.sname);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'SEX');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.ssex);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'BIRTHDAY');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.sdob);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'MARK');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.smark);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'SUBJECT');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.ssub);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'NameandSubject');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.sname||student.ssub);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
end loop;
xmldom.writeToFile(doc, filename);
xmldom.freeDocument(doc);
exception
when xmldom.INDEX_SIZE_ERR then
raise_application_error(-20120, 'Index Size error');
when xmldom.DOMSTRING_SIZE_ERR then
raise_application_error(-20120, 'String Size error');
when xmldom.HIERARCHY_REQUEST_ERR then
raise_application_error(-20120, 'Hierarchy request error');
when xmldom.WRONG_DOCUMENT_ERR then
raise_application_error(-20120, 'Wrong doc error');
when xmldom.INVALID_CHARACTER_ERR then
raise_application_error(-20120, 'Invalid Char error');
when xmldom.NO_DATA_ALLOWED_ERR then
raise_application_error(-20120, 'Nod data allowed error');
when xmldom.NO_MODIFICATION_ALLOWED_ERR then
raise_application_error(-20120, 'No mod allowed error');
when xmldom.NOT_FOUND_ERR then
raise_application_error(-20120, 'Not found error');
when xmldom.NOT_SUPPORTED_ERR then
raise_application_error(-20120, 'Not supported error');
when xmldom.INUSE_ATTRIBUTE_ERR then
raise_application_error(-20120, 'In use attr error');
end proc_tabletoxml;
--执行过程
begin
proc_tabletoxml('c:\mydata\mystudent.xml');
end;
触发器与过程的区别在于:
过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的。
---------------------------------------------------------------------------
2.写一遍创建触发器的代码。
create or replace trigger 触发器名称
[before 在执行前|after 在执行后|instead of 关于视图操作]
{insert | delete | update}
on 表名 或者 视图名
【referencing 指定新行或旧行】
【for each row 行级锁或是表级锁】
---------------------------------------------------------------------------
3.有表forum(id number(9,0),title,content,author,fjs number(8,0),pubdate)
表fj(id number,fid number(9,0),title,content,author,pubdate)
请写存储过程当向表fj插入数据成功后,修改forum表中与fid对应的id行的fjs=fjs+1.
--建表
create table forum(id number(9,0),title varchar2(50),content varchar2(200),author varchar2(80),fjs number(8,0),pubdate date);
create table fj(id number,fid number(9,0),title varchar2(50),content varchar2(200),author varchar2(80),pubdate date);
--插入数据
insert into forum values(1,'测试','我的测试触发器','Peter',19,sysdate);
insert into fj values(1,1,'回复测试','回答 我的触发器','Lisa',sysdate);
--查询
select * from forum ;
select * from fj;
--建立触发器
create or replace trigger trigger_test
after insert
on fj
referencing new as n
for each row
begin
if inserting then
dbms_output.put_line(:n.ID);
update forum set fjs=fjs+1 where id = :n.ID;
end if;
end;
---------------------------------------------------------------------------
4.instead of在创建存储过程是什么意思?
instead of 触发器是在视图上而不是在表上定义的触发器,它是用来替换所使用实际语句的触发器。
---------------------------------------------------------------------------
5.new 和old分别 是什么意思?
指定新行(即将更新)和旧行(更新前)的其他名称。
---------------------------------------------------------------------------
6.referencing是什么意思?for each row呢?
for each row
指定是否对受影响的每行都执行触发器,行几触发器,如果不用此子句,则为语句级触发器。
---------------------------------------------------------------------------
7.有表account(acct varchar2(20),acctname varchar2(50),bal number(9,2),flag varchar2(1))
分别表示帐号,户名,余额,性质(0存储,1贷款)
规则:存款户开户时必须交款10元(如一卡通)
为了防止操作员在开户时填错余额,现要求写一存储过程来防止上述问题。
--建表
create table account(acct varchar2(20),acctname varchar2(50),bal number(9,2),flag varchar2(1));
--建立是否是新用户的过程过程
create or replace procedure proc_getnum(accout varchar2,accountname varchar2,num varchar2,numflag out number) is
begin
select count(*) into numflag from account where acct=accout and acctname = accountname and flag = num;
end;
--建立是否交款10元的过程
create or replace procedure proc_num(accout varchar2,accountname varchar2,bal number,flag varchar2) is
num number;
begin
proc_getnum(accout,accountname,flag,num);
if num = 0 and bal < 10 then
dbms_output.put_line('必须交款十元!');
end if;
end;
--测试过程
begin
proc_num('1001','aaa',0.6,'1');
end;
--查询表
select * from account
------------------------------------------------------------------------------------
8.行级触发器指的是?如何定义行级触发器呢?
行级触发器对DML语句影响的每个行执行一次。
for each row;
------------------------------------------
9.有表ls(id number(9,0),acct varchar2(20),amount number(9,2),flag varchar2(1))
其中字段Id是一个自动增长的字段,并已为其建立了序列seq_id,
但程序员在为此表插入数据时并未为此字段指定值,
请问我应如何做,才能让id按照序列值插入?
--建表
create table ls(id number(9,0),acct varchar2(20),amount number(9,2),flag varchar2(1));
--建立序列
create sequence seq_test;
---建触发器
create or replace trigger trig_test
before insert
on ls
for each row
begin
if inserting then
select seq_test.nextval into :new.ID from dual;
end if;
end;
--插入数据
insert into ls(ACCT,amount,FLAG) values ('aaa',93.02,'1');
insert into ls(ACCT,amount,FLAG) values ('bbb',152.36,'1');
insert into ls(ACCT,amount,FLAG) values ('ccc',23.65,'1');
insert into ls(ACCT,amount,FLAG) values ('ddd',45.89,'1');
insert into ls(ACCT,amount,FLAG) values ('eee',78.95,'1');
--查询数据
select * from ls
------------------------------------------
10.语句级触发器指的是?主要用来实现什么?
语句级触发器对每个DML语句执行一次
------------------------------------------
11.有表student(classid,stuid,stuname,stuaddress)班号,学号,学生姓名,学生地址
表stumark(classid,stuid,clsid,mark)班号,学号,科目号,成绩
其中表stumark的stuid与表stuid相对应,classid也与student表的classid相对应。有外键联系。
现要求当删除student表中某班学生或某个学生时,先删除stumark中此班的所有或指定学生信息。
请编写触发器来实现约束检查。
--删除表
drop table stumark;
drop table student;
--建表
create table student(classid varchar2(20),stuid varchar2(20) primary key,stuname varchar2(20),stuaddress varchar2(50));
create table stumark(classid varchar2(20),stuid varchar2(20),clsid varchar2(20),mark varchar2(20));
--建约束
alter table stumark add constraint Fk_mark Foreign Key(stuid) references student(stuid);
--建触发器
create or replace trigger trig_delinfoforstumark
before delete
on student
referencing old as o
for each row
begin
if deleting then
dbms_output.put_line(:o.STUID);
delete from stumark where stuid = :o.STUID;
end if;
end;
select * from student;
select * from stumark;
--插入数据
insert into student values ('A001','001','Peter','秦皇岛');
insert into stumark values('A001','001','SQL','100');
insert into stumark values('A001','001','JAVA','89.25');
--删除测试之
delete from student where stuid = '001';
------------------------------------------
12.我们知道要在视图上执行插入,删除更新记录时需要有键保留表的限制。如果不存在此限制时,如何才能删除视图数据呢?
利用触发器 Instead Of
------------------------------------------
13.以题11中的表为例,建立视图
create view v_stu as select a.classid,a.stuid,a.stuname,b.clsid,b.mark from student a ,stumark b where a.classid=b.classid and a.stuid=b.stuid
现在要通过删除视图来实现
delete from v_stu where classid='....' and stuid='.....'
请问应如何写触发器来实现。
--建立触发器
create or replace trigger trig_forview
instead of delete on v_stu
referencing old as o
for each row
begin
delete from stumark where stuid = :o.STUID and classid = :o.classid;
delete from student where stuid = :o.stuid and classid = :o.classid;
end;
--测试DEL语句
delete from v_stu where classid = 'A001' and stuid = '001'
---------/"/"/"/"/"/"/"/"/"/"/"/"/"---------
现在要通过向视图插入数据来实现
inset into v_stu values('0123','ts287','china','.net',88)
请问应如何写触发器来实现?
--建立触发器
create or replace trigger trig_forview
instead of insert on v_stu
referencing new as n
for each row
begin
insert into student(classid,stuid,stuname) values(:n.CLASSID,:n.STUID,:n.STUNAME);
insert into stumark values (:n.CLASSID,:n.STUID,:n.CLSID,:n.MARK);
end;
--测试Insert语句
insert into v_stu values('0123','ts287','china','.net',88);
select * from student;
select * from stumark;
select * from v_stu;
select * from user_updatable_columns where TABLE_Name = 'V_STU'
------------------------------------------
14.模式触发器指的是?
如 create alter drop grant revoke 和 truncate 等DDL语句。用户可以创建触发器来防止删除自己创建的表。
模式触发器提供的主要功能是阻止DDL操作以及在发生DDL操作时提供额外的安全监控。
------------------------------------------
15.请写一触发器来记录本模式下对象创建的信息,保存内容包括(对象名,对象类型,创建日期)。
触发器名称为newobj
信息保存表为objdata(name varchar2(30),objtype varchar2(20),creatdate date)
--建表
create table objdata(name varchar2(30),objtype varchar2(20),creatdate date)
--建触发器
create or replace trigger trig_fortable
after create on schema
begin
insert into objdata values(ora_dict_obj_name,ora_dict_obj_type,sysdate);
end;
--测试语句
create table test(aa varchar2(20),bb varchar(30));
select * from objdata
create view view_tt
as select * from test
--查询objdata
select * from objdata
------------------------------------------
17.数据库触发器指的是?
--
可以创建在数据库事件上的触发器,包括启动,关闭,服务器错误,登录和注销等。
------------------------------------------
18.如何禁用触发器newobj?
alter trigger newobj enable;
alter trigger newobj disable;
------------------------------------------
19.触发器保存在哪个数据字典中?
user_triggers
------------------------------------------
20.dbms_output包中的put,put_line,new_line分别是什么意思?
put--------把文本放到缓冲区里去
put_line---把缓冲区文本打印出来
new_line---用于向缓冲区中添加换行符。
------------------------------------------
21.dbms_lob包中的read,write和substr分别是什么意思?
read----此过程从LOB数据中读取指定长度数据到缓冲区。
write---此过程用于将指定数量的数据写入LOB.
substr---此函数从LOB数据中取子串
------------------------------------------
22.调用哪个包的哪个函数可以将查询结果转换为xml格式?它的返回值是什么类型?
请写代码将student表中的数据转换为xml格式,并调用put_line显示出来?
Dbms_Xmlquery包
它的返回值是个CLOB类型
select * from student
declare
results clob;
xmlstr varchar2(32767);
line varchar(2000);
line_no integer := 1;
begin
results := dbms_xmlquery.getxml('select * from student');
xmlstr := dbms_lob.substr(results,32767);
loop
exit when xmlstr is null;
line := substr(xmlstr,1,instr(xmlstr,chr(10))-1);
dbms_output.put_line(line_no || ':'|| line);
xmlstr := substr(xmlstr,instr(xmlstr,chr(10))+1);--截取每一行一直到换行时的字符串 chr(10)是代表换行的ASCII码 instr('字符窜','要在该字符窜查找的字符')->返回一个数字
line_no := line_no + 1;
end loop;
end;
select chr(36) from dual
select instr('ssdf','s') from dual
------------------------------------------
23.如何来生成随机数与随机字符串?
--生成随机数
declare
num number;
begin
num := abs(dbms_random.random mod 100) ;
dbms_output.put_line(num);
end;
--生成随机字符串
declare
num varchar2(100);
begin
num := dbms_random.string('A',1);
dbms_output.put_line(num);
end;
------------------------------------------
24.请写过程来将表中数据读取到的xml内容写到c:"mydata"mystudent.xml文件中。
--建立一个表
drop table roster;
create table roster
(
sid varchar2(20),
sname varchar2(50),
ssex varchar2(50),
sdob varchar2(50),
smark varchar2(50),
ssub varchar2(50)
)
--插入测试数据
insert into roster values ('101','李华','男','1978.9.12','92','Java')
--建立一个过程
create or replace procedure proc_xmltotable(dir varchar,filename varchar2,errfile varchar2) is
p xmlparser.Parser;--建立一个解析器
doc xmldom.DOMDocument; --为读取XML文档
--在里面又定义了一个存储过程 需要xmldom.DOMDocument做参数
procedure readElement(doc xmldom.DOMDocument) is
dnl xmldom.DOMNodeList;
length number;
strsql varchar2(2000);
n xmldom.DOMNode;
m xmldom.DOMNode;
aname xmldom.DOMNamedNodeMap;--属性名
length1 number;
dnl1 xmldom.DOMNodeList;--读取student的子节点
begin
dnl := xmldom.getElementsByTagName(doc,'student');
length := xmldom.getLength(dnl);
for i in 0..length-1
loop
strsql := 'insert into roster values (';--
dbms_output.put_line(strsql||'1');
n := xmldom.item(dnl,i);
if xmldom.getNodeName(n)='student' then
aname := xmldom.getAttributes(n);
m := xmldom.item(aname,0);
strsql := strsql ||''''||xmldom.getNodeValue(m)||'''';
dbms_output.put_line(strsql||'2');--
end if;
dnl1 := xmldom.getChildNodes(n);
length1 := xmldom.getLength(dnl1);
for j in 0.. length1-1
loop
n := xmldom.item(dnl1,j);
strsql := strsql || ','''||xmldom.getNodeValue(xmldom.getfirstchild(n))||'''';--
dbms_output.put_line(strsql||'3');
end loop;
strsql := strsql || ')';
dbms_output.put_line(strsql||'4');
execute immediate(strsql);
end loop;
commit;
end readElement;
begin
p := xmlparser.newParser;--实例话
xmlparser.setValidationMode(p,False);--设定解析器的状态
xmlparser.setErrorLog(p,dir||'"'||errfile);--错误日志文件
xmlparser.setBaseDir(p,dir);--目录
xmlparser.parse(p,dir||'"'||filename);--设定文件的目录和文件
doc := xmlparser.getDocument(p);
readELement(doc);
xmldom.freeDocument(doc);
exception
when xmldom.INDEX_SIZE_ERR then
raise_application_error(-20120, 'Index Size error');
when xmldom.DOMSTRING_SIZE_ERR then
raise_application_error(-20120, 'String Size error');
when xmldom.HIERARCHY_REQUEST_ERR then
raise_application_error(-20120, 'Hierarchy request error');
when xmldom.WRONG_DOCUMENT_ERR then
raise_application_error(-20120, 'Wrong doc error');
when xmldom.INVALID_CHARACTER_ERR then
raise_application_error(-20120, 'Invalid Char error');
when xmldom.NO_DATA_ALLOWED_ERR then
raise_application_error(-20120, 'Nod data allowed error');
when xmldom.NO_MODIFICATION_ALLOWED_ERR then
raise_application_error(-20120, 'No mod allowed error');
when xmldom.NOT_FOUND_ERR then
raise_application_error(-20120, 'Not found error');
when xmldom.NOT_SUPPORTED_ERR then
raise_application_error(-20120, 'Not supported error');
when xmldom.INUSE_ATTRIBUTE_ERR then
raise_application_error(-20120, 'In use attr error');
end porcxmltotable;
--执行过程
begin
proc_tabletoxml('c:\mydata\','mystudent.xml','err.log');
end;
25.请写过程读取c:"mydata"mystudent.xml文件的内容并显示出来。
--建立过程
create or replace procedure proc_tableToXml(filename varchar2)
is
doc xmldom.DOMDocument; --定义全局XML文档的DOC
mainnode xmldom.DOMNode; --根元素的标签对象
rootele xmldom.DOMElement; --根元素的标签
rootnode xmldom.DOMNode; --根元素的标签的内容
brachele xmldom.DOMElement; --叶元素的标签
brachtext xmldom.DOMText; --叶元素的标签的内容
brachnode xmldom.DOMNode; --叶元素的标签的对象
student_node xmldom.DOMNode;--给根元素的标签确定为《student》
cursor getinfo is select * from roster; --定义一个游标来查询表
begin
doc := xmldom.newDOMDocument; --初始化
mainnode := xmldom.makeNode(doc);--读取主标签
rootele := xmldom.createElement(doc,'Roster');--把根标签命名为Roster
rootnode := xmldom.appendChild(mainnode,xmldom.makeNode(rootele));--把根标Roster加入子节点
for student in getinfo
loop
brachele := xmldom.createElement(doc, 'Student');
xmldom.setAttribute(brachele, 'ID', student.sid);
student_node := xmldom.appendChild(rootnode, xmldom.makeNode(brachele));
brachele := xmldom.createElement(doc, 'NAME');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.sname);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'SEX');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.ssex);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'BIRTHDAY');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.sdob);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'MARK');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.smark);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'SUBJECT');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.ssub);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
brachele := xmldom.createElement(doc, 'NameandSubject');
brachnode := xmldom.appendChild(student_node, xmldom.makeNode(brachele));
brachtext := xmldom.createTextNode(doc, student.sname||student.ssub);
brachnode := xmldom.appendChild(brachnode, xmldom.makeNode(brachtext));
end loop;
xmldom.writeToFile(doc, filename);
xmldom.freeDocument(doc);
exception
when xmldom.INDEX_SIZE_ERR then
raise_application_error(-20120, 'Index Size error');
when xmldom.DOMSTRING_SIZE_ERR then
raise_application_error(-20120, 'String Size error');
when xmldom.HIERARCHY_REQUEST_ERR then
raise_application_error(-20120, 'Hierarchy request error');
when xmldom.WRONG_DOCUMENT_ERR then
raise_application_error(-20120, 'Wrong doc error');
when xmldom.INVALID_CHARACTER_ERR then
raise_application_error(-20120, 'Invalid Char error');
when xmldom.NO_DATA_ALLOWED_ERR then
raise_application_error(-20120, 'Nod data allowed error');
when xmldom.NO_MODIFICATION_ALLOWED_ERR then
raise_application_error(-20120, 'No mod allowed error');
when xmldom.NOT_FOUND_ERR then
raise_application_error(-20120, 'Not found error');
when xmldom.NOT_SUPPORTED_ERR then
raise_application_error(-20120, 'Not supported error');
when xmldom.INUSE_ATTRIBUTE_ERR then
raise_application_error(-20120, 'In use attr error');
end proc_tabletoxml;
--执行过程
begin
proc_tabletoxml('c:\mydata\mystudent.xml');
end;