Oracle数据库基本 *** 作
1概述
Oracle数据库客户端一般需要安装在服务器上,可以在服务器端 *** 作,一般我们可以用sql developer工具远程连接到数据库,先行建立数据库,然后对表进行增删改查。也可以使用MyEclispse的DB Broswer工具进行连接数据库并进行简单的增删改查。
2.SQL语句
Data Definition Language(DDL):
主要用于建立、修改、删除数据库对象(表),不需要事务的参与CREATE:创建表
CREATE TABLE emp(
id NUMBER(10),
name VARCHAR2(20),
gender CHAR(1),
birth DATE,
salary NUMBER(6,2),
);
DESC :查询表结构
DESC emp;
RENAME:重命名表名
RENAME emp TO employee;
DROP:删除表
DROP TABLE emp;
ALTER:列(字段) *** 作
ADD:增加字段
ALTER TABLE employee ADD (birth DATE DEFAULT sysdate);MODITY:修改字段
ALTER TABLE employee MODIFY (name VARCHAR2(40) DEFAULT 'CLERK' );DROP:删除字段
ALTER TABLE employee DROP (birth);
Data Manipulation Language(DML)
用于对数据记录进行 *** 作,包括插入,删除,修改。需要commit才能真正确认 *** 作,如果需要撤销则rollback。
INSERT INTO:插入数据
INSERT INTO employee(id, name, salary) VALUES(1001, 'rose', 5500);UPDATE…SET:更新数据
UPDATE employee SET salary = 8500 WHERE name = 'ROSE';DELETE FROM:删除记录
DELETE FROM employee WHERE job is null;
Transaction Control Language(TCL)
事务控制语言,包括commit提交,rollback回滚,savepoint保存点(可以回退到指定保存点)。在sql developer中为图标。
Data Query Language(DQL)
SQL基础查询:
查询语句的执行顺序
FROM 子句:执行顺序为从后往前、从右到左。数据量较少的表尽量放在后面。
WHERE子句:执行顺序为自下而上、从右到左。将能过滤掉最大数量记录的条件写在WHERE 子句的最右。
GROUP BY:执行顺序从左往右分组,最好在GROUP BY前使用WHERE将不需要的记录在GROUP BY之前过滤掉。
HAVING 子句:消耗资源。尽量避免使用,HAVING 会在检索出所有记录之后才对结果集进行过滤,需要排序等 *** 作。
SELECT子句:少用号,尽量取字段名称。ORACLE 在解析的过程中, 通过查询数据字典将号依次转换成所有的列名, 消耗时间。
ORDER BY子句:执行顺序为从左到右排序,消耗资源。
也就是从哪张表中以什么样的限制条件确定数据内容,再通过分组与进一步限制分组条件得到一个处理过的数据,最后选择出来,如有需要,则对最后选择的数据进行排序。
FROM子句:
From后接表名,from前可以可以是,但是不建议(查询效率低),一般接要查询的字段名。分组函数,字段和表名都可以使用别名,不加引号数据库中为大写,加引号别名可以用空格小写等。
WHERE子句:
当查询条件中和数字比较,可以使用单引号引起,也可以不用,当和字符及日期类型的数据比较,则必须用单引号引起。
使用条件判断:>,<,<=,<=,!=,<>,=。
SELECT ename, sal FROM emp WHERE sal< 2000;SELECT ename, sal, job FROM emp WHERE job = 'SALESMAN';SELECT ename, sal, hiredate FROM emp
WHERE hiredate>todate('2002-1-1','YYYY-MM-DD');使用AND/OR关键字
如果希望返回的结果必须满足多个条件,应该使用AND逻辑 *** 作符连接这些条件如果希望返回的结果满足多个条件之一即可,应该使用OR逻辑 *** 作符连接这些条件SELECT ename, sal, job FROM emp
WHERE sal> 1000 AND job = 'CLERK';
使用LIKE条件
SELECT ename, job FROM emp WHERE ename LIKE '_A%';(第二个字母为A)‘_A%’_表示占位一个字符,%表示0到多个字符。
使用IN/NOT IN
在WHERE子句中可以用比较 *** 作符IN(list)来取出符合列表范围中的数据。其中的参数list表示值列表,当列或表达式匹配于列表中的任何一个值时,条件为TRUE,该条记录则被显示出来。
SELECT ename, job FROM emp WHERE job IN ('MANAGER', 'CLERK');使用BETWEEN 1 AND 2
用来查询符合(1,2)值域范围之内的数据,通常查询数字和日期类型的数据范围。
SELECT ename, sal FROM emp
WHERE sal BETWEEN 1500 AND 3000;
使用IS NULL和IS NOT NULL
条件筛选值为空的记录,空值不能用‘=’来判断。
使用ANY和ALL条件
在比较运算符中,可以出现ALL和ANY,表示“全部”和“任一”,> ANY : 大于最小< ANY:小于最大> ALL:大于最大< ALL:小于最小SELECT empno, ename, job, sal, deptno
FROM emp WHERE
sal> ANY (SELECT sal FROM emp WHERE job = 'SALESMAN');查询条件中使用算术表达式
当查询需要对选出的字段进行进一步计算,可以在数字列上使用算术表达式(+、-、、/)。表达式符合四则运算的默认优先级,如果要改变优先级可以使用括号。
SELECT ename, sal, job FROMempWHERE ename = UPPER('rose');SELECT ename, sal, job FROM empWHERE sal 12 >100000;使用DISTINCT过滤重复
DISTINCT必须紧跟SELECT,后面可以有多个字段,表示过滤掉多个字段都重复的选项,第二例中不显示重复的deptno和job相同的记录。
SELECT DISTINCT deptno FROM emp;
SELECT DISTINCT deptno, job FROM emp;
使用ORDER BY子句
对查询数据按照一定的规则排序,则使用order by子句,order by子句必须为select子句的最后一个子句。默认升序排列,从小到大,ASC表示升序。DESC表示降序,从大到小。
SELECT ename, sal FROM emp
ORDER BY sal DESC;
Order by多个列,每个列需要单独指定排序规则,先按照第一个字段排序,当第一个字段的值相同时,再按照第二个字段的值排序。
聚合函数分组函数
当需要统计的数据并不能在表里直观列出,而是需要根据现有的数据计算得到结果,这种功能可以使用聚合函数来实现。
因为是多行数据参与运算返回一行结果,也称作分组函数、多行函数、集合函数。用到的关键字:GOURP BY 按什么分组,HAVING进一步限制分组结果MAX和MIN
用来取得列或者表达式的最大最小值,包括数字,字符和日期。
SELECT MAX(sal) max_sal, MIN(sal) min_sal FROM emp;AVG和SUM
用来统计列或者表达式的平均值和求和,只能处理数字类,并且平均值忽略NULL。
SELECT AVG(sal) avg_sal, SUM(sal) sum_sal FROM emp;COUNT
用来计算表中的记录条数,同样忽略NULL。
SELECT COUNT(job) total_num FROM emp;
空值的 *** 作
NVL(expr1, expr2):将NULL转变为非NULL值。如果expr1为NULL,则取值expr2, expr2是非空值。
NVL2(expr1, expr2, expr3):和NVL函数功能类似,都是将NULL转变为非空值。NVL2用来判断expr1是否为NULL,如果不是NULL,返回expr2,如果是NULL,返回expr3。
GROUP BY子句
Group by是表示对表中某个字段进行分组,值相同为一组,而分组函数的意思则是对这每一个组进行计算,平均值或是最大最小值。
HAVING子句
是对分组后的结果进行进一步的限制,HAVING子句必须紧跟在GROUP BY子句后,不能单独存在。限制分组条件不能放在WHERE子句中。
SELECT deptno, MAX(sal) max_sal FROM emp
GROUP BY deptno HAVING MAX(sal) >4000;
SQL关联查询:
概述,在实际应用中,往往我们所需要的数据是分布在不同的表上的,我们想要获取数据必须跨表格查询。
关联有两种方式:
SELECT table1column, table2column
FROM table1, table2
WHERE table1column1 = table2column2;
SELECT table1column, table2column
FROM table1JOIN table2
ON(table1column1 = table2column2);
关联查询有三种连接方式
内连接返回关联表中所有满足条件的记录(也称等值连接)外连接返回一些不满足条件的记录,外连接有左外连接,右外连接和全外连接三种形式其中左外连接返回左边所有记录而不必管右边是否匹配,如不匹配则为NULL值,右外连接返回右边所有记录而不必管左边的记录是否匹配,如不匹配则默认NULL,全外连接返回左边和右边所有的数据,左右边不匹配的数据,对应的其他字段值为NULL,格式如下
JOIN ON式
SELECT table1column, table2column
FROM table1 [LEFT | RIGHT | FULL] JOIN table2ON table1column1 = table2column2;
WHERE式
Select from dave a,bl b where aid=bid(+);+号的位置和意义
‘+’号加在哪个表,哪个表就是关联表,另一张表就是基表。基表全部显示,关联表匹配显示。+在左边就是右外连接,+在右边就是左外连接。
自连接:
表示数据的来源是同一张表的内容,即将一张表中的不同列进行连接,可以是等值或者不等值。实现方式是利用别名将一张表看作两张表。
SELECT workerempnow_empno,workerenamew_ename, managerempnom_empno, managerenamem_enameFROM emp worker join emp manager
ON workermgr = managerempno;
SQL高级查询:
子查询:
子查询用在WHERE里
在SELECT中,往往WHERE的限制条件并不是一个确定的值,而是来源于另一个查询结果,即需要在另一个查询结果的基础上进行查询,这个时候为另一个查询提供数据的查询就叫做子查询。
SELECT eename, ejob FROM emp e
WHERE ejob = (SELECT job FROM emp WHERE ename = 'SCOTT');可以与多行/单行比较 *** 作符混合使用。
子查询用在HAVING子句
SELECT deptno, MIN(sal) min_sal FROM emp GROUP BY deptnoHAVING MIN(sal) > (SELECT MIN(sal) FROM emp WHERE deptno = 30);表示分组条件需要满足的条件。可以把子查询当成一个结果。
子查询用在FROM部分
子查询用在FROM子句中,子查询可称为行内视图或者匿名试图,可以把它当成一张单独的表,用别名进行标识。
子查询用在SELECT子句中
可以认为是外连接的一张表现
分页查询:
ROWNUM
伪列,返回标识行数据顺序的数字,伪列并不是真正的列数据,只是用来显示行数,并不能单独作为一列进行分组 *** 作。
ROWNUM的结果从第一行数据之上开始,每查询到一条数据则指针下移一个,所以只有查询到数据后才能够出现伪列数字,因此不能直接用在where里,如果要利用ROWNUM截取结果集的部分数据,可以将含有ROWNUM伪列的SELECT子句放在FROM内,作为视图,供外部的SELECT语句使用,此时的伪列已形成顺序数据,可以进行分组函数 *** 作。
也就是将ROWNUM先作为行内视图的一个列,在主查询中就可以使用这个列值作为条件。
SELECT FROM (SELECT ROWNUMrn , e FROM emp e )WHERE rn BETWEEN 8 AND 10;
使用子查询和ROWNUM进行分页
分页 *** 作需要有一个作为分页标准的数据,该数据线进行排序,排序的结果作为视图被父查询用伪列标识顺序数字,然后在最外面的爷爷查询对伪列进行分页。
如:
SELECT FROM
(SELECT ROWNUMrn , t FROM
(SELECT empno,ename,sal FROM emp
ORDER BY sal DESC) t
)
WHERE rn BETWEEN 8 AND 10;
DECODE函数
DECODE (expr, search1, result1[, search2, result2…][, default])它用于比较参数expr的值,如果匹配到哪一个search条件,就返回对应的result结果,可以有多组search和result的对应关系,如果任何一个search条件都没有匹配到,则返回最后default的值。default参数是可选的,如果没有提供default参数值,当没有匹配到时,将返回NULL。
SELECT ename, job, sal,
DECODE(job, 'MANAGER', sal 12,
'ANALYST', sal 11,
'SALESMAN', sal 105,
sal) bonus
FROM emp;
SELECT deptno, dname, loc
FROM dept
ORDER BY
DECODE(dname, '研发部',1,'市场部',2,'销售部',3), loc;分组函数
ROW_NUMBER
ROW_NUMBER()
OVER (PARTITION BY deptno ORDER BY empno)根据deptno分组,在分组内根据empno内排序,比ROWNUM功能更强。可以直接从结果集中取出子集RANK
RANK() OVER( PARTITION BY col1 ORDER BY col2)功能与上相同,不同在于存在并列,并列第二跳过第三直接第四的规则。
DENSE_RANK
如果有并列第二,下一个排序将是三。
高级分组函数
ROLLUP
如果对两个字段rollup,那么第一个字段相同的值会当成一组,如果有分组函数求和,就会对第一字段所有的数据求和,单独成行。此时第二字段值为空。可以用于统计年度销售(工资)和。
CUBE
CUBE函数对字段进行排列统计,比如三个字段的CUBE运算,将三个字段排列成6种情况具体需要使用的时候再参考百度。
GROUPING()
GROUPING只能在使用ROLLUP或CUBE的查询中使用。当需要在返回空值的地方显示某个值时,GROUPING()就非常有用。案例情况复杂,具体使用时再说。
集合 *** 作
UNION、UNION ALL、INTERSECT、MINUS
Union表示取多次SELECT结果的并集,如果去掉重复的数据。
Union All与union功能一样,只是它不会去掉重复的数据,会全部显示。
Intersect表示相交,多次查询后去相同的数据,即同时满足两个查询条件的数据Minus表示差集,即将第一个结果集中的数据,减去第二个结果集的数据。即满足第一个查询条件,而不满足第二查询条件的数据。
Data Control Language(DCL):
用于执行权限的授予和收回 *** 作、创建用户等,包括授予(GRANT)语句,收回(REVOKE)语句,CREATE USER语句,其中GRANT用于给用户或角色授予权限, REVOKE用于收回用户或角色已有的权限。DCL语句也不需要事务的参与,是自动提交的。
GRANT CREATE VIEW TO tarena;
3视图、索引、序列、约束
视图
视图本质上是一条SELECT语句,当SELECT子查询在from子句中,可以把SELECT子句的结果当作一个视图。视图本身只是基表的映射,只是把基表中的数据显示出来,可以把视图当成表看待,所有 *** 作都与表 *** 作极其相似。
视图有三种,简单视图不包括函数,复杂视图包含了分组函数等附加的内容,连接视图是基于多个表的。
视图的优劣点:
如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询;视图本质上就是一条SELECT语句,所以当访问视图时,只能访问到所对应的SELECT语句中涉及到的列,对基表中的其它列起到安全和保密的作用,可以限制数据访问。
同时因为视图本质是基表的数据,所以对视图的 *** 作会影响到基表从而不安全。这里可以使用WITH READ ONLY来限制对视图的DML语言。
CREATE OR REPLACE VIEW v_emp_10
AS
SELECT empno, ename, sal, deptno FROM empWHERE deptno = 10
WITH READ ONLY;
使用DCL语句可以授权用户创建视图的权限,
GRANT CREATE VIEW TO tarena;
创建简单视图
CREATE VIEW v_emp_10
AS
SELECT empno, ename, sal, deptno
FROM emp
WHERE deptno = 10;
查询视图
SELECT id, name, salary FROM v_emp_10;
对视图的DML *** 作
简单视图可以进行DML *** 作,但是 *** 作的对象必须是基表里视图包含的字段,即对视图可见。而且简单视图的DML *** 作会对影响基表数据。
WITH CHECK OPTION短语表示,通过视图所做的修改,必须在视图的可见范围内,无论是INSERT UPDATE DELETE *** 作都必须在视图范围内,超过视图范围不可用。
CREATE [OR REPLACE] VIEW view_name[(alias[, alias…])]
AS subquery
[WITH CHECK OPTION];
删除视图
DROP VIEW v_emp_10;
对视图的删除不会导致基表数据的丢失,不会影响基表数据。
序列
序列(SEQUENCE)是一种用来生成唯一数字值的数据库对象。序列的值由Oracle程序按递增或递减顺序自动生成,通常用来自动产生表的主键值,是一种高效率获得唯一键值的途径。
序列是独立的数据库对象,和表是独立的对象,序列并不依附于表。
通常情况下,一个序列为一个表提供主键值,但一个序列也可以为多个表提供主键值。
CREATE SEQUENCE [schema]sequence_name
[ START WITH i ] [ INCREMENT BY j ]
[ MAXVALUE m | NOMAXVALUE ]
[ MINVALUE n | NOMINVALUE ]
[ CYCLE | NOCYCLE ][ CACHE p | NOCACHE ]
创建一个序列,起始数据是100,步进是10:
CREATE SEQUENCE emp_seq
START WITH 100
INCREMENT BY 10;
NEXTVAL:获取序列的下个值
CURRVAL:获取序列的当前值
当序列创建以后,必须先执行一次NEXTVAL,之后才能使用CURRVAL。
获取序列的第一个值,并且使用序列值为EMP表插入新的记录:
删除序列
DROP SEQUENCE emp_seq;
索引
创建索引
CREATE [UNIQUE] INDEX index_name
ON table(column[, column…]);
index_name表示索引名称
table表示表名
column表示列名,可以建立单列索引或复合索引UNIQUE表示唯一索引
CREATE INDEX idx_emp_job_sal ON emp(job, sal);可以增加函数
CREATE INDEX emp_ename_upper_idx
ON emp(UPPER(ename));
重建索引,提高索引空间利用率
ALTER INDEX index_name REBUILD;
删除索引
DROP INDEX idx_emp_ename;
为提升查询效率,创建和使用索引的原则:
1为经常出现在WHERE子句中的列创建索引
2为经常出现在ORDER BY、DISTINCT后面的字段建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致3为经常作为表的连接条件的列上创建索引
4不要在经常做DML *** 作的表上建立索引
5不要在小表上建立索引
6限制表上的索引数目,索引并不是越多越好
7删除很少被使用的、不合理的索引
约束
CONSTRAINT
非空约束(Not Null),简称NN
创建表时添加约束
CONSTRAINT employees_hiredate_nn NOT NULL修改表时增加非空约束
ALTER TABLE employees
MODIFY (eid NUMBER(6) NOT NULL);
修改表时取消非空约束
ALTER TABLE employees
MODIFY (eid NUMBER(6));
唯一性约束(Unique),简称UK
1、建立数据库
/建立Oracle登录用户(以ZXDIFSRV为例) 即建立空数据库---------------------------------/
xsl>svrmgrl
svrmgrl>connect system/manager
svrmgrl>
drop user ZXDIFSRV cascade;
CREATE USER "ZXDIFSRV" IDENTIFIED BY "ZXDIFSRV" DEFAULT TABLESPACE "USERS" TEMPORARY TABLESPACE "TEMP" PROFILE DEFAULT;
GRANT "CONNECT" TO "ZXDIFSRV";
GRANT "RESOURCE" TO "ZXDIFSRV";
GRANT UNLIMITED TABLESPACE TO "ZXDIFSRV";
ALTER USER "ZXDIFSRV" DEFAULT ROLE ALL;
svrmgrl>commit;
2、数据库启动
//数据库启动,即启动Oracle Service ORCL
xsl>svrmgrl
xsl>connect interal
xsl>startup
xsl>exit
xsl>sqlplus system/manager
xsl>sqlplus zxdifsrv/zxdifsrv
3、建立一个新访问用户
建立一个新的访问用户与密码:
xsl>svrmgrl
svrmgrll>connect system/manager
svrmgrl>
drop user win2001-900 cascade;
CREATE USER "win2001-900" IDENTIFIED BY "123456" DEFAULT TABLESPACE "USERS" TEMPORARY TABLESPACE "TEMP" PROFILE DEFAULT;
GRANT "CONNECT" TO "win2001-900";
GRANT "RESOURCE" TO "win2001-900";
GRANT UNLIMITED TABLESPACE TO "win2001-900";
ALTER USER "win2001-900" DEFAULT ROLE ALL;
svrmgrl>commit;
4、导入导出数据
导入数据时必须先要建立一个空的数据库
直接进入命令行窗口,可以进行导入导出命令
导入xsl>imp zxdifsrv/zxdifsrv 然后按提示写入文件的路径就可以了(输入时提示要输入用户名,此用户名应该为导入文件的原数据库的用户名,而不是导入的数据库的用户名)
导出xsl>exp zxdifsrv/zxdifsrv 然后按提示写入文件的路径就可以了
启动Oracle,首先要启动OracleServiceORCL服务
5、建立一个表
//在Oracle里system数据库建立一个表Customer
xml>svrmgrl
svrmgrl>connect system/manager
svrmgrl>Create table Customer(
CustID integer,
CustName varchar(20),
Memo varchar(200)
);
commit;
//DB2直接ENTER就可以,不用commit;
svrmgrl>exit
语句已执行
建立成功
/
6、导入数据的另外一种方法
注:不管用哪一种数据库导入的方法,都要先建立一个空的数据库
xml>sqlplus zxdifsrv/zxdifsrv
sql>@ (为要导入的数据库的脚本),然后Enter。
7、delete tablename是删除整个表的内容,而drop tablename是删除表。
运行存储过程用“/”结束
8、数据库后安装配置
把D:\Oracle\network\ADMIN里的tnsnamesora配置下,参照原来的配置就可以了
9、sqlplus远程启动
在命令提示符下输入(此方式必须先进行关闭数据库 *** 作,见14、远程关闭(要求远程数据库必须是已启动),在E:\ORACLE\ORA81\SYSMAN\IFILES目录下生成一个DE_TEST_ZCB_8112ORA文件后,再以此文件启动数据库):
SQLPLUS /NOLOG
CONNECT INTERNAL/ORACLE@TESTSOFTONECOM AS SYSDBA
STARTUP FILE=E:\ORACLE\ORA81\SYSMAN\IFILES\DE_TEST_ZCB_8112ORA
此路径为远程启动服务路径,一般情况下在本地安装目录的ORACLE\ORA81\SYSMAN\IFILES下。
INTERNAL 为用户名,ORACLE为密码,TESTSOFTONECOM为远程服务连接串
Sqlplus远程关闭
SQLPLUS /NOLOG
CONNECT INTERNAL/ORACLE@TESTSOFTONECOM AS SYSDBA
SHUTDOWN
INTERNAL 为用户名,ORACLE为密码,TESTSOFTONECOM为远程服务连接串。
10、TNSNAMESORA配置
在安装目录下,如:E:\Oracle\Ora81\network\ADMIN下用写字板或记事本打开TNSNAMEORA文件,文件内容大概如下:
TESTSOFTONECOM =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = zcb_8115)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = test)
)
)
蓝色部分为安装时录入的信息。
如果该文件没有配置成功,该文件可通过以下步骤进行配置:
1)、在程序菜单中打开NET8 CONFIGURATION ASSISTANT
2)、选择Net8 Configuration Assistant,打开,进入"Net8 Configuration Assistant:欢迎"窗口
2)、选择"本地网络服务名设置",点击"下一步", d出以下窗体;
3)、在"Net8 Configuration Assistant:网络服务名配置"窗口中选择"添加",点击"下一步", d出以下窗体;
4)在"Net8 Configuration Assistant:网络服务名配置,数据库版本"窗口中选择"ORACLE 8I数据库或服务",点击"下一步",d出以下窗体;
5)在"Net8 Configuration Assistant:网络服务名配置,服务名"窗口输入服务名,此服务名跟安装时录入的服务名(SID)相同,录入后,点击"下一步",d出以下窗体;
6)、在"Net8 Configuration Assistant:网络服务名配置,请选择协议"窗口选择"TCP"此时只能选择"TCP",点击"下一步", d出以下窗体;
7)在"Net8 Configuration Assistant:网络服务名配置,TCP/IP协议"窗口输入主机名(如果连接本地数据库,则录入本地计算机名,如果连接远程数据库,则录入远程计算机名),选择默认的"请使用标准端口号1521"(建议最好不要修改),点击"下一步",d出以下窗体;
8)、在"Net8 Configuration Assistant:网络服务名配置,测试"窗口选择"是,进行测试",点击"下一步",d出以下窗体;
9)、当"Net8 Configuration Assistant:网络服务名配置,正在连接"窗口对话框中出现提示"正在连接…测试成功"信息,表示测试通过。此时点击"下一步",进入"Net8 Configuration Assistant: 网络服务名配置,网络服务名"窗口;
10)、在"Net8 Configuration Assistant:网络服务名配置,网络服务名"窗口输入网络服务名,服务名为ORACLE连接串,可任意录入,如:test,点击"下一步",d出以下窗体;
11)、在"Net8 Configuration Assistant:网络服务名配置,是否需要另一个网络服务名"窗口中选择"否",点击"下一步",进入"网络服务名配置完成" 窗口;
12)、在"网络服务名配置完成"窗口中点击"下一步",d出以下窗体;
13)、在"欢迎"窗口点击"完成",退出配置过程
TNSNAMESORA配置完成后,再配置BDE(BDE如何配置略),可通过BDE、PLSQL、SQL EXPLORER和TNSPING命令来测试ORACLE是否连接正确。下面用TNSPING来测试是否连接。
11、配置服务
可以在客户端机器上使用oracle Net Configuration Assistant或oracle Net Manager图形配置工具对客户端进行配置,该配置工具实际上修改tnsnamesora文件。所以我们可以直接修改tnsnamesora文件,下面以直接修改tnsnamesora文件为例:
该文件的位置为: …\network\admin\tnsnamesora (for windows)
…/network/admin/tnsnamesora (for unix)
此处,假设服务器名为testserver,服务名为orcltestservercom,使用的侦听端口为1521,则tnsnamsora文件中的一个test网络服务名(数据库别名)为:
test =
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=orcltestservercom)
)
)
在命令提示符下录入: TNSPING TESTSOFTONECOM
用sqlplus程序通过testtestservercom网络服务名测试,如sqlplus system/manager@testtestservercom
12、易混淆术语介绍
Db_name:对一个数据库(Oracle database)的唯一标识
Db_domain:定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。
Global_name:对一个数据库(Oracle database)的唯一标识
Service_name:该参数是oracle8i新引进的。
Net service name:网络服务名,又可以称为数据库别名(database alias)。
通过使用一些辅助性工具来找到程序中的瓶颈,然后就可以对瓶颈部分的代码进行优化。一般有两种方案:即优化代码或更改设计方法。我们一般会选择后者,因为不去调用以下代码要比调用一些优化的代码更能提高程序的性能。而一个设计良好的程序能够精简代码,从而提高性能。
下面将提供一些在JAVA程序的设计和编码中,为了能够提高JAVA程序的性能,而经常采用的一些方法和技巧。
1.对象的生成和大小的调整。
JAVA程序设计中一个普遍的问题就是没有好好的利用JAVA语言本身提供的函数,从而常常会生成大量的对象(或实例)。由于系统不仅要花时间生成对象,以后可能还需花时间对这些对象进行垃圾回收和处理。因此,生成过多的对象将会给程序的性能带来很大的影响。
例1:关于String ,StringBuffer,+和append
JAVA语言提供了对于String类型变量的 *** 作。但如果使用不当,会给程序的性能带来影响。如下面的语句:
String name=new String("HuangWeiFeng");
Systemoutprintln(name+"is my name");
看似已经很精简了,其实并非如此。为了生成二进制的代码,要进行如下的步骤和 *** 作:
(1) 生成新的字符串 new String(STR_1);
(2) 复制该字符串;
(3) 加载字符串常量"HuangWeiFeng"(STR_2);
(4) 调用字符串的构架器(Constructor);
(5) 保存该字符串到数组中(从位置0开始);
(6) 从javaioPrintStream类中得到静态的out变量;
(7) 生成新的字符串缓冲变量new StringBuffer(STR_BUF_1);
(8) 复制该字符串缓冲变量;
(9) 调用字符串缓冲的构架器(Constructor);
(10) 保存该字符串缓冲到数组中(从位置1开始);
(11) 以STR_1为参数,调用字符串缓冲(StringBuffer)类中的append方法;
(12) 加载字符串常量"is my name"(STR_3);
(13) 以STR_3为参数,调用字符串缓冲(StringBuffer)类中的append方法;
(14) 对于STR_BUF_1执行toString命令;
(15) 调用out变量中的println方法,输出结果。
由此可以看出,这两行简单的代码,就生成了STR_1,STR_2,STR_3,STR_4和STR_BUF_1五个对象变量。这些生成的类的实例一般都存放在堆中。堆要对所有类的超类,类的实例进行初始化,同时还要调用类极其每个超类的构架器。而这些 *** 作都是非常消耗系统资源的。因此,对对象的生成进行限制,是完全有必要的。
经修改,上面的代码可以用如下的代码来替换。
StringBuffer name=new StringBuffer("HuangWeiFeng");
Systemoutprintln(nameappend("is my name")toString());
系统将进行如下的 *** 作:
(1) 生成新的字符串缓冲变量new StringBuffer(STR_BUF_1);
(2) 复制该字符串缓冲变量;
(3) 加载字符串常量"HuangWeiFeng"(STR_1);
(4) 调用字符串缓冲的构架器(Constructor);
(5) 保存该字符串缓冲到数组中(从位置1开始);
(6) 从javaioPrintStream类中得到静态的out变量;
(7) 加载STR_BUF_1;
(8) 加载字符串常量"is my name"(STR_2);
(9) 以STR_2为参数,调用字符串缓冲(StringBuffer)实例中的append方法;
(10) 对于STR_BUF_1执行toString命令(STR_3);
(11)调用out变量中的println方法,输出结果。
由此可以看出,经过改进后的代码只生成了四个对象变量:STR_1,STR_2,STR_3和STR_BUF_1你可能觉得少生成一个对象不会对程序的性能有很大的提高。但下面的代码段2的执行速度将是代码段1的2倍。因为代码段1生成了八个对象,而代码段2只生成了四个对象。
代码段1:
String name= new StringBuffer("HuangWeiFeng");
name+="is my";
name+="name";
代码段2:
StringBuffer name=new StringBuffer("HuangWeiFeng");
nameappend("is my");
nameappend("name")toString();
因此,充分的利用JAVA提供的库函数来优化程序,对提高JAVA程序的性能时非常重要的其注意点主要有如下几方面;
(1) 尽可能的使用静态变量(Static Class Variables)
如果类中的变量不会随他的实例而变化,就可以定义为静态变量,从而使他所有的实例都共享这个变量。
例:
public class foo
{
SomeObject so=new SomeObject();
}
就可以定义为:
public class foo
{
static SomeObject so=new SomeObject();
}
(2) 不要对已生成的对象作过多的改变。
对于一些类(如:String类)来讲,宁愿在重新生成一个新的对象实例,而不应该修改已经生成的对象实例。
例:
String name="Huang";
name="Wei";
name="Feng";
上述代码生成了三个String类型的对象实例。而前两个马上就需要系统进行垃圾回收处理。如果要对字符串进行连接的 *** 作,性能将得更差,因为系统将不得为此生成更多得临时变量,如上例1所示。
(3) 生成对象时,要分配给它合理的空间和大小JAVA中的很多类都有它的默认的空间分配大小。对于StringBuffer类来讲,默认的分配空间大小是16个字符。如果在程序中使用StringBuffer的空间大小不是16个字符,那么就必须进行正确的初始化。
(4) 避免生成不太使用或生命周期短的对象或变量。对于这种情况,因该定义一个对象缓冲池。以为管理一个对象缓冲池的开销要比频繁的生成和回收对象的开销小的多。
(5) 只在对象作用范围内进行初始化。JAVA允许在代码的任何地方定义和初始化对象。这样,就可以只在对象作用的范围内进行初始化。从而节约系统的开销。
例:
SomeObject so=new SomeObject();
If(x==1) then
{
Foo=sogetXX();
}
可以修改为:
if(x==1) then
{
SomeObject so=new SomeObject();
Foo=sogetXX();
}
2.异常(Exceptions)
JAVA语言中提供了try/catch来发方便用户捕捉异常,进行异常的处理。但是如果使用不当,也会给JAVA程序的性能带来影响。因此,要注意以下两点:
(1) 避免对应用程序的逻辑使用try/catch
如果可以用if,while等逻辑语句来处理,那么就尽可能的不用try/catch语句。
(2) 重用异常
在必须要进行异常的处理时,要尽可能的重用已经存在的异常对象。以为在异常的处理中,生成一个异常对象要消耗掉大部分的时间。
3 线程(Threading)
一个高性能的应用程序中一般都会用到线程。因为线程能充分利用系统的资源。在其他线程因为等待硬盘或网络读写而 时,程序能继续处理和运行。但是对线程运用不当,也会影响程序的性能。
例2:正确使用Vector类
Vector主要用来保存各种类型的对象(包括相同类型和不同类型的对象)。但是在一些情况下使用会给程序带来性能上的影响。这主要是由Vector类的两个特点所决定的。第一,Vector提供了线程的安全保护功能。即使Vector类中的许多方法同步。但是如果你已经确认你的应用程序是单线程,这些方法的同步就完全不必要了。第二,在Vector查找存储的各种对象时,常常要花很多的时间进行类型的匹配。而当这些对象都是同一类型时,这些匹配就完全不必要了。因此,有必要设计一个单线程的,保存特定类型对象的类或集合来替代Vector类用来替换的程序如下(StringVectorjava):
public class StringVector
{
private String [] data;
private int count;
public StringVector()
{
this(10); // default size is 10
}
public StringVector(int initialSize)
{
data = new String[initialSize];
}
public void add(String str)
{
// ignore null strings
if(str == null) { return; }
ensureCapacity(count + 1);
data[count++] = str;
}
private void ensureCapacity(int minCapacity)
{
int oldCapacity = datalength;
if (minCapacity > oldCapacity)
{
String oldData[] = data;
int newCapacity = oldCapacity 2;
data = new String[newCapacity];
Systemarraycopy(oldData, 0, data, 0, count);
}
}
public void remove(String str)
{
if(str == null) { return; // ignore null str }
for(int i = 0; i < count; i++)
{
// check for a match
if(data[i]equals(str))
{
Systemarraycopy(data,i+1,data,i,count-1); // copy data
// allow previously valid array element be gc'd
data[--count] = null;
return;
}
}
}
public final String getStringAt(int index)
{
if(index < 0) { return null; }
else if(index > count) { return null; // index is > # strings }
else { return data[index]; // index is good }
}
}
因此,代码:
Vector Strings=new Vector();
Stringsadd("One");
Stringsadd("Two");
String Second=(String)StringselementAt(1);
可以用如下的代码替换:
StringVector Strings=new StringVector();
Stringsadd("One");
Stringsadd("Two");
String Second=StringsgetStringAt(1);
这样就可以通过优化线程来提高JAVA程序的性能。用于测试的程序如下(TestCollectionjava):
import javautilVector;
public class TestCollection
{
public static void main(String args [])
{
TestCollection collect = new TestCollection();
if(argslength == 0)
{
Systemoutprintln("Usage: java TestCollection [ vector | stringvector ]");
Systemexit(1);
}
if(args[0]equals("vector"))
{
Vector store = new Vector();
long start = SystemcurrentTimeMillis();
for(int i = 0; i < 1000000; i++)
{
storeaddElement("string");
}
long finish = SystemcurrentTimeMillis();
Systemoutprintln((finish-start));
start = SystemcurrentTimeMillis();
for(int i = 0; i < 1000000; i++)
{
String result = (String)storeelementAt(i);
}
finish = SystemcurrentTimeMillis();
Systemoutprintln((finish-start));
}
else if(args[0]equals("stringvector"))
{
StringVector store = new StringVector();
long start = SystemcurrentTimeMillis();
for(int i = 0; i < 1000000; i++) { storeadd("string"); }
long finish = SystemcurrentTimeMillis();
Systemoutprintln((finish-start));
start = SystemcurrentTimeMillis();
for(int i = 0; i < 1000000; i++) {
String result = storegetStringAt(i);
}
finish = SystemcurrentTimeMillis();
Systemoutprintln((finish-start));
}
}
}
关于线程的 *** 作,要注意如下几个方面:
(1) 防止过多的同步
如上所示,不必要的同步常常会造成程序性能的下降。因此,如果程序是单线程,则一定不要使用同步。
(2) 同步方法而不要同步整个代码段
对某个方法或函数进行同步比对整个代码段进行同步的性能要好。
(3) 对每个对象使用多”锁”的机制来增大并发。
一般每个对象都只有一个”锁”,这就表明如果两个线程执行一个对象的两个不同的同步方法时,会发生”死锁”。即使这两个方法并不共享任何资源。为了避免这个问题,可以对一个对象实行”多锁”的机制。如下所示:
class foo
{
private static int var1;
private static Object lock1=new Object();
private static int var2;
private static Object lock2=new Object();
public static void increment1()
{
synchronized(lock1)
{
var1++;
}
}
public static void increment2()
{
synchronized(lock2)
{
var2++;
}
}
}
4.输入和输出(I/O)
输入和输出包括很多方面,但涉及最多的是对硬盘,网络或数据库的读写 *** 作。对于读写 *** 作,又分为有缓存和没有缓存的;对于数据库的 *** 作,又可以有多种类型的JDBC驱动器可以选择。但无论怎样,都会给程序的性能带来影响。因此,需要注意如下几点:
(1) 使用输入输出缓冲
尽可能的多使用缓存。但如果要经常对缓存进行刷新(flush),则建议不要使用缓存。
(2) 输出流(Output Stream)和Unicode字符串
当时用Output Stream和Unicode字符串时,Write类的开销比较大。因为它要实现Unicode到字节(byte)的转换因此,如果可能的话,在使用Write类之前就实现转换或用OutputStream类代替Writer类来使用。
(3) 当需序列化时使用transient
当序列化一个类或对象时,对于那些原子类型(atomic)或可以重建的原素要表识为transient类型。这样就不用每一次都进行序列化。如果这些序列化的对象要在网络上传输,这一小小的改变对性能会有很大的提高。
(4) 使用高速缓存(Cache)
对于那些经常要使用而又不大变化的对象或数据,可以把它存储在高速缓存中。这样就可以提高访问的速度。这一点对于从数据库中返回的结果集尤其重要。
(5) 使用速度快的JDBC驱动器(Driver)
JAVA对访问数据库提供了四种方法。这其中有两种是JDBC驱动器。一种是用JAVA外包的本地驱动器;另一种是完全的JAVA驱动器。具体要使用哪一种得根据JAVA布署的环境和应用程序本身来定。
5一些其他的经验和技巧
(1) 使用局部变量。
(2) 避免在同一个类中动过调用函数或方法(get或set)来设置或调用变量。
(3) 避免在循环中生成同一个变量或调用同一个函数(参数变量也一样)。
(4) 尽可能的使用static,final,private等关键字。
(5) 当复制大量数据时,使用Systemarraycopy()命令。
以上就是关于oracle里面更新 *** 作能带有四则运算吗全部的内容,包括:oracle里面更新 *** 作能带有四则运算吗、oracle的基础谁能告诉我点、大虾请进:oracle数据库超大数据量的处理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)