oracle基础

Oracle数据库命名概念解析


数据库名、实例名、数据库域名、全局数据库名、服务名 ,这是几个令很多初学者容易混淆的概念。相信很多初学者都与我一样被标题上这些个概念搞得一头雾水。我们现在就来把它们弄个明白。
一、数据库名什么是数据库名? 数据库名就是一个数据库的标识,就像人的身份证号一样。他用参数DB_NAME表示,如果一台机器上装了多全数据库,那么每一个数据库都有一个数据库名。在数据库安装或创建完成之后,参数DB_NAME被写入参数文件之中。格式如下: DB_NAME=myorcl ... 在创建数据库时就应考虑好数据库名,并且在创建完数据库之后,数据库名不宜修改,即使要修改也会很麻烦。因为,数据库名还被写入控制文件中,控制文件是以二进制型式存储的,用户无法修改控制文件的内容。假设用户修改了参数文件中的数据库名,即修改DB_NAME的值。但是在Oracle启动时,由于参数文件中的DB_NAME与控制文件中的数据库名不一致,导致数据库启动失败,将返回ORA-01103错误。

数据库名的作用 数据库名是在安装数据库、创建新的数据库、创建数据库控制文件、修改数据结构、备份与恢复数据库时都需要使用到的。有很多Oracle安装文件目录是与数据库名相关的,如: winnt: d:\oracle\product\10.1.0\oradata\DB_NAME\... Unix: /home/app/oracle/product/10.1.0/oradata/DB_NAME/... pfile: winnt: d:\oracle\product\10.1.0\admin\DB_NAME\pfile\ini.ora Unix: /home/app/oracle/product/10.1.0/admin/DB_NAME/pfile/init$ORACLE_SID.ora 跟踪文件目录: winnt: /home/app/oracle/product/10.1.0/admin/DB_NAME/bdump/... 另外,在创建数据时,careate database命令中的数据库名也要与参数文件中DB_NAME参数的值一致,否则将产生错误。同样,修改数据库结构的语句alter database, 当然也要指出要修改的数据库的名称。如果控制文件损坏或丢失,数据库将不能加载,这时要重新创建控制文件,方法是以nomount方式启动实例,然后以create controlfile命令创建控制文件,当然这个命令中也是指指DB_NAME。还有在备份或恢复数据库时,都需要用到数据库名。总之,数据库名很重要,要准确理解它的作用。

查询当前数据名 方法一:select name from v$database; 方法二:show parameter db_name 方法三:查看参数文件。

修改数据库名 前面建议:应在创建数据库时就确定好数据库名,数据库名不应作修改,因为修改数据库名是一件比较复杂的事情。那么现在就来说明一下,如何在已创建数据之后,修改数据库名。步骤如下: 1.关闭数据库。 2.修改数据库参数文件中的DB_NAME参数的值为新的数据库名。 3.以NOMOUNT方式启动实例,修建控制文件(有关创建控制文件的命令语法,请参考oracle文档)

二、数据库实例名 什么是数据库实例名? 数据库实例名是用于和操作系统进行联系的标识,就是说数据库和操作系统之间的交互用的是数据库实例名。实例名也被写入参数文件中,该参数为instance_name,在winnt平台中,实例名同时也被写入注册表。数据库名和实例名可以相同也可以不同。在一般情况下,数据库名和实例名是一对一的关系,但如果在oracle并行服务器架构(即oracle实时应用集群)中,数据库名和实例名是一对多的关系。这一点在第一篇中已有图例说明。

查询当前数据库实例名 方法一:select instance_name from v$instance; 方法二:show parameter instance 方法三:在参数文件中查询。

数据库实例名与ORACLE_SID 虽然两者都表是oracle实例,但两者是有区别的。instance_name是oracle数据库参数。而ORACLE_SID是操作系统的环境变量。 ORACLD_SID用于与操作系统交互,也就是说,从操作系统的角度访问实例名,必须通过ORACLE_SID。在winnt不台, ORACLE_SID还需存在于注册表中。且ORACLE_SID必须与instance_name的值一致,否则,你将会收到一个错误,在unix平台,是“ORACLE not available”,在winnt平台,是“TNS:协议适配器错误”。

数据库实例名与网络连接 数据库实例名除了与操作系统交互外,还用于网络连接的oracle服务器标识。当你配置oracle主机连接串的时候,就需要指定实例名。当然8i以后版本的网络组件要求使用的是服务名SERVICE_NAME。这个概念接下来说明 。

三、数据库域名什么是数据库域名? 在分布工数据库系统中,不同版本的数据库服务器之间,不论运行的操作系统是unix或是windows,各服务器之间都可以通过数据库链路进行远程复制,数据库域名主要用于oracle分布式环境中的复制。举例说明如:全国交通运政系统的分布式数据库,其中:福建节点: fj.jtyz 福建厦门节点: xm.fj.jtyz 江西: jx.jtyz 江西上饶:sr.jx.jtyz 这就是数据库域名。数据库域名在存在于参数文件中,他的参数是db_domain.

查询数据库域名 方法一:select value from v$parameter where name = 'db_domain'; 方法二:show parameter domain 方法三:在参数文件中查询。

全局数据库名 全局数据库名=数据库名+数据库域名,如前述福建节点的全局数据库名是:oradb.fj.jtyz

四、数据库服务名 什么是数据库服务名? 从oracle9i版本开始,引入了一个新的参数,即数据库服务名。参数名是SERVICE_NAME。如果数据库有域名,则数据库服务名就是全局数据库名;否则,数据库服务名与数据库名相同。

查询数据库服务名 方法一:select value from v$parameter where name = 'service_name'; 方法二:show parameter service_name 方法三:在参数文件中查询。

数据库服务名与网络连接 从oracle8i开如的oracle网络组件,数据库与客户端的连接主机串使用数据库服务名。之前用的是ORACLE_SID,即数据库实例名
创建Oracle数据库(以Oracle10g为例)

有两种创建数据库的方式,一种是以命令行脚本方式,即手动方式创建;另一种是利用Oracle提供的数据库配置向导来创建。

一个完整的数据库系统,应包括一个物理结构、一个逻辑结构、一个内存结构和一个进程结构,如果要创建一个新的数据库,则这些结构都必须完整的建立起来。





--常见的异常
--no_data_found 数据没有找到
--dup_val_on_index 向有唯一约束的表中插入重复行
--too_many_rows 返回出现多行
--value_error 一个算法,转换,截断,或大小约束错误
--zero_divide 发生被零除


declare test varchar(50);
begin
select ename into test from emp where empno=7499;
dbms_output.put_line('test='||test);
exception
when no_data_found then
dbms_output.put_line('test='||'数据没有找到');
end;*/
--自定义异常:

declare test varchar(20);
e exception;
begin
select ename into test from emp where empno='73691';
dbms_output.put_line('test='||test);
if test<>'SMITH' then raise e; end if;
exception
when no_data_found then dbms_output.put_line('test='||'数据没有找到');--系统异常
when e then dbms_output.put_line('test='||'不是须要的数据');--自定义的异常
end;

--自己申请变量

declare
type myrecord is record(a emp.empno%type, b varchar(20));--%表示与表中数据类型一致
real_record myrecord;
begin
select e.empno,e.ename into real_record from emp e where e.empno='7369' ;
dbms_output.put_line(real_record.a ||','||real_record.b);
end;

declare
myrec emp%rowtype;--%表示与表中数据类型一致
begin
select * into myrec from emp e where e.empno='7369' ;
dbms_output.put_line(myrec.empno ||','||myrec.ename||','||myrec.job);
end;
--游标
declare
cursor mycursor is select * from emp;
myrecord emp%rowtype;
begin
open mycursor;
fetch mycursor into myrecord;
while mycursor%found loop
dbms_output.put_line(myrecord.empno||','||myrecord.ename||','||myrecord.job);
fetch mycursor into myrecord;
end loop;
close mycursor;
end;

--用游标处理单个字段
declare
cursor cur_para(id varchar2) is select ename from emp where empno=id;
t_name emp.ename%type;
begin
open cur_para('7369');
loop
fetch cur_para into t_name;
exit when cur_para%notfound ;
dbms_output.put_line(t_name);
end loop;
close cur_para;
end;
----用for循环来处理单个字段

declare
cursor mycur_para(id varchar2) IS
select ename from emp where empno=id;
begin
dbms_output.put_line('*******结果集为********');
for mycur in mycur_para('7369') loop
dbms_output.put_line(mycur.ename);
end loop;
end;

--游标%isopen属性的使用

declare
t_name dept.dname%type;
cursor cur(id varchar2) IS
select dname from dept where deptno=id;
begin
--open cur('10');
if cur%isopen then dbms_output.put_line('游标己被打开');
else open cur('10');
end if;
fetch cur into t_name;
close cur;
dbms_output.put_line(t_name);
end;

--游标%rowcount属性的使用

declare
t_name dept.dname%type;
cursor mycur IS select dname from dept;
begin
open mycur;
loop
fetch mycur into t_name;
exit when mycur%notfound or mycur%found is null;
dbms_output.put_line('游标mycur的rowcount是:'||mycur%rowcount);
end loop;
close mycur;
end;

--用游标来修改字段

declare
cursor cur IS select dname from dept for update;
text dept.dname%type;
begin
open cur;
fetch cur into text;
while cur%found loop
update dept set dname=dname||'_t' where current of cur;
fetch cur into text;
end loop;
close cur;
end ;
select * from dept;

  --隐式游标

begin
for cur in(select dname from dept) loop
dbms_output.put_line(cur.dname);
end loop;
end;
--存储过程

create or replace procedure myproc(id in number) is name varchar2(14);
begin
select dept.dname into name from dept where dept.deptno=id;
--dbms_output.put_line(name);
end myproc;
--带参数的存储过程
create or replace procedure p(a_1 in number,b_1 in number,c_1 out number , d_1 in out number)
is
begin
if(a_1>b_1) then c_1:=a_1;
else c_1:=b_1;
end if;
d_1:=d_1+1;
end;
--in 表示输入参数,out表输出参数

declare
a_1 number :=3;
b_1 number :=4;
c_1 number;
d_1 number :=5;
begin
p(a_1,b_1,c_1,d_1);
dbms_output.put_line(c_1);
dbms_output.put_line(d_1);
end;

--在SQL下可运行的
create or replace procedure p
is
cursor c is select * from emp2 for update;
begin
for v_emp in c loop
if (v_emp.deptno=10) then update emp2 set sal=sal+10 where current of c;--特别之处
elsif (v_emp.deptno=20) then update emp2 set sal=sal+20 where current of c;
else update emp2 set sal=sal+50 where current of c;
end if;
end loop;
commit;
end;
java 调用存储过程p核心代码
Connection conn = db.getConn();连接oracle数据库
CallableStatement cstmt = conn.prepareCall("{call p(?,?,?,?)}");
cstmt.registerOutParameter(3, Types.INTEGER);
cstmt.registerOutParameter(4,Types.INTEGER);
cstmt.setInt(1,304);
cstmt.setInt(2,4);
cstmt.setInt(4,5);
cstmt.execute();
System.out.println(cstmt.getInt(3));
System.out.println(cstmt.getInt(4))
--创建函数 在SQL下可运行

create or replace function sal_tax(v_sal number) return number
is
begin
if(v_sal<2000) then return 0.01;
elsif(v_sal<3000) then return 0.5;
else return 0.8;
end if;
end;
--触发器
create table emp2_logw(
uname varchar2(12),
action varchar2(10),
atime date
);
create or replace trigger trig
after insert or update or delete on emp2 for each row
begin
if inserting then insert into emp2_log values(user,'insert',sysdate);
elsif updating then insert into emp2_log values(user,'update',sysdate);
elsif deleting then insert into emp2_log values(user,'delete',sysdate);
end if;
end;
update emp2 set sal=sal*2 where deptno=10;
select uname,action,to_char(atime,'yyyy-mm-dd hh24:mi:ss') from emp2_log;

--本来update dept set deptno=99 where deptno=10;是行不通的 当加入这个触发器后就可以运行了
create or replace trigger trig
after update on dept for each row
begin
update emp set deptno=:new.deptno where deptno=:old.deptno;
end;
--创建一个存储器
create or replace procedure myproc(id in number) is
myname varchar2(18);--这时定义的变量类型一定要有长度
begin
select dname into myname from dept where deptno=id;
dbms_output.put_line(myname);
end myproc;
--创建一个包
create or replace package p_package as
type test_cursor is ref cursor;
end p_package;
create or replace procedure test(p_cursor out p_package.test_cursor) is
begin
open p_cursor for select * from dept;
end test;
java 调用核心代码
Connection conn = db.getConn();连接oracle数据库
CallableStatement cstmt = conn.prepareCall("{call test(?)}");
cstmt.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR );
cstmt.execute();
ResultSet rs =(ResultSet)cstmt.getObject(1);
while(rs.next()){
System.out.println("<tr><td>" + rs.getInt(1) + "</td><td>"
 +rs.getString(2)+"</td><td>"+rs.getString(3)+"</td></tr>");
    }


CREATE OR REPLACE PACKAGE pkg_test
AS
TYPE myrctype IS REF CURSOR;

PROCEDURE get (p_id NUMBER, p_rc OUT myrctype);
END pkg_test;


CREATE OR REPLACE PACKAGE BODY pkg_test
AS
PROCEDURE get (p_id NUMBER, p_rc OUT myrctype)
IS
sqlstr VARCHAR2 (500);
BEGIN
IF p_id = 0 THEN
OPEN p_rc FOR
SELECT ID, NAME, sex, address, postcode, birthday
FROM student;
ELSE
sqlstr :=
'select id,name,sex,address,postcode,birthday
from student where id=:w_id';
OPEN p_rc FOR sqlstr USING p_id;
END IF;
END get;
END pkg_test;
package和package body有什么区别?
一个是定义所有的过程,一个是对所有过程的实现
package 是声明 package body是实现。

日记处理:
CREATE TABLE errorlog (
errorlog_id NUMBER,
logged_on TIMESTAMP DEFAULT SYSTIMESTAMP,
logged_by VARCHAR2(30) DEFAULT USER,
num1 NUMBER,
num2 NUMBER,
num3 NUMBER,
text1 VARCHAR2(1000),
text2 VARCHAR2(1000),
text3 VARCHAR2(1000)
);


CREATE SEQUENCE errorlog_seq
START WITH 1
INCREMENT BY 1;

CREATE OR REPLACE
PROCEDURE log_error (
n1 IN NUMBER:=NULL, t1 IN VARCHAR:=NULL,
n2 IN NUMBER:=NULL, t2 IN VARCHAR:=NULL,
n3 IN NUMBER:=NULL, t3 IN VARCHAR:=NULL
)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO errorlog
(errorlog_id,
num1, num2, num3, text1, text2, text3)
VALUES
(errorlog_seq.NEXTVAL, n1, n2, n3, t1, t2, t3);
COMMIT;
END;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值