2006年02月15日

drscode字段中存储的数据格式为 ‘aaa,bbb,ccc’  现在只想取出drscode中的bbb  下面是使用得sql:


select t.drscode,substr(t.drscode,instr(t.drscode,’,',1)+1,instr(t.drscode,’,',1,2)-instr(t.drscode,’,',1)-1) aaa  from kensa_order t where t.id=’7800220′


instr(string1,string2[,a][,b])
这个是orcale内置SQL函数,返回的是一个数字,表示string1中包含string2的位置,a和b是可选参数,a表示起始位置,当a为负数时表示从右开始查找; b表示string2在string1中出现的次数,也就是第b次出现string2时将位置返回。a和b的缺省值都是1,即返回在string1中第一次出现string2的位置。


substr(string,a [,b])
这个是orcale内置SQL函数,返回的是string的一部分,从字符位置a开始,长为b个字符,当a为负数时表示从右边开始截取。

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年02月13日

lpad格式是 lpad(char1,n,char2)
LPAD returns char1, left-padded to length n with the sequence of characters in char2; char2 defaults to a single blank. If char1 is longer than n, then this function returns the portion of char1 that fits in n.

LPAD (‘55′, 10, ‘0′) ==> ‘0000000055′


 


 

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年11月10日

数据导出:
 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中
   exp system/manager@TEST file=d:\daochu.dmp full=y
 2 将数据库中system用户与sys用户的表导出
   exp system/manager@TEST file=d:\daochu.dmp owner=(system,sys)
 3 将数据库中的表table1 、table2导出
   exp system/manager@TEST file=d:\daochu.dmp tables=(table1,table2) 
 4 将数据库中的表table1中的字段filed1以”00″打头的数据导出
   exp system/manager@TEST file=d:\daochu.dmp tables=(table1) query=\” where filed1 like ‘00%’\”
 
     上面是常用的导出,对于压缩我不太在意,用winzip把dmp文件可以很好的压缩。
                     不过在上面命令后面 加上 compress=y  就可以了

数据的导入
 1 将D:\daochu.dmp 中的数据导入 TEST数据库中。
   imp system/manager@TEST  file=d:\daochu.dmp
   上面可能有点问题,因为有的表已经存在,然后它就报错,对该表就不进行导入。
   在后面加上 ignore=y 就可以了。
 2 将d:\daochu.dmp中的表table1 导入
 imp system/manager@TEST  file=d:\daochu.dmp  tables=(table1) 
 
 基本上上面的导入导出够用了。不少情况我是将表彻底删除,然后导入。


功能:Oracle数据导入导出imp/exp就相当与oracle数据还原与备份。
 大多情况都可以用Oracle数据导入导出完成数据的备份和还原(不会造成数据的丢失)。
 
 Oracle有个好处,虽然你的电脑不是服务器,但是你装了oracle客户端,并建立了连接
 (通过net8 assistant中本地–>服务命名 添加正确的服务命名
 其实你可以想成是客户端与服务器端修了条路,然后数据就可以被拉过来了)
 这样你可以把数据导出到本地,虽然可能服务器离你很远。
 你同样可以把dmp文件从本地导入到远处的数据库服务器中。
 利用这个功能你可以构建俩个相同的数据库,一个用来测试,一个用来正式使用。
 
执行环境:可以在SQLPLUS.EXE或者DOS(命令行)中执行,
 DOS中可以执行时由于 在oracle 8i 中  安装目录\ora81\BIN被设置为全局路径,
 该目录下有EXP.EXE与IMP.EXE文件被用来执行导入导出。
 oracle用java编写,我想SQLPLUS.EXE、EXP.EXE、IMP.EXE这俩个文件是被包装后的类文件。
 SQLPLUS.EXE调用EXP.EXE、IMP.EXE他们所包裹的类,完成导入导出功能。


注意:
 你要有足够的权限,权限不够它会提示你。
 数据库时可以连上的。可以用tnsping TEST 来获得数据库TEST能否连上。


本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年11月04日

简单介绍

在 Oracle 10g 以前的版本,更改表空间名字是几乎不可能的事情,除非删除,重新创建,大费周章。Oracle 10g 新添加了一项更改表空间名字的功能,使得更改表空间名字瞬间即可完成。是个较为人性化的功能。

SQL> COL FILE_NAME format a70
SQL> SET linesize 120
SQL> SET pagesize 99
SQL> COL TABLESPACE_NAME format a10
SQL>
SQL> SELECT file_name, tablespace_name FROM dba_data_files;

FILE_NAME                               TABLESPACE
———————————————————————- ———-
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/users01.dbf      USERS
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/sysaux01.dbf     SYSAUX
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/undotbs01.dbf     UNDOTBS1
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/system01.dbf     SYSTEM
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/example01.dbf     EXAMPLE
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/foo1.dbf       FOO

6 rows selected.

该命令的语法很简单:

ALTER TABLESPACE tablespacename RENAME TO newtablespacename;
tablespacename 和newtablespacename 分别对应原来的表空间名字和更改后的表空间名字:

实战演练

注意:在操作前后都请做好控制文件的备份工作

SQL>ALTER TABLESPACE foo RENAME TO test;

Tablespace altered.

SQL> SELECT file_name, tablespace_name FROM dba_data_files;

FILE_NAME                               TABLESPACE
———————————————————————- ———-
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/users01.dbf      USERS
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/sysaux01.dbf     SYSAUX
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/undotbs01.dbf     UNDOTBS1
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/system01.dbf     SYSTEM
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/example01.dbf     EXAMPLE
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/foo1.dbf       TEST

因为 system 和 sysaux 这两个表空间的特殊性,是不可以更名的:

SQL> ALTER TABLESPACE system RENAME TO mysystem;
ALTER TABLESPACE system RENAME TO mysystem
*
ERROR at line 1:
ORA-00712: cannot rename system tablespace

SQL> ALTER TABLESPACE sysaux RENAME TO mysysaux;
ALTER TABLESPACE sysaux RENAME TO mysysaux
*
ERROR at line 1:
ORA-13502: Cannot rename SYSAUX tablespace
可以对 undo tablespace 重新命名,如果使用的是 spfile ,而不是 pfile, Oracle 会自动对 spfile 中的 undo_tablespace 进行更改(不过要在数据库重新启动之后才可以观察到), 如果使用的是 pfile ,要对其进行手工更改。我们看看 spfile 的变化情况:

SQL> ALTER tablespace undotbs1 RENAME TO undotbs;

Tablespace altered.

SQL>
SQL> show parameter pfile

NAME                 TYPE    VALUE
———————————— ———– ——————————
spfile                string   /u01/app/oracle/product/10.1.0
                         /db_1/dbs/spfileTEST.ora
SQL> show parameters undo

NAME                 TYPE    VALUE
———————————— ———– ——————————
undo_management           string   AUTO
undo_retention            integer   900
undo_tablespace           string   UNDOTBS1
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area 180355072 bytes
Fixed Size          777996 bytes
Variable Size       128983284 bytes
Database Buffers      50331648 bytes
Redo Buffers         262144 bytes
Database mounted.
Database opened.
SQL> show parameters undo

NAME                 TYPE    VALUE
———————————— ———– ——————————
undo_management           string   AUTO
undo_retention            integer   900
undo_tablespace           string   UNDOTBS
SQL>

对脱机表空间的更名是不允许的:

SQL> ALTER TABLESPACE TEST OFFLINE;

Tablespace altered.

SQL> ALTER TABLESPACE test RENAME TO testoffline;
ALTER TABLESPACE test RENAME TO testoffline
*
ERROR at line 1:
ORA-01135: file 6 accessed for DML/query is offline
ORA-01110: data file 6:
‘/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/foo1.dbf’

给出的提示信息很有参考价值:更名操作是要对表空间进行 DML/query 操作的,表空间offline的话,则不可以。

那么如果表空间是只读的会怎么样呢?

SQL> ALTER TABLESPACE TEST ONLINE;

Tablespace altered.

SQL> ALTER TABLESPACE TEST READ ONLY;

Tablespace altered.

SQL> ALTER TABLESPACE test RENAME TO testreadonly;

Tablespace altered.

SQL> list
 1* SELECT file_name, tablespace_name FROM dba_data_files
SQL> /

FILE_NAME                               TABLESPACE
———————————————————————- ———-
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/users01.dbf      USERS
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/sysaux01.dbf     SYSAUX
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/undotbs01.dbf     UNDOTBS
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/system01.dbf     SYSTEM
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/example01.dbf     EXAMPLE
/u01/app/oracle/product/10.1.0/db_1/oradata/TEST/foo1.dbf       TESTREADONLY

6 rows selected.

SQL>

看来数据字典已经更新,不过Oracle会向alert_SID.log 中写入类似如下的日志:

ALTER TABLESPACE test RENAME TO testreadonly
Sat Nov 13 16:15:21 2004
Tablespace ‘TEST’ is renamed to ‘TESTREADONLY’.
Tablespace name change is not propagated to file headersbecause the tablespace is read only.
Completed: ALTER TABLESPACE test RENAME TO testreadonly

注意Log里有个细微的小Bug:headersbecause。这是两个词,应该空开的 :-)

限制条件

应用这个特性有个主要的限制条件:COMPATIBLE 初始化参数要求为 10.0 或者更高才可以

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

  以前在做一个系统时,遇到了一个问题!今天无意之中找到了这个问题的解决方法,贴出来!!!

问题描述:

varchar2(4000) abc;

intert into table_name(abc) values(‘这里有1500个汉字……’);

报错:插入字符过长!经过测试,发现一个汉字占3个字节,所以报错!!!

问题所在:

使用的字符集是UTF8,就有可能出现这个错误!

使用命令查看:

SQL> select * from v$nls_parameters where parameter=’NLS_CHARACTERSET’;

PARAMETER
——————————————————————————–
VALUE
——————————————————————————–
NLS_CHARACTERSET
AL32UTF8

解决方法:

建议使用ZHS16GBK字符集!

操作:

SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE CHARACTER SET AL32UTF8/ZHS16GBK;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;

问题解决!!!


日文同样

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

1.书写格式
  
  示例代码:
  
  存储过程SQL文书写格式例
  select
  c.dealerCode,
  round(sum(c.submitSubletAmountDLR + c.submitPartsAmountDLR + c.submitLaborAmountDLR) / count(*), 2) as avg,
  decode(null, ‘x’, ‘xx’, ‘CNY’)
  from (
  select
  a.dealerCode,
  a.submitSubletAmountDLR,
  a.submitPartsAmountDLR,
  a.submitLaborAmountDLR
  from SRV_TWC_F a
  where (to_char(a.ORIGSUBMITTIME, ‘yyyy/mm/dd’) >= ‘Date Range(start)’
  and to_char(a.ORIGSUBMITTIME, ‘yyyy/mm/dd’) <= ‘Date Range(end)’
  and nvl(a.deleteflag, ‘0′) <> ‘1′)
  union all
  select
  b.dealerCode,
  b.submitSubletAmountDLR,
  b.submitPartsAmountDLR,
  b.submitLaborAmountDLR
  from SRV_TWCHistory_F b
  where (to_char(b.ORIGSUBMITTIME, ‘yyyy/mm/dd’) >= ‘Date Range(start)’
  and to_char(b.ORIGSUBMITTIME,’yyyy/mm/dd’) <= ‘Date Range(end)’
  and nvl(b.deleteflag,’0′) <> ‘1′)
  ) c
  group by c.dealerCode
  order by avg desc;
  
  Java source里的SQL字符串书写格式例
  strSQL = “insert into Snd_FinanceHistory_Tb “
  + “(DEALERCODE, “
  + “REQUESTSEQUECE, “
  + “HANDLETIME, “
  + “JOBFLAG, “
  + “FRAMENO, “
  + “INMONEY, “
  + “REMAINMONEY, “
  + “DELETEFLAG, “
  + “UPDATECOUNT, “
  + “CREUSER, “
  + “CREDATE, “
  + “HONORCHECKNO, “
  + “SEQ) “
  + “values (‘” + draftInputDetail.dealerCode + “‘, “
  + “‘” + draftInputDetail.requestsequece + “‘, “
  + “sysdate, “
  + “‘07′, “
  + “‘” + frameNO + “‘, “
  + requestMoney + “, “
  + remainMoney + “, “
  + “‘0′, “
  + “0, “
  + “‘” + draftStruct.employeeCode + “‘, “
  + “sysdate, “
  + “‘” + draftInputDetail.honorCheckNo + “‘, “
  + index + “)”;
  
  1).缩进
  对于存储过程文件,缩进为8个空格
  对于Java source里的SQL字符串,不可有缩进,即每一行字符串不可以空格开头
  
  2).换行
  1>.Select/From/Where/Order by/Group by等子句必须另其一行写
  2>.Select子句内容如果只有一项,与Select同行写
  3>.Select子句内容如果多于一项,每一项单独占一行,在对应Select的基础上向右缩进8个空格(Java source无缩进)
  4>.From子句内容如果只有一项,与From同行写
  5>.From子句内容如果多于一项,每一项单独占一行,在对应From的基础上向右缩进8个空格(Java source无缩进)
  6>.Where子句的条件如果有多项,每一个条件占一行,以AND开头,且无缩进
  7>.(Update)Set子句内容每一项单独占一行,无缩进
  8>.Insert子句内容每个表字段单独占一行,无缩进;values每一项单独占一行,无缩进
  9>.SQL文中间不允许出现空行
  10>.Java source里单引号必须跟所属的SQL子句处在同一行,连接符(”+”)必须在行首
  
  3).空格
  1>.SQL内算数运算符、逻辑运算符连接的两个元素之间必须用空格分隔
  2>.逗号之后必须接一个空格
  3>.关键字、保留字和左括号之间必须有一个空格
  
  2.不等于统一使用”<>”
  
  Oracle认为”!=”和”<>”是等价的,都代表不等于的意义。为了统一,不等于一律使用”<>”表示
  
  3.使用表的别名
  
  数据库查询,必须使用表的别名
  
  4.SQL文对表字段扩展的兼容性
  
  在Java source里使用Select *时,严禁通过getString(1)的形式得到查询结果,必须使用getString(“字段名”)的形式
  使用Insert时,必须指定插入的字段名,严禁不指定字段名直接插入values
  
  5.减少子查询的使用
  
  子查询除了可读性差之外,还在一定程度上影响了SQL运行效率
  请尽量减少使用子查询的使用,用其他效率更高、可读性更好的方式替代
  
  6.适当添加索引以提高查询效率
  
  适当添加索引可以大幅度的提高检索速度
  请参看ORACLE SQL性能优化系列
  
  7.对数据库表操作的特殊要求
  
  本项目对数据库表的操作还有以下特殊要求:
  
  1).以逻辑删除替代物理删除
  
  注意:现在数据库表中数据没有物理删除,只有逻辑删除
  
  以deleteflag字段作为删除标志,deleteflag=’1′代表此记录被逻辑删除,因此在查询数据时必须考虑deleteflag的因素
  
  deleteflag的标准查询条件:NVL(deleteflag, ‘0′) <> ‘1′
  
  2).增加记录状态字段
  
  数据库中的每张表基本都有以下字段:DELETEFLAG、UPDATECOUNT、CREDATE、CREUSER、UPDATETIME、UPDATEUSER
  
  要注意在对标进行操作时必须考虑以下字段
  
  插入一条记录时要置DELETEFLAG=’0′, UPDATECOUNT=0, CREDATE=sysdate, CREUSER=登录User
  
  查询一条记录时要考虑DELETEFLAG,如果有可能对此记录作更新时还要取得UPDATECOUNT作同步检查
  
  修改一条记录时要置UPDATETIME=sysdate, UPDATEUSER=登录User, UPDATECOUNT=(UPDATECOUNT+1) mod 1000,
  
  删除一条记录时要置DELETEFLAG=’1′
  
  3).历史表
  
  数据库里部分表还存在相应的历史表,比如srv_twc_f和srv_twchistory_f
  
  在查询数据时除了检索所在表之外,还必须检索相应的历史表,对二者的结果做Union(或Union All)
  
  8.用执行计划分析SQL性能
  
  EXPLAIN PLAN是一个很好的分析SQL语句的工具,它可以在不执行SQL的情况下分析语句
  
  通过分析,我们就可以知道ORACLE是怎样连接表,使用什么方式扫描表(索引扫描或全表扫描),以及使用到的索引名称
  
  按照从里到外,从上到下的次序解读分析的结果
  
  EXPLAIN PLAN的分析结果是用缩进的格式排列的,最内部的操作将最先被解读,如果两个操作处于同一层中,带有最小操作号的将首先被执行
  
  目前许多第三方的工具如PLSQL Developer和TOAD等都提供了极其方便的EXPLAIN PLAN工具
  
  PG需要将自己添加的查询SQL文记入log,然后在EXPLAIN PLAN中进行分析,尽量减少全表扫描
  
  ORACLE SQL性能优化系列
  
  1.选择最有效率的表名顺序(只在基于规则的优化器中有效)
  
  ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表driving table)将被最先处理
  
  在FROM子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表
  
  当ORACLE处理多个表时,会运用排序及合并的方式连接它们
  
  首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行排序;
  
  然后扫描第二个表(FROM子句中最后第二个表);
  
  最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并
  
  例如:
  
  表 TAB1 16,384 条记录
  
  表 TAB2 5 条记录
  
  选择TAB2作为基础表 (最好的方法)
  
  select count(*) from tab1,tab2 执行时间0.96秒
  
  选择TAB2作为基础表 (不佳的方法)
  
  select count(*) from tab2,tab1 执行时间26.09秒
  
  如果有3个以上的表连接查询,那就需要选择交叉表(intersection table)作为基础表,交叉表是指那个被其他表所引用的表
  
  例如:
  EMP表描述了LOCATION表和CATEGORY表的交集
  SELECT *
  FROM LOCATION L,
  CATEGORY C,
  EMP E
  WHERE E.EMP_NO BETWEEN 1000 AND 2000
  AND E.CAT_NO = C.CAT_NO
  AND E.LOCN = L.LOCN
  
  将比下列SQL更有效率
  SELECT *
  FROM EMP E ,
  LOCATION L ,
  CATEGORY C
  WHERE E.CAT_NO = C.CAT_NO
  AND E.LOCN = L.LOCN
  AND E.EMP_NO BETWEEN 1000 AND 2000
  
  2.WHERE子句中的连接顺序
  
  ORACLE采用自下而上的顺序解析WHERE子句
  
  根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾
  
  例如:
  (低效,执行时间156.3秒)
  SELECT *
  FROM EMP E
  WHERE SAL > 50000
  AND JOB = ‘MANAGER’
  AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO);
  
  (高效,执行时间10.6秒)
  SELECT *
  FROM EMP E
  WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO)
  AND SAL > 50000
  AND JOB = ‘MANAGER’;
  
  3.SELECT子句中避免使用’*’
  
  当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用’*'是一个方便的方法,不幸的是,这是一个非常低效的方法
  
  实际上,ORACLE在解析的过程中,会将’*'依次转换成所有的列名
  
  这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间
  
  4.减少访问数据库的次数
  
  当执行每条SQL语句时,ORACLE在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量,读数据块等等
  
  由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量
  
  例如:
  
  以下有三种方法可以检索出雇员号等于0342或0291的职员
  
  方法1 (最低效)
  SELECT EMP_NAME, SALARY, GRADE
  FROM EMP
  WHERE EMP_NO = 342;
  
  SELECT EMP_NAME, SALARY, GRADE
  FROM EMP
  WHERE EMP_NO = 291;
  
  方法2 (次低效)
  DECLARE
  CURSOR C1 (E_NO NUMBER) IS
  SELECT EMP_NAME,SALARY,GRADE
  FROM EMP
  WHERE EMP_NO = E_NO;
  BEGIN
  OPEN C1(342);
  FETCH C1 INTO …,…,…;
  …
  OPEN C1(291);
  FETCH C1 INTO …,…,…;
  …
  CLOSE C1;
  END;
  
  方法2 (高效)
  SELECT A.EMP_NAME, A.SALARY, A.GRADE,
  B.EMP_NAME, B.SALARY, B.GRADE
  FROM EMP A, EMP B
  WHERE A.EMP_NO = 342
  AND B.EMP_NO = 291;
  
  5.使用DECODE函数来减少处理时间
  
  使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表
  
  例如:
  SELECT COUNT(*), SUM(SAL)
  FROM EMP
  WHERE DEPT_NO = ‘0020′
  AND ENAME LIKE ‘SMITH%’;
  
  SELECT COUNT(*), SUM(SAL)
  FROM EMP
  WHERE DEPT_NO = ‘0030′
  AND ENAME LIKE ‘SMITH%’;
  
  你可以用DECODE函数高效地得到相同结果
  SELECT COUNT(DECODE(DEPT_NO, ‘0020′, ‘X’, NULL)) D0020_COUNT,
  COUNT(DECODE(DEPT_NO, ‘0030′, ‘X’, NULL)) D0030_COUNT,
  SUM(DECODE(DEPT_NO, ‘0020′, SAL, NULL)) D0020_SAL,
  SUM(DECODE(DEPT_NO, 0030, SAL, NULL)) D0030_SAL
  FROM EMP
  WHERE ENAME LIKE ‘SMITH%’;
  
  ’X'表示任何一个字段
  类似的,DECODE函数也可以运用于GROUP BY和ORDER BY子句中
  
  6.用Where子句替换HAVING子句
  
  避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序、统计等操作
  
  如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销
  
  例如:
  低效
  SELECT REGION, AVG(LOG_SIZE)
  FROM LOCATION
  GROUP BY REGION
  HAVING REGION REGION != ‘SYDNEY’
  AND REGION != ‘PERTH’
  
  高效
  SELECT REGION, AVG(LOG_SIZE)
  FROM LOCATION
  WHERE REGION REGION != ‘SYDNEY’
  AND REGION != ‘PERTH’
  GROUP BY REGION
  
  7.减少对表的查询
  
  在含有子查询的SQL语句中,要特别注意减少对表的查询
  
  例如:
  
  低效
  SELECT TAB_NAME
  FROM TABLES
  WHERE TAB_NAME = (SELECT TAB_NAME
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  AND DB_VER = (SELECT DB_VER
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  
  高效
  SELECT TAB_NAME
  FROM TABLES
  WHERE (TAB_NAME, DB_VER) = (SELECT TAB_NAME, DB_VER
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  
  Update多个Column例子:
  低效
  UPDATE EMP
  SET EMP_CAT = (SELECT MAX(CATEGORY)
  FROM EMP_CATEGORIES),
  SAL_RANGE = (SELECT MAX(SAL_RANGE)
  FROM EMP_CATEGORIES)
  WHERE EMP_DEPT = 0020;
  
  高效
  UPDATE EMP
  SET (EMP_CAT, SAL_RANGE) = (SELECT MAX(CATEGORY), MAX(SAL_RANGE)
  FROM EMP_CATEGORIES)
  WHERE EMP_DEPT = 0020;
  
  8.使用表的别名(Alias)
  
  当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上
  
  这样可以减少解析的时间并减少那些由Column歧义引起的语法错误
  
  9.用EXISTS替代IN
  
  在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接
  
  在这种情况下,使用EXISTS(或NOT EXISTS)通常将提高查询的效率
  
  低效
  SELECT *
  FROM EMP (基础表)
  WHERE EMPNO > 0
  AND DEPTNO IN (SELECT DEPTNO
  FROM DEPT
  WHERE LOC = ‘MELB’)
  
  高效
  SELECT *
  FROM EMP (基础表)
  WHERE EMPNO > 0
  AND EXISTS (SELECT ‘X’
  FROM DEPT
  WHERE DEPT.DEPTNO = EMP.DEPTNO
  AND LOC = ‘MELB’)
  
  10.用NOT EXISTS替代NOT IN
  
  在子查询中,NOT IN子句将执行一个内部的排序和合并
  
  无论在哪种情况下,NOT IN都是最低效的,因为它对子查询中的表执行了一个全表遍历
  
  为了避免使用NOT IN,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS
  
  例如:
  SELECT …
  FROM EMP
  WHERE DEPT_NO NOT IN (SELECT DEPT_NO
  FROM DEPT
  WHERE DEPT_CAT = ‘A’);
  
  为了提高效率改写为
  高效
  SELECT …
  FROM EMP A, DEPT B
  WHERE A.DEPT_NO = B.DEPT(+)
  AND B.DEPT_NO IS NULL
  AND B.DEPT_CAT(+) = ‘A’
  
  最高效
  SELECT …
  FROM EMP E
  WHERE NOT EXISTS (SELECT ‘X’
  FROM DEPT D
  WHERE D.DEPT_NO = E.DEPT_NO
  AND DEPT_CAT = ‘A’);
  
  11.用表连接替换EXISTS
  
  通常来说,采用表连接的方式比EXISTS更有效率
  
  例如:
  SELECT ENAME
  FROM EMP E
  WHERE EXISTS (SELECT ‘X’
  FROM DEPT
  WHERE DEPT_NO = E.DEPT_NO
  AND DEPT_CAT = ‘A’);
  
  更高效
  SELECT ENAME
  FROM DEPT D, EMP E
  WHERE E.DEPT_NO = D.DEPT_NO
  AND DEPT_CAT = ‘A’;
  
  12.用EXISTS替换DISTINCT
  
  当提交一个包含多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT,一般可以考虑用EXIST替换
  
  例如:
  
  低效
  SELECT DISTINCT DEPT_NO, DEPT_NAME
  FROM DEPT D, EMP E
  WHERE D.DEPT_NO = E.DEPT_NO
  
  高效
  SELECT DEPT_NO, DEPT_NAME
  FROM DEPT D
  WHERE EXISTS (SELECT ‘X’
  FROM EMP E
  WHERE E.DEPT_NO = D.DEPT_NO);
  
  EXISTS使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果
  
  13.用索引提高效率
  
  索引是表的一个概念部分,用来提高检索数据的效率。实际上,ORACLE使用了一个复杂的自平衡B-tree结构
  
  通常,通过索引查询数据比全表扫描要快。当ORACLE找出执行查询和Update语句的最佳路径时,ORACLE优化器将使用索引
  
  同样,在联结多个表时使用索引也可以提高效率。另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证
  
  除了那些LONG或LONG RAW数据类型,你可以索引几乎所有的列
  
  通常在大型表中使用索引特别有效,当然,在扫描小表时,使用索引同样能提高效率
  
  虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价
  
  索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改
  
  这意味着每条记录的INSERT、DELETE、UPDATE将为此多付出4、5次的磁盘I/O
  
  因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢
  
  ORACLE对索引有两种访问模式:
  
  1).索引唯一扫描(INDEX UNIQUE SCAN)
  
  大多数情况下, 优化器通过WHERE子句访问INDEX
  
  例如:
  表LODGING有两个索引:建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER
  SELECT *
  FROM LODGING
  WHERE LODGING = ‘ROSE HILL’;
  
  在内部,上述SQL将被分成两步执行:
  
  首先,LODGING_PK索引将通过索引唯一扫描的方式被访问,获得相对应的ROWID;然后通过ROWID访问表的方式执行下一步检索
  
  如果被检索返回的列包括在INDEX列中,ORACLE将不执行第二步的处理(通过ROWID访问表)
  
  因为检索数据保存在索引中,单单访问索引就可以完全满足查询结果
  
  2).索引范围查询(INDEX RANGE SCAN)
  
  适用于两种情况:
  
  1>.基于唯一性索引的一个范围的检索
  
  2>.基于非唯一性索引的检索
  
  例1
  SELECT LODGING
  FROM LODGING
  WHERE LODGING LIKE ‘M%’;
  
  WHERE子句条件包括一系列值,ORACLE将通过索引范围查询的方式查询LODGING_PK
  
  由于索引范围查询将返回一组值,它的效率就要比索引唯一扫描低一些
  
  例2
  SELECT LODGING
  FROM LODGING
  WHERE MANAGER = ‘BILL GATES’;
  
  这个SQL的执行分两步,LODGING$MANAGER的索引范围查询(得到所有符合条件记录的ROWID),通过ROWID访问表得到LODGING列的值
  
  由于LODGING$MANAGER是一个非唯一性的索引,数据库不能对它执行索引唯一扫描
  
  WHERE子句中,如果索引列所对应的值的第一个字符由通配符(WILDCARD)开始,索引将不被采用
  SELECT LODGING
  FROM LODGING
  WHERE MANAGER LIKE ‘%HANMAN’;
  
  在这种情况下,ORACLE将使用全表扫描
  
  14.避免在索引列上使用计算
  
  WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描
  
  例如:
  
  低效
  SELECT …
  FROM DEPT
  WHERE SAL * 12 > 25000;
  
  高效
  SELECT …
  FROM DEPT
  WHERE SAL > 25000/12;
  
  请务必注意,检索中不要对索引列进行处理,如:TRIM,TO_DATE,类型转换等操作,破坏索引,使用全表扫描,影响SQL执行效率
  
  15.避免在索引列上使用IS NULL和IS NOT NULL
  
  避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引
  
  对于单列索引,如果列包含空值,索引中将不存在此记录;
  
  对于复合索引,如果每个列都为空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中
  
  如果唯一性索引建立在表的A列和B列上,并且表中存在一条记录的A,B值为(123,null),
  
  ORACLE将不接受下一条具有相同A,B值(123,null)的记录插入
  
  如果所有的索引列都为空,ORACLE将认为整个键值为空,而空不可能等于空,因此你可以插入1000条具有相同键值的记录,当然它们都是空!
  
  因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引
  
  低效(索引失效)
  SELECT …
  FROM DEPARTMENT
  WHERE DEPT_CODE IS NOT NULL
  
  16.使用UNION-ALL和UNION
  
  当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,然后在输出最终结果前进行排序
  
  如果用UNION ALL替代UNION,这样排序就不是必要了,效率就会因此得到提高
  
  需要注意的是,UNION ALL将重复输出两个结果集合中相同记录,因此还是要从业务需求分析使用UNION ALL的可行性
  
  关于索引下列经验请参考:
  
  1).如果检索数据量超过30%的表中记录数,使用索引将没有显著的效率提高
  
  2).在特定情况下,使用索引也许会比全表扫描慢,但这是同一个数量级上的差距;而通常情况下,使用索引比全表扫描要快几倍乃至几千倍!
  
  其他具体内容请参考《ORACLE SQL性能优化系列》
  
  17.使用PrepareStatement
  
  在同一个方法中,当循环使用SQL文时,为了提高性能,
  
  请使用PreparedStatement。注意,
  
  仅限使用于少数的模块。
  
  方法如下:
  ? PreparedStatement stmt
  = conn.prepareStatement(“select a from TABLE_A where b=? c=?”);
  
  for(?? ){
  ???? stmt.setInt(1, varB);
  ???? stmt.setString(2, varC);
  ?   ResultSet rst = stmt.executeQuery();
  
  }

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

  一.SELECT语句的完整语法为:
  
  SELECT[ALL|DISTINCT|DISTINCTROW|TOP]
  {*|talbe.*|[table.]field1[AS alias1][,[table.]field2[AS alias2][,…]]}
  FROM tableexpression[,…][IN externaldatabase]
  [WHERE…]
  [GROUP BY…]
  [HAVING…]
  [ORDER BY…]
  [WITH OWNERACCESS OPTION]
  
  说明:
  
  用中括号([])括起来的部分表示是可选的,用大括号({})括起来的部分是表示必须从中选择其中的一个。
  
  1 FROM子句
  
  FROM子句指定了SELECT语句中字段的来源。FROM子句后面是包含一个或多个的表达式(由逗号分开),其中的表达式可为单一表名称、已保存的查询或由 INNER JOIN、LEFT JOIN 或 RIGHT JOIN 得到的复合结果。如果表或查询存储在外部数据库,在IN 子句之后指明其完整路径。
  
  例:下列SQL语句返回所有有定单的客户:
  
  SELECT OrderID,Customer.customerID
  FROM Orders Customers
  WHERE Orders.CustomerID=Customers.CustomeersID
  
  2 ALL、DISTINCT、DISTINCTROW、TOP谓词
  
  (1) ALL 返回满足SQL语句条件的所有记录。如果没有指明这个谓词,默认为ALL。
  
  例:SELECT ALL FirstName,LastName
  FROM   Employees
  
  (2) DISTINCT 如果有多个记录的选择字段的数据相同,只返回一个。
  
  (3) DISTINCTROW 如果有重复的记录,只返回一个
  
  (4) TOP显示查询头尾若干记录。也可返回记录的百分比,这是要用 TOP N PERCENT子句(其中N 表示百分比)
  
  例:返回5%定货额最大的定单
  SELECT TOP 5 PERCENT*
  FROM [ Order Details]
  ORDER BY UnitPrice*Quantity*(1-Discount) DESC
  
  3 用 AS 子句为字段取别名
  
  如果想为返回的列取一个新的标题,或者,经过对字段的计算或总结之后,产生了一个新的值,希望把它放到一个新的列里显示,则用AS保留。
  
  例:返回FirstName字段取别名为NickName
  SELECT  FirstName AS NickName ,LastName ,City
  FROM   Employees
  
  例:返回新的一列显示库存价值
  SELECT ProductName ,UnitPrice ,UnitsInStock ,UnitPrice*UnitsInStock AS valueInStock
  FROM  Products
  
  二 .WHERE 子句指定查询条件
  
  1 比较运算符
  
  比较运算符 含义
  = 等于
  > 大于
  < 小于
  >= 大于等于
  <= 小于等于
  <> 不等于
  !> 不大于
  !< 不小于
  
  例:返回96年1月的定单
  
  SELECT OrderID, CustomerID, OrderDate
  FROM Orders
  WHERE OrderDate>#1/1/96# AND OrderDate<#1/30/96#
  
  注意:
  Mcirosoft JET SQL 中,日期用‘#’定界。日期也可以用Datevalue()函数来代替。在比较字符型的数据时,要加上单引号’’,尾空格在比较中被忽略。
  
  例:
  WHERE OrderDate>#96-1-1#
  
  也可以表示为:
  WHERE OrderDate>Datevalue(‘1/1/96’)
  
  使用 NOT 表达式求反。
  
  例:查看96年1月1日以后的定单
  WHERE Not OrderDate<=#1/1/96#
  
  2 范围(BETWEEN 和 NOT BETWEEN)
  
  BETWEEN …AND…运算符指定了要搜索的一个闭区间。
  
  例:返回96年1月到96年2月的定单。
  
  WHERE OrderDate Between #1/1/96# And #2/1/96#
  
  3 列表(IN ,NOT IN)
  
  IN 运算符用来匹配列表中的任何一个值。IN子句可以代替用OR子句连接的一连串的条件。
  
  例:要找出住在 London、Paris或Berlin的所有客户
  
  SELECT CustomerID, CompanyName, ContactName, City
  FROM Customers
  WHERE City In(‘London’,’ Paris’,’ Berlin’)
  
  4 模式匹配(LIKE)
  
  LIKE运算符检验一个包含字符串数据的字段值是否匹配一指定模式。
  
  LIKE运算符里使用的通配符
  
  通配符 含义
  
  ? 任何一个单一的字符
  * 任意长度的字符
  # 0~9之间的单一数字
  [字符列表] 在字符列表里的任一值
  [!字符列表] 不在字符列表里的任一值
  - 指定字符范围,两边的值分别为其上下限
  例:返回邮政编码在(171)555-0000到(171)555-9999之间的客户
  SELECT CustomerID ,CompanyName,City,Phone
  FROM Customers
  WHERE Phone Like ‘(171)555-####’
  LIKE运算符的一些样式及含义
  样式 含义 不符合
  LIKE ‘A*’ A后跟任意长度的字符 Bc,c255
  LIKE’5[*]’ 5*5 555
  LIKE’5?5’ 5与5之间有任意一个字符 55,5wer5
  LIKE’5##5’ 5235,5005 5kd5,5346
  LIKE’[a-z]’ a-z间的任意一个字符 5,%
  LIKE’[!0-9]’ 非0-9间的任意一个字符 0,1
  LIKE’[[]’ 1,*
  
  三 .用ORDER BY子句排序结果
  
  ORDER子句按一个或多个(最多16个)字段排序查询结果,可以是升序(ASC)也可以是降序(DESC),缺省是升序。ORDER子句通常放在SQL语句的最后。
  
  ORDER子句中定义了多个字段,则按照字段的先后顺序排序。
  
  例:
  SELECT ProductName,UnitPrice, UnitInStock
  FROM  Products
  ORDER BY  UnitInStock DESC , UnitPrice DESC, ProductName
  
  ORDER BY 子句中可以用字段在选择列表中的位置号代替字段名,可以混合字段名和位置号。
  
  例:下面的语句产生与上列相同的效果。
  
  SELECT ProductName,UnitPrice, UnitInStock
  FROM  Products
  ORDER BY  1 DESC , 2 DESC,3
  
  四 .运用连接关系实现多表查询
  
  例:找出同一个城市中供应商和客户的名字
  
  SELECT Customers.CompanyName, Suppliers.ComPany.Name
  FROM  Customers, Suppliers
  WHERE Customers.City=Suppliers.City
  
  例:找出产品库存量大于同一种产品的定单的数量的产品和定单
  
  SELECT ProductName,OrderID, UnitInStock, Quantity
  FROM  Products, [Order Deails]
  WHERE Product.productID=[Order Details].ProductID
  AND UnitsInStock>Quantity
  
  另一种方法是用 Microsof JET SQL 独有的 JNNER JOIN
  
  语法:
  
  FROM table1 INNER JOIN table2
  ON   table1.field1 comparision table2.field2
  
  其中comparision 就是前面WHERE子句用到的比较运算符。
  
  SELECT FirstName,lastName,OrderID,CustomerID,OrderDate
  FROM Employees
  INNER JOIN Orders ON Employees.EmployeeID=Orders.EmployeeID
  
  注意:
  
  INNER JOIN不能连接Memo OLE Object Single Double 数据类型字段。
  
  在一个JOIN语句中连接多个ON子句
  
  语法:
  SELECT fields
  FROM table1 INNER JOIN table2
  ON table1.field1 compopr table2.field1 AND
  ON table1.field2 compopr table2.field2 OR
  ON table1.field3 compopr table2.field3
  也可以
  SELECT fields
  FROM table1 INNER JOIN
  (table2 INNER JOIN [( ]table3
  [INNER JOER] [( ]tablex[INNER JOIN]
  ON table1.field1 compopr table2.field1
  ON table1.field2 compopr table2.field2
  ON table1.field3 compopr table2.field3
  
  外部连接返回更多记录,在结果中保留不匹配的记录,不管存不存在满足条件的记录都要返回另一侧的所有记录。
  
  FROM table [LEFT|RIGHT]JOIN table2
  ON table1.field1comparision table.field2
  
  用左连接来建立外部连接,在表达式的左边的表会显示其所有的数据
  
  例:不管有没有定货量,返回所有商品
  
  SELECT   ProductName ,OrderID
  FROM   Products
  LEFT JOIN Orders  ON  Products.PrductsID=Orders.ProductID


  右连接与左连接的差别在于:不管左侧表里有没有匹配的记录,它都从左侧表中返回所有记录。
  
  例:如果想了解客户的信息,并统计各个地区的客户分布,这时可以用一个右连接,即使某个地区没有客户,也要返回客户信息。
  
  空值不会相互匹配,可以通过外连接才能测试被连接的某个表的字段是否有空值。
  
  SELECT *
  FROM talbe1
  LEFT JOIN table2 ON table1.a=table2.c
  
  1 连接查询中使用Iif函数实现以0值显示空值
  
  Iif表达式: Iif(IsNull(Amount,0,Amout)
  
  例:无论定货大于或小于¥50,都要返回一个标志。
  
  Iif([Amount]>50,?Big order?,?Small order?)
  
  五. 分组和总结查询结果
  
  在SQL的语法里,GROUP BY和HAVING子句用来对数据进行汇总。GROUP BY子句指明了按照哪几个字段来分组,而将记录分组后,用HAVING子句过滤这些记录。
  
  GROUP BY 子句的语法
  
  SELECT fidldlist
  FROM table
  WHERE criteria
  [GROUP BY groupfieldlist [HAVING groupcriteria]]
  
  注:Microsoft Jet数据库 Jet 不能对备注或OLE对象字段分组。
  
  GROUP BY字段中的Null值以备分组但是不能被省略。
  
  在任何SQL合计函数中不计算Null值。
  
  GROUP BY子句后最多可以带有十个字段,排序优先级按从左到右的顺序排列。
  
  例:在‘WA’地区的雇员表中按头衔分组后,找出具有同等头衔的雇员数目大于1人的所有头衔。
  
  SELECT Title ,Count(Title) as Total
  FROM Employees
  WHERE Region = ‘WA’
  GROUP BY Title
  HAVING Count(Title)>1
  JET SQL 中的聚积函数
  聚集函数 意义
  SUM ( ) 求和
  AVG ( ) 平均值
  COUNT ( ) 表达式中记录的数目
  COUNT (* ) 计算记录的数目
  MAX 最大值
  MIN 最小值
  VAR 方差
  STDEV 标准误差
  FIRST 第一个值
  LAST 最后一个值
  
  六. 用Parameters声明创建参数查询
  
  Parameters声明的语法:
  
  PARAMETERS name datatype[,name datatype[, …]]
  
  其中name 是参数的标志符,可以通过标志符引用参数.
  
  Datatype说明参数的数据类型.
  
  使用时要把PARAMETERS 声明置于任何其他语句之前.
  
  例:
  PARAMETERS[Low price] Currency,[Beginning date]datatime
  SELECT OrderID ,OrderAmount
  FROM Orders
  WHERE OrderAMount>[low price]
  AND OrderDate>=[Beginning date]
  
  七. 功能查询
  
  所谓功能查询,实际上是一种操作查询,它可以对数据库进行快速高效的操作.它以选择查询为目的,挑选出符合条件的数据,再对数据进行批处理.功能查询包括更新查询,删除查询,添加查询,和生成表查询.
  
  1 更新查询
  
  UPDATE子句可以同时更改一个或多个表中的数据.它也可以同时更改多个字段的值.
  
  更新查询语法:
  
  UPDATE 表名
  SET   新值
  WHERE 准则
  
  例:英国客户的定货量增加5%,货运量增加3%
  
  UPDATE OEDERS
  SET   OrderAmount = OrderAmount *1.1
  Freight = Freight*1.03
  WHERE  ShipCountry = ‘UK’
  
  2 删除查询
  
  DELETE子句可以使用户删除大量的过时的或冗于的数据.
  
  注:删除查询的对象是整个记录.
  
  DELETE子句的语法:
  
  DELETE [表名.*]
  FROM  来源表
  WHERE  准则
  
  例: 要删除所有94年前的定单
  
  DELETE *
  FROM Orders
  WHERE OrderData<#94-1-1#
  
  3 追加查询
  
  INSERT子句可以将一个或一组记录追加到一个或多个表的尾部.
  
  INTO 子句指定接受新记录的表
  
  valueS 关键字指定新记录所包含的数据值.
  
  INSERT 子句的语法:
  
  INSETR INTO 目的表或查询(字段1,字段2,…)
  valueS(数值1,数值2,…)
  
  例:增加一个客户
  INSERT INTO Employees(FirstName,LastName,title)
  valueS(‘Harry’,’Washington’,’Trainee’)
  
  4 生成表查询
  
  可以一次性地把所有满足条件的记录拷贝到一张新表中.通常制作记录的备份或副本或作为报表的基础.
  
  SELECT INTO子句用来创建生成表查询语法:
  SELECT 字段1,字段2,…
  INTO  新表[IN 外部数据库]
  FROM  来源数据库
  WHERE 准则
  
  例:为定单制作一个存档备份
  SELECT *
  INTO  OrdersArchive
  FROM Orders
  
  八. 联合查询
  
  UNION运算可以把多个查询的结果合并到一个结果集里显示.
  
  UNION运算的一般语法:
  
  [表]查询1 UNION [ALL]查询2 UNION …
  
  例:返回巴西所有供给商和客户的名字和城市
  
  SELECT CompanyName,City
  FROM Suppliers
  WHERE Country = ‘Brazil’
  UNION
  SELECT CompanyName,City
  FROM Customers
  WHERE Country = ‘Brazil’
  
  注:
  
  缺省的情况下,UNION子句不返回重复的记录.如果想显示所有记录,可以加ALL选项
  
  UNION运算要求查询具有相同数目的字段.但是,字段数据类型不必相同.
  
  每一个查询参数中可以使用GROUP BY 子句 或 HAVING 子句进行分组.要想以指定的顺序来显示返回的数据,可以在最后一个查询的尾部使用OREER BY子句.
  
  九. 交叉查询
  
  交叉查询可以对数据进行总和,平均,计数或其他总和计算法的计算,这些数据通过两种信息进行分组:一个显示在表的左部,另一个显示在表的顶部.
  
  Microsoft Jet SQL 用TRANSFROM语句创建交叉表查询语法:
  
  TRANSFORM aggfunction
  SELECT 语句
  GROUP BY 子句
  PIVOT pivotfield[IN(value1 [,value2[,…]]) ]
  
  Aggfounction指SQL聚积函数,
  
  SELECT语句选择作为标题的的字段,
  
  GROUP BY 分组
  
  说明:
  
  Pivotfield 在查询结果集中创建列标题时用的字段或表达式,用可选的IN子句限制它的取值.
  
  value代表创建列标题的固定值.
  
  例:显示在1996年里每一季度每一位员工所接的定单的数目:
  
  TRANSFORM Count(OrderID)
  SELECT    FirstName&’’&LastName AS FullName
  FROM    Employees INNER JOIN Orders
  ON      Employees.EmployeeID = Orders.EmployeeID
  WHERE    DatePart(“yyyy”,OrderDate)= ‘1996’
  GROUP BY  FirstName&’’&LastName
  ORDER BY  FirstName&’’&LastName
  POVOT    DatePart(“q”,OrderDate)&’季度’
  
  十 .子查询
  
  子查询可以理解为 套查询.子查询是一个SELECT语句.
  
  1 表达式的值与子查询返回的单一值做比较
  
  语法:
  
  表达式 comparision [ANY|ALL|SOME](子查询)
  
  说明:
  
  ANY和SOME谓词是同义词,与比较运算符(=,<,>,<>,<=,>=)一起使用.返回一个布尔值True或False.ANY的意思是,表达式与子查询返回的一系列的值逐一比较,只要其中的一次比较产生True结果,ANY测试的返回 True值(既WHERE子句的结果),对应于该表达式的当前记录将进入主查询的结果中.ALL测试则要求表达式与子查询返回的一系列的值的比较都产生True结果,才回返回True值.
  
  例:主查询返回单价比任何一个折扣大于等于25%的产品的单价要高的所有产品
  
  SELECT * FROM Products
  WHERE UnitPrice>ANY
  (SELECT UnitPrice FROM[Order Details] WHERE Discount>0.25)
  
  2 检查表达式的值是否匹配子查询返回的一组值的某个值
  
  语法:
  
  [NOT]IN(子查询)
  
  例:返回库存价值大于等于1000的产品.
  
  SELECT ProductName FROM Products
  WHERE ProductID IN
  (SELECT PrdoctID FROM [Order DEtails]
  WHERE UnitPrice*Quantity>= 1000)
  
  3检测子查询是否返回任何记录
  
  语法:
  [NOT]EXISTS (子查询)
  
  例:用EXISTS检索英国的客户
  SELECT ComPanyName,ContactName
  FROM Orders
  WHERE EXISTS
  (SELECT *
  FROM Customers
  WHERE Country = ‘UK’ AND
  Customers.CustomerID= Orders.CustomerID)

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年10月20日

Oracle 默认的XML DB把HTTP的默认端口设为8080,这是一个太常用的端口了,很多别的WebServer都会使用这个端口,所以我们需要修改它。方法三种:
1。dbca,选择你的数据库,然后Standard Database Features->Customize->Oracle XML DB option,进入这个画面你应该就知道怎么改了。

2。OEM console,在XML Database 的配置里面修改

3。用oracle提供的包:
– 把HTTP/WEBDAV端口从8080改到8081
SQL> call dbms_xdb.cfg_update(updateXML(dbms_xdb.cfg_get(),
‘/xdbconfig/sysconfig/protocolconfig/httpconfig/http-port/text()’,8081))
/

– 把FTP端口从2100改到2111
SQL> call dbms_xdb.cfg_update(updateXML(dbms_xdb.cfg_get(),
‘/xdbconfig/sysconfig/protocolconfig/ftpconfig/ftp-port/text()’,2111))
/

SQL> commit;

SQL> exec dbms_xdb.cfg_refresh;


– 检查修改是否已经成功
SQL> set long 100000
SQL> set pagesize 1000
SQL> select dbms_xdb.cfg_get from dual;


以下是我使用的方法


SQL> — Change the HTTP/WEBDAV port from 8080 to 8081
  SQL> call dbms_xdb.cfg_update(updateXML(
    2        dbms_xdb.cfg_get()
    3      , ‘/xdbconfig/sysconfig/protocolconfig/httpconfig/http-port/text()’
    4      , 8081))
    5  /

  Call completed.


  SQL> — Change the FTP port from 2100 to 2111
  SQL> call dbms_xdb.cfg_update(updateXML(
    2         dbms_xdb.cfg_get()
    3       , ‘/xdbconfig/sysconfig/protocolconfig/ftpconfig/ftp-port/text()’
    4       , 2111))
    5  /

  Call completed.


  SQL> COMMIT;

  Commit complete.


  SQL> EXEC dbms_xdb.cfg_refresh;

  PL/SQL procedure successfully completed.


  SQL> — Verify the change
  SQL> set long 100000
  SQL> set pagesize 9000
  SQL> SELECT dbms_xdb.cfg_get FROM dual;

CFG_GET
——————————————————————————–
本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年09月01日

–语 句 功 能
–数据操作
SELECT –从数据库表中检索数据行和列
INSERT –向数据库表添加新数据行
DELETE –从数据库表中删除数据行
UPDATE –更新数据库表中的数据
–数据定义
CREATE TABLE –创建一个数据库表
DROP TABLE –从数据库中删除表
ALTER TABLE –修改数据库表结构
CREATE VIEW –创建一个视图
DROP VIEW –从数据库中删除视图
CREATE INDEX –为数据库表创建一个索引
DROP INDEX –从数据库中删除索引
CREATE PROCEDURE –创建一个存储过程
DROP PROCEDURE –从数据库中删除存储过程
CREATE TRIGGER –创建一个触发器
DROP TRIGGER –从数据库中删除触发器
CREATE SCHEMA –向数据库添加一个新模式
DROP SCHEMA –从数据库中删除一个模式
CREATE DOMAIN –创建一个数据值域
ALTER DOMAIN –改变域定义
DROP DOMAIN –从数据库中删除一个域
–数据控制
GRANT –授予用户访问权限
DENY –拒绝用户访问
REVOKE –解除用户访问权限
–事务控制
COMMIT –结束当前事务
ROLLBACK –中止当前事务
SET TRANSACTION –定义当前事务数据访问特征
–程序化SQL
DECLARE –为查询设定游标
EXPLAN –为查询描述数据访问计划
OPEN –检索查询结果打开一个游标
FETCH –检索一行查询结果
CLOSE –关闭游标
PREPARE –为动态执行准备SQL 语句
EXECUTE –动态地执行SQL 语句
DESCRIBE –描述准备好的查询
—局部变量
declare @id char(10)
–set @id = ‘10010001′
select @id = ‘10010001′


—全局变量
—必须以@@开头


–IF ELSE
declare @x int @y int @z int
select @x = 1 @y = 2 @z=3
if @x > @y
print ‘x > y’ –打印字符串’x > y’
else if @y > @z
print ‘y > z’
else print ‘z > y’


–CASE
use pangu
update employee
set e_wage =
case
when job_level = ’1’ then e_wage*1.08
when job_level = ’2’ then e_wage*1.07
when job_level = ’3’ then e_wage*1.06
else e_wage*1.05
end


–WHILE CONTINUE BREAK
declare @x int @y int @c int
select @x = 1 @y=1
while @x < 3
begin
print @x –打印变量x 的值
while @y < 3
begin
select @c = 100*@x + @y
print @c –打印变量c 的值
select @y = @y + 1
end
select @x = @x + 1
select @y = 1
end


–WAITFOR
–例 等待1 小时2 分零3 秒后才执行SELECT 语句
waitfor delay ’01:02:03’
select * from employee
–例 等到晚上11 点零8 分后才执行SELECT 语句
waitfor time ’23:08:00’
select * from employee


***SELECT***


select *(列名) from table_name(表名) where column_name operator value
ex:(宿主)
select * from stock_information where stockid = str(nid)
stockname = ’str_name’
stockname like ‘% find this %’
stockname like ‘[a-zA-Z]%’ ——— ([]指定值的范围)
stockname like ‘[^F-M]%’ ——— (^排除指定范围)
——— 只能在使用like关键字的where子句中使用通配符)
or stockpath = ’stock_path’
or stocknumber < 1000
and stockindex = 24
not stock*** = ‘man’
stocknumber between 20 and 100
stocknumber in(10,20,30)
order by stockid desc(asc) ——— 排序,desc-降序,asc-升序
order by 1,2 ——— by列号
stockname = (select stockname from stock_information where stockid = 4)
——— 子查询
——— 除非能确保内层select只返回一个行的值,
——— 否则应在外层where子句中用一个in限定符
select distinct column_name form table_name ——— distinct指定检索独有的列值,不重复
select stocknumber ,stocknumber + 10 = stocknumber + 10 from table_name
select stockname , stocknumber = count(*) from table_name group by stockname
——— group by 将表按行分组,指定列中有相同的值
having count(*) = 2 ——— having选定指定的组


select *
from table1, table2
where table1.id *= table2.id ——– 左外部连接,table1中有的而table2中没有得以null表示
table1.id =* table2.id ——– 右外部连接


select stockname from table1
union [all] —– union合并查询结果集,all-保留重复行
select stockname from table2


***insert***


insert into table_name (Stock_name,Stock_number) value (xxx,xxxx)
value (select Stockname , Stocknumber from Stock_table2)—value为select语句


***update***


update table_name set Stockname = xxx [where Stockid = 3]
Stockname = default
Stockname = null
Stocknumber = Stockname + 4


***delete***


delete from table_name where Stockid = 3
truncate table_name ———– 删除表中所有行,仍保持表的完整性
drop table table_name ————— 完全删除表


***alter table*** — 修改数据库表结构


alter table database.owner.table_name add column_name char(2) null …..
sp_help table_name —- 显示表已有特征
create table table_name (name char(20), age smallint, lname varchar(30))
insert into table_name select ……… —– 实现删除列的方法(创建新表)
alter table table_name drop constraint Stockname_default —- 删除Stockname的default约束


***function(/*常用函数*/)***


—-统计函数—-
***G –求平均值
COUNT –统计数目
MAX –求最大值
MIN –求最小值
SUM –求和


–***G
use pangu
select avg(e_wage) as dept_avgWage
from employee
group by dept_id


–MAX
–求工资最高的员工姓名
use pangu
select e_name
from employee
where e_wage =
(select max(e_wage)
from employee)


–STDEV()
–STDEV()函数返回表达式中所有数据的标准差


–STDEVP()
–STDEVP()函数返回总体标准差


–VAR()
–VAR()函数返回表达式中所有值的统计变异数


–VARP()
–VARP()函数返回总体变异数


—-算术函数—-


/***三角函数***/
SIN(float_expression) –返回以弧度表示的角的正弦
COS(float_expression) –返回以弧度表示的角的余弦
TAN(float_expression) –返回以弧度表示的角的正切
COT(float_expression) –返回以弧度表示的角的余切
/***反三角函数***/
ASIN(float_expression) –返回正弦是FLOAT 值的以弧度表示的角
ACOS(float_expression) –返回余弦是FLOAT 值的以弧度表示的角
ATAN(float_expression) –返回正切是FLOAT 值的以弧度表示的角
ATAN2(float_expression1,float_expression2)
–返回正切是float_expression1 /float_expres-sion2的以弧度表示的角
DEGREES(numeric_expression)
–把弧度转换为角度返回与表达式相同的数据类型可为
–INTEGER/MONEY/REAL/FLOAT 类型
RADIANS(numeric_expression) –把角度转换为弧度返回与表达式相同的数据类型可为
–INTEGER/MONEY/REAL/FLOAT 类型
EXP(float_expression) –返回表达式的指数值
LOG(float_expression) –返回表达式的自然对数值
LOG10(float_expression)–返回表达式的以10 为底的对数值
SQRT(float_expression) –返回表达式的平方根
/***取近似值函数***/
CEILING(numeric_expression) –返回>=表达式的最小整数返回的数据类型与表达式相同可为
–INTEGER/MONEY/REAL/FLOAT 类型
FLOOR(numeric_expression) –返回<=表达式的最小整数返回的数据类型与表达式相同可为
–INTEGER/MONEY/REAL/FLOAT 类型
ROUND(numeric_expression) –返回以integer_expression 为精度的四舍五入值返回的数据
–类型与表达式相同可为INTEGER/MONEY/REAL/FLOAT 类型
ABS(numeric_expression) –返回表达式的绝对值返回的数据类型与表达式相同可为
–INTEGER/MONEY/REAL/FLOAT 类型
SIGN(numeric_expression) –测试参数的正负号返回0 零值1 正数或-1 负数返回的数据类型
–与表达式相同可为INTEGER/MONEY/REAL/FLOAT 类型
PI() –返回值为π 即3.1415926535897936
RAND([integer_expression]) –用任选的[integer_expression]做种子值得出0-1 间的随机浮点数


—-字符串函数—-
ASCII() –函数返回字符表达式最左端字符的ASCII 码值
CHAR() –函数用于将ASCII 码转换为字符
–如果没有输入0 ~ 255 之间的ASCII 码值CHAR 函数会返回一个NULL 值
LOWER() –函数把字符串全部转换为小写
UPPER() –函数把字符串全部转换为大写
STR() –函数把数值型数据转换为字符型数据
LTRIM() –函数把字符串头部的空格去掉
RTRIM() –函数把字符串尾部的空格去掉
LEFT(),RIGHT(),SUBSTRING() –函数返回部分字符串
CHARINDEX(),PATINDEX() –函数返回字符串中某个指定的子串出现的开始位置
SOUNDEX() –函数返回一个四位字符码
–SOUNDEX函数可用来查找声音相似的字符串但SOUNDEX函数对数字和汉字均只返回0 值
DIFFERENCE() –函数返回由SOUNDEX 函数返回的两个字符表达式的值的差异
–0 两个SOUNDEX 函数返回值的第一个字符不同
–1 两个SOUNDEX 函数返回值的第一个字符相同
–2 两个SOUNDEX 函数返回值的第一二个字符相同
–3 两个SOUNDEX 函数返回值的第一二三个字符相同
–4 两个SOUNDEX 函数返回值完全相同


QUOTENAME() –函数返回被特定字符括起来的字符串
/*select quotename(‘abc’, ‘{‘) quotename(‘abc’)
运行结果如下
———————————-{
{abc} [abc]*/


REPLICATE() –函数返回一个重复character_expression 指定次数的字符串
/*select replicate(‘abc’, 3) replicate( ‘abc’, -2)
运行结果如下
———– ———–
abcabcabc NULL*/


REVERSE() –函数将指定的字符串的字符排列顺序颠倒
REPLACE() –函数返回被替换了指定子串的字符串
/*select replace(‘abc123g’, ‘123′, ‘def’)
运行结果如下
———– ———–
abcdefg*/


SPACE() –函数返回一个有指定长度的空白字符串
STUFF() –函数用另一子串替换字符串指定位置长度的子串


—-数据类型转换函数—-
CAST() 函数语法如下
CAST() ( AS [ length ])
CONVERT() 函数语法如下
CONVERT() ([ length ], [, style])


select cast(100+99 as char) convert(varchar(12), getdate())
运行结果如下
—————————— ————
199 Jan 15 2000


—-日期函数—-
DAY() –函数返回date_expression 中的日期值
MONTH() –函数返回date_expression 中的月份值
YEAR() –函数返回date_expression 中的年份值
DATEADD( , ,)
–函数返回指定日期date 加上指定的额外日期间隔number 产生的新日期
DATEDIFF( , ,)
–函数返回两个指定日期在datepart 方面的不同之处
DATENAME( , ) –函数以字符串的形式返回日期的指定部分
DATEPART( , ) –函数以整数值的形式返回日期的指定部分
GETDATE() –函数以DATETIME 的缺省格式返回系统当前的日期和时间


—-系统函数—-
APP_NAME() –函数返回当前执行的应用程序的名称
COALESCE() –函数返回众多表达式中第一个非NULL 表达式的值
COL_LENGTH(<’table_name’>, <’column_name’>) –函数返回表中指定字段的长度值
COL_NAME(, ) –函数返回表中指定字段的名称即列名
DATALENGTH() –函数返回数据表达式的数据的实际长度
DB_ID(['database_name']) –函数返回数据库的编号
DB_NAME(database_id) –函数返回数据库的名称
HOST_ID() –函数返回服务器端计算机的名称
HOST_NAME() –函数返回服务器端计算机的名称
IDENTITY([, seed increment]) [AS column_name])
–IDENTITY() 函数只在SELECT INTO 语句中使用用于插入一个identity column列到新表中
/*select identity(int, 1, 1) as column_name
into newtable
from oldtable*/
ISDATE() –函数判断所给定的表达式是否为合理日期
ISNULL(, ) –函数将表达式中的NULL 值用指定值替换
ISNUMERIC() –函数判断所给定的表达式是否为合理的数值
NEWID() –函数返回一个UNIQUEIDENTIFIER 类型的数值
NULLIF(, )
–NULLIF 函数在expression1 与expression2 相等时返回NULL 值若不相等时则返回expression1 的值


sql中的保留字


action add aggregate all
alter after and as
asc avg avg_row_length auto_increment
between bigint bit binary
blob bool both by
cascade case char character
change check checksum column
columns comment constraint create
cross current_date current_time current_timestamp
data database databases date
datetime day day_hour day_minute
day_second dayofmonth dayofweek dayofyear
dec decimal default delayed
delay_key_write delete desc describe
distinct distinctrow double drop
end else escape escaped
enclosed enum explain exists
fields file first float
float4 float8 flush foreign
from for full function
global grant grants group
having heap high_priority hour
hour_minute hour_second hosts identified
ignore in index infile
inner insert insert_id int
integer interval int1 int2
int3 int4 int8 into
if is isam join
key keys kill last_insert_id
leading left length like
lines limit load local
lock logs long longblob
longtext low_priority max max_rows
match mediumblob mediumtext mediumint
middleint min_rows minute minute_second
modify month monthname myisam
natural numeric no not
null on optimize option
optionally or order outer
outfile pack_keys partial password
precision primary procedure process
processlist privileges read real
references reload regexp rename
replace restrict returns revoke
rlike row rows second
select set show shutdown
smallint soname sql_big_tables sql_big_selects
sql_low_priority_updates sql_log_off sql_log_update sql_select_limit
sql_small_result sql_big_result sql_warnings straight_join
starting status string table
tables temporary terminated text
then time timestamp tinyblob
tinytext tinyint trailing to
type use using unique
unlock unsigned update usage
values varchar variables varying
varbinary with write when
where year year_month zerofill

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”