??xml version="1.0" encoding="utf-8" standalone="yes"?>jjzz亚洲亚洲女人,亚洲精品无码AV人在线播放,日韩亚洲翔田千里在线http://www.tkk7.com/jlin/articles/334529.htmlflyflyTue, 12 Oct 2010 03:59:00 GMThttp://www.tkk7.com/jlin/articles/334529.htmlhttp://www.tkk7.com/jlin/comments/334529.htmlhttp://www.tkk7.com/jlin/articles/334529.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/334529.htmlhttp://www.tkk7.com/jlin/services/trackbacks/334529.html  我们要做C但会写SQL,q要做到写出性能优良的SQL,以下为笔者学习、摘录、ƈ汇总部分资料与大家分nQ?
Q?Q?nbsp;     选择最有效率的表名序(只在Z规则的优化器中有?Q?br /> ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名QFROM子句中写在最后的?基础?driving table)被最先处理,在FROM子句中包含多个表的情况下,你必选择记录条数最的表作为基表。如果有3个以上的表连接查? 那就需要选择交叉?intersection table)作ؓ基础? 交叉表是指那个被其他表所引用的表.
Q?Q?nbsp;     WHERE子句中的q接序Q:
ORACLE采用自下而上的顺序解析WHERE子句,Ҏq个原理,表之间的q接必须写在其他WHERE条g之前, 那些可以qo掉最大数量记录的条g必须写在WHERE子句的末?
Q?Q?nbsp;     SELECT子句中避免?‘ * ‘Q?br /> ORACLE在解析的q程? 会将'*' 依次转换成所有的列名, q个工作是通过查询数据字典完成? q意味着耗费更多的时?br /> Q?Q?nbsp;     减少讉K数据库的ơ数Q?br /> ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, l定变量 , L据块{;
Q?Q?nbsp;     在SQL*Plus , SQL*Forms和Pro*C中重新设|ARRAYSIZE参数, 可以增加每次数据库访问的索数据量 ,gؓ200
Q?Q?nbsp;     使用DECODE函数来减处理时_
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的?
Q?Q?nbsp;     整合?无关联的数据库访问:
如果你有几个单的数据库查询语?你可以把它们整合C个查询中(即它们之间没有关系)
Q?Q?nbsp;     删除重复记录Q?br /> 最高效的删除重复记录方?( 因ؓ使用了ROWID)例子Q?br /> DELETE  FROM  EMP E  WHERE  E.ROWID > (SELECT MIN(X.ROWID)
FROM  EMP X  WHERE  X.EMP_NO = E.EMP_NO);
Q?Q?nbsp;     用TRUNCATE替代DELETEQ?br /> 当删除表中的记录?在通常情况? 回滚D?rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状?准确地说是恢复到执行删除命o之前的状? 而当q用TRUNCATE? 回滚D不再存放Q何可被恢复的信息.当命令运行后,数据不能被恢?因此很少的资源被调用,执行旉也会很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
Q?0Q?量多用COMMITQ?br /> 只要有可?在程序中量多用COMMIT, q样E序的性能得到提高,需求也会因为COMMIT所释放的资源而减?
COMMIT所释放的资?
a. 回滚D上用于恢复数据的信?
b. 被程序语句获得的?
c. redo log buffer 中的I间
d. ORACLE为管理上q?U资源中的内部花?br /> Q?1Q?用Where子句替换HAVING子句Q?br /> 避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集q行qo. q个处理需要排?总计{操? 如果能通过WHERE子句限制记录的数?那就能减这斚w的开销. (非oracle?on、where、havingq三个都可以加条件的子句中,on是最先执行,whereơ之Qhaving最后,因ؓon是先把不W合条g的记录过滤后才进行统计,它就可以减少中间q算要处理的数据Q按理说应该速度是最快的Qwhere也应该比having快点的,因ؓ它过滤数据后才进行sumQ在两个表联接时才用on的,所以在一个表的时候,剩下where跟having比较了。在q单表查询统计的情况下,如果要过滤的条g没有涉及到要计算字段Q那它们的结果是一LQ只是where可以使用rushmore技术,而having׃能,在速度上后者要慢如果要涉及到计的字段Q就表示在没计算之前Q这个字D늚值是不确定的Q根据上写的工作流E,where的作用时间是在计之前就完成的,而having是在计后才v作用的,所以在q种情况下,两者的l果会不同。在多表联接查询Ӟon比where更早起作用。系l首先根据各个表之间的联接条Ӟ把多个表合成一个时表后,再由whereq行qoQ然后再计算Q计完后再由havingq行qo。由此可见,要想qo条g起到正确的作用,首先要明白这个条件应该在什么时候v作用Q然后再军_攑֜那里
Q?2Q?减少对表的查询:
在含有子查询的SQL语句?要特别注意减对表的查询.例子Q?br />      SELECT  TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM  TAB_COLUMNS  WHERE  VERSION = 604)
Q?3Q?通过内部函数提高SQL效率.Q?br /> 复杂的SQL往往牺牲了执行效? 能够掌握上面的运用函数解决问题的Ҏ在实际工作中是非常有意义?br /> Q?4Q?使用表的别名(Alias)Q?br /> 当在SQL语句中连接多个表? 请用表的别名ƈ把别名前~于每个Column?q样一?可以减解析的旉q减那些由Column歧义引v的语法错?
Q?5Q?用EXISTS替代IN、用NOT EXISTS替代NOT INQ?br /> 在许多基于基表的查询?Z满一个条?往往需要对另一个表q行联接.在这U情况下, 使用EXISTS(或NOT EXISTS)通常提高查询的效率. 在子查询?NOT IN子句执行一个内部的排序和合q? 无论在哪U情况下,NOT IN都是最低效?(因ؓ它对子查询中的表执行了一个全表遍?. Z避免使用NOT IN ,我们可以把它改写成外q接(Outer Joins)或NOT EXISTS.
例子Q?br /> Q高效)SELECT * FROM  EMP (基础?  WHERE  EMPNO > 0  AND  EXISTS (SELECT ‘X'  FROM DEPT  WHERE  DEPT.DEPTNO = EMP.DEPTNO  AND  LOC = ‘MELB')
(低效)SELECT  * FROM  EMP (基础?  WHERE  EMPNO > 0  AND  DEPTNO IN(SELECT DEPTNO  FROM  DEPT  WHERE  LOC = ‘MELB')
Q?6Q?识别'低效执行'的SQL语句Q?br /> 虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始l是一个最好的ҎQ?br /> SELECT  EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM  V$SQLAREA
WHERE  EXECUTIONS>0
AND  BUFFER_GETS > 0
AND  (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY  4 DESC;
Q?7Q?用烦引提高效率:
索引是表的一个概念部?用来提高索数据的效率QORACLE使用了一个复杂的自^衡B-treel构. 通常,通过索引查询数据比全表扫描要? 当ORACLE扑և执行查询和Update语句的最佌\径时, ORACLE优化器将使用索引. 同样在联l多个表时用烦引也可以提高效率. 另一个用烦引的好处?它提供了主键(primary key)的唯一性验?。那些LONG或LONG RAW数据cd, 你可以烦引几乎所有的? 通常, 在大型表中用烦引特别有? 当然,你也会发? 在扫描小表时,使用索引同样能提高效? 虽然使用索引能得到查询效率的提高,但是我们也必L意到它的代h. 索引需要空间来存储,也需要定期维? 每当有记录在表中增减或烦引列被修Ҏ, 索引本n也会被修? q意味着每条记录的INSERT , DELETE , UPDATEؓ此多付出4 , 5 ơ的盘I/O . 因ؓ索引需要额外的存储I间和处?那些不必要的索引反而会使查询反应时间变?。定期的重构索引是有必要?Q?br /> ALTER  INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
Q?8Q?用EXISTS替换DISTINCTQ?br /> 当提交一个包含一对多表信?比如部门表和雇员?的查询时,避免在SELECT子句中用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更?因ؓRDBMS核心模块在子查询的条g一旦满_,立刻q回l果. 例子Q?br />        (低效):
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);
Q?9Q?sql语句用大写的Q因为oracleL先解析sql语句Q把写的字母{换成大写的再执行
Q?0Q?在java代码中尽量少用连接符“Q?#8221;q接字符Ԍ
Q?1Q?避免在烦引列上用NOT 通常Q 
我们要避免在索引列上使用NOT, NOT会生在和在索引列上使用函数相同的媄? 当ORACLE”遇到”NOT,他就会停止用烦引{而执行全表扫?
Q?2Q?避免在烦引列上用计.
WHERE子句中,如果索引列是函数的一部分Q优化器不使用索引而用全表扫描.
举例:
低效Q?
SELECT … FROM  DEPT  WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
Q?3Q??gt;=替代>
高效:
SELECT * FROM  EMP  WHERE  DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMS直接蟩到第一个DEPT{于4的记录而后者将首先定位到DEPTNO=3的记录ƈ且向前扫描到W一个DEPT大于3的记?
Q?4Q?用UNION替换OR (适用于烦引列)
通常情况? 用UNION替换WHERE子句中的OR会起到较好的效? 对烦引列使用OR造成全表扫描. 注意, 以上规则只针对多个烦引列有效. 如果有column没有被烦? 查询效率可能会因Z没有选择OR而降? 在下面的例子? LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你坚持要用OR, 那就需要返回记录最的索引列写在最前面.
Q?5Q?用IN来替换OR 
q是一条简单易记的规则Q但是实际的执行效果q须验,在ORACLE8i下,两者的执行路径g是相同的Q 
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT… FROM LOCATION WHERE LOC_IN  IN (10,20,30);
Q?6Q?避免在烦引列上用IS NULL和IS NOT NULL
避免在烦引中使用M可以为空的列QORACLE无法用该索引Q对于单列烦引,如果列包含空|索引中将不存在此记录. 对于复合索引Q如果每个列都ؓI,索引中同样不存在此记? 如果臛_有一个列不ؓI,则记录存在于索引中.举例: 如果唯一性烦引徏立在表的A列和B列上, q且表中存在一条记录的A,Bgؓ(123,null) , ORACLE不接受下一条具有相同A,B|123,nullQ的记录(插入). 然而如果所有的索引列都为空QORACLE认为整个键gؓI空不等于空. 因此你可以插?000 条具有相同键值的记录,当然它们都是I? 因ؓIg存在于烦引列?所以WHERE子句中对索引列进行空值比较将使ORACLE停用该烦?
低效: (索引失效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE >=0;
Q?7Q?L使用索引的第一个列Q?br /> 如果索引是徏立在多个列上, 只有在它的第一个列(leading column)被where子句引用?优化器才会选择使用该烦? q也是一条简单而重要的规则Q当仅引用烦引的W二个列?优化器用了全表扫描而忽略了索引
Q?8Q?用UNION-ALL 替换UNION ( 如果有可能的?Q?br /> 当SQL语句需要UNION两个查询l果集合?q两个结果集合会以UNION-ALL的方式被合ƈ, 然后在输出最l结果前q行排序. 如果用UNION ALL替代UNION, q样排序׃是必要了. 效率׃因此得到提高. 需要注意的是,UNION ALL 重复输Z个结果集合中相同记录. 因此各位q是要从业务需求分析用UNION ALL的可行? UNION 对l果集合排序,q个操作会用到SORT_AREA_SIZEq块内存. 对于q块内存的优化也是相当重要的. 下面的SQL可以用来查询排序的消耗量
低效Q?
SELECT  ACCT_NUM, BALANCE_AMT
FROM  DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
高效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
Q?9Q?用WHERE替代ORDER BYQ?br /> ORDER BY 子句只在两种严格的条件下使用索引.
ORDER BY中所有的列必d含在相同的烦引中q保持在索引中的排列序.
ORDER BY中所有的列必d义ؓ非空.
WHERE子句使用的烦引和ORDER BY子句中所使用的烦引不能ƈ?
例如:
表DEPT包含以下?
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效: (索引不被使用)
SELECT DEPT_CODE FROM  DEPT  ORDER BY  DEPT_TYPE
高效: (使用索引)
SELECT DEPT_CODE  FROM  DEPT  WHERE  DEPT_TYPE > 0
Q?0Q?避免改变索引列的cd.:
当比较不同数据类型的数据? ORACLE自动对列q行单的cd转换.
假设 EMPNO是一个数值类型的索引?
SELECT …  FROM EMP  WHERE  EMPNO = ‘123'
实际?l过ORACLEcd转换, 语句转化?
SELECT …  FROM EMP  WHERE  EMPNO = TO_NUMBER(‘123')
q运的是,cd转换没有发生在烦引列?索引的用途没有被改变.
现在,假设EMP_TYPE是一个字W类型的索引?
SELECT …  FROM EMP  WHERE EMP_TYPE = 123
q个语句被ORACLE转换?
SELECT …  FROM EMP  WHERETO_NUMBER(EMP_TYPE)=123
因ؓ内部发生的类型{? q个索引不会被用到! Z避免ORACLE对你的SQLq行隐式的类型{? 最好把cd转换用显式表现出? 注意当字W和数值比较时, ORACLE会优先{换数值类型到字符cd
Q?1Q?需要当心的WHERE子句:
某些SELECT 语句中的WHERE子句不用烦? q里有一些例?
在下面的例子? (1)‘!=' 不使用索引. C, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表? (2) ‘||'是字W连接函? p其他函数那样, 停用了烦? (3) ‘+'是数学函? p其他数学函数那样, 停用了烦? (4)相同的烦引列不能互相比较,q将会启用全表扫?
Q?2Q?a. 如果索数据量过30%的表中记录数.使用索引没有显著的效率提高.
b. 在特定情况下, 使用索引也许会比全表扫描? 但这是同一个数量上的区别. 而通常情况?使用索引比全表扫描要块几倍乃臛_千?
Q?3Q?避免使用耗费资源的操?
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎
执行耗费资源的排?SORT)功能. DISTINCT需要一ơ排序操? 而其他的臛_需要执行两ơ排? 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑? 毕竟它们的可L很?br /> Q?4Q?优化GROUP BY:
提高GROUP BY 语句的效? 可以通过不需要的记录在GROUP BY 之前qo?下面两个查询q回相同l果但第二个明显快了许?
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
GROUP JOB


本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/fuwei2241/archive/2006/09/06/1185198.aspx



fly 2010-10-12 11:59 发表评论
]]>
Oracle中的BLOB和CLOBdhttp://www.tkk7.com/jlin/articles/328130.htmlflyflyFri, 06 Aug 2010 06:20:00 GMThttp://www.tkk7.com/jlin/articles/328130.htmlhttp://www.tkk7.com/jlin/comments/328130.htmlhttp://www.tkk7.com/jlin/articles/328130.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/328130.htmlhttp://www.tkk7.com/jlin/services/trackbacks/328130.html一、区别和定义

      LONG: 可变长的字符?/font>数据Q最?GQLONGhVARCHAR2列的Ҏ,可以存储长文本一个表中最多一个LONG?br />   LONG RAW: 可变?font color="#993300">二进?/font>数据Q最?G
  CLOB:  字符大对?font size="+0">Clob
用来存储单字节的字符数据
  NCLOB: 用来存储多字节的字符数据
  BLOB: 用于存储二进?/font>数据
  BFILE: 存储在文件中?font color="#993300">二进?/font>数据Q这个文件中的数据只能被只读ѝ但该文件不包含在数据库内?/font>

        bfile字段实际的文件存储在文gpȝ?字段中存储的是文件定位指?bfile对oracle来说是只ȝ,也不参与事务性控制和数据恢复.
  
  CLOBQNCLOBQBLOB都是内部?font color="#993300">LOB(Large Object)
cdQ最?GQ没有LONG只能有一列的限制

  要保存图片、文本文件、Word文g各自最好用哪种数据cd?
  --BLOB最好,LONG RAW也不错,但Long是oracle要废弃的类型,因此用BLOB?/font>

二、操?

1?get

CLOB

 

java 代码
  1. //获得数据库连?  
  2.     Connection con = ConnectionFactory.getConnection();   
  3.     con.setAutoCommit(false);   
  4.     Statement st = con.createStatement();   
  5.     //不需?#8220;for update”   
  6.     ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1");   
  7.     if (rs.next())   
  8.     {   
  9.         java.sql.Clob clob = rs.getClob("CLOBATTR");   
  10.         Reader inStream = clob.getCharacterStream();   
  11.         char[] c = new char[(int) clob.length()];   
  12.         inStream.read(c);   
  13.         //data是读出ƈ需要返回的数据Q类型是String   
  14.         data = new String(c);   
  15.         inStream.close();   
  16.     }   
  17.     inStream.close();   
  18.     con.commit();   
  19.     con.close();   
  20.    

 

BLOB
java 代码
  1. //获得数据库连?  
  2.     Connection con = ConnectionFactory.getConnection();   
  3.     con.setAutoCommit(false);   
  4.     Statement st = con.createStatement();   
  5.     //不需?#8220;for update”   
  6.     ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1");   
  7.     if (rs.next())   
  8.     {   
  9.         java.sql.Blob blob = rs.getBlob("BLOBATTR");   
  10.         InputStream inStream = blob.getBinaryStream();   
  11.         //data是读出ƈ需要返回的数据Q类型是byte[]   
  12.         data = new byte[input.available()];   
  13.         inStream.read(data);   
  14.         inStream.close();   
  15.     }   
  16.     inStream.close();   
  17.     con.commit();   
  18.     con.close();   

 

2?put

CLOB
java 代码
  1. //获得数据库连?  
  2.     Connection con = ConnectionFactory.getConnection();   
  3.     con.setAutoCommit(false);   
  4.     Statement st = con.createStatement();   
  5.     //插入一个空对象empty_clob()   
  6.     st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");   
  7.     //锁定数据行进行更斎ͼ注意“for update”语句   
  8.     ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");   
  9.     if (rs.next())   
  10.     {   
  11.         //得到java.sql.Clob对象后强制{换ؓoracle.sql.CLOB   
  12.         oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBATTR");   
  13.         Writer outStream = clob.getCharacterOutputStream();   
  14.         //data是传入的字符Ԍ定义QString data   
  15.         char[] c = data.toCharArray();   
  16.         outStream.write(c, 0, c.length);   
  17.     }   
  18.     outStream.flush();   
  19.     outStream.close();   
  20.     con.commit();   
  21.     con.close();   
  22.   
BLOB
java 代码
  1. //获得数据库连?  
  2.     Connection con = ConnectionFactory.getConnection();   
  3.     con.setAutoCommit(false);   
  4.     Statement st = con.createStatement();   
  5.     //插入一个空对象empty_blob()   
  6.     st.executeUpdate("insert into TESTBLOB (ID, NAME, BLOBATTR) values (1, "thename", empty_blob())");   
  7.     //锁定数据行进行更斎ͼ注意“for update”语句   
  8.     ResultSet rs = st.executeQuery("select BLOBATTR from TESTBLOB where ID=1 for update");   
  9.     if (rs.next())   
  10.     {   
  11.         //得到java.sql.Blob对象后强制{换ؓoracle.sql.BLOB   
  12.         oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBATTR");   
  13.         OutputStream outStream = blob.getBinaryOutputStream();   
  14.         //data是传入的byte数组Q定义:byte[] data   
  15.         outStream.write(data, 0, data.length);   
  16.     }   
  17.     outStream.flush();   
  18.     outStream.close();   
  19.     con.commit();   
  20.     con.close();


fly 2010-08-06 14:20 发表评论
]]>
jdbc事务处理机制(?http://www.tkk7.com/jlin/articles/323881.htmlflyflySat, 19 Jun 2010 13:07:00 GMThttp://www.tkk7.com/jlin/articles/323881.htmlhttp://www.tkk7.com/jlin/comments/323881.htmlhttp://www.tkk7.com/jlin/articles/323881.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/323881.htmlhttp://www.tkk7.com/jlin/services/trackbacks/323881.html  事务处理

  信息是Q何企事业单位的重要资产,M企业部门都包含着信息的流入、流出,M企业部门都控制着某些信息。同Ӟ信息必须在适当的时Z播给需要的人。而且Q信息还需要安全约束,通常Ҏ信息的类型和内容实施讉K控制。ؓ了保证数据的安全有效和正可靠,数据库管理系l(DBMSQ必L供统一的数据保护功能?

  事务是现代数据库理论中的核心概念之一。如果一l处理步骤或者全部发生或者一步也不执行,我们U该l处理步骤ؓ一个事务。当所有的步骤像一个操作一栯完整地执行,我们U该事务被提交。由于其中的一部分或多步执行失败,D没有步骤被提交,则事务必d滚(回到最初的pȝ状态)。事务必L从ISO/IEC所制定的ACID原则。ACID是原子性(atomicityQ、一致性(consistencyQ、隔L(isolationQ和持久性(durabilityQ的~写。事务的原子性表CZ务执行过E中的Q何失败都导致事务所做的M修改失效。一致性表C当事务执行p|Ӟ所有被该事务媄响的数据都应该恢复到事务执行前的状态。隔L表C在事务执行q程中对数据的修改,在事务提交之前对其他事务不可见。持久性表C已提交的数据在事务执行p|Ӟ数据的状态都应该正确?

  在下面我们列举一个用SQL Server数据库进行事务处理的例子。主表是一个规章制度信息表QbylawQ,主要字段有记录编受标题、作者、书写日期等。两个子表分别是附g表(bylaw_affixQ和文本信息表(bylaw_contentQ。表l构见图1所C。bylaw表的记录~号与bylaw_affix表的记录~号、bylaw_content表的记录~号是对应的Q每ơ对规章制度信息的操作也是对这三个表的联合操作。例如要删除规章制度中的一条记录,如果不用事务,可能会出现q样的情况:W一个表中成功删除后Q数据库H然出现意外状况Q而第二、三个表中的操作没有完成Q这P删除操作q没有完成,甚至已经破坏数据库中的数据。要避免q种情况Q就应该使用事务Q它的作用是Q要么三个表都操作成功,要么都失败。换句话_是保持数据的一致性。所以,Z保Ҏ据操作的完整和一_在程序设计时要充分考虑C务处理方面的问题?


? CZ表结?

  Java中的事务处理

  一般情况下QJ2EE应用服务器支持JDBC事务、JTAQJava Transaction APIQ事务、容器管理事务。一般情况下Q最好不要在E序中同时用上qCU事务类型,比如在JTA事务中嵌套JDBC事务。第二方面,事务要在可能短的时间内完成Q不要在不同Ҏ中实C务的使用。下面我们列举两U事务处理方式?

  1、JavaBean中用JDBC方式q行事务处理

  在JDBC中怎样多个SQL语句l合成一个事务呢Q在JDBC中,打开一个连接对象ConnectionӞ~省是auto-commit模式Q每个SQL语句都被当作一个事务,xơ执行一个语句,都会自动的得C务确认。ؓ了能多个SQL语句l合成一个事务,要将auto-commit模式屏蔽掉。在auto-commit模式屏蔽掉之后,如果不调用commit()ҎQSQL语句不会得到事务认。在最q一ơcommit()Ҏ调用之后的所有SQL会在Ҏcommit()调用时得到确认?

public int delete(int sID) {
 dbc = new DataBaseConnection();
 Connection con = dbc.getConnection();
 try {
  con.setAutoCommit(false);// 更改JDBC事务的默认提交方?
  dbc.executeUpdate("delete from bylaw where ID=" + sID);
  dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
  dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
  con.commit();//提交JDBC事务
  con.setAutoCommit(true);// 恢复JDBC事务的默认提交方?
  dbc.close();
  return 1;
 }
 catch (Exception exc) {
  con.rollBack();//回滚JDBC事务
  exc.printStackTrace();
  dbc.close();
  return -1;
 }
}

  2、SessionBean中的JTA事务

  JTA 是事务服务的 J2EE 解决Ҏ。本质上Q它是描qC务接口(比如 UserTransaction 接口Q开发h员直接用该接口或者通过 J2EE 容器使用该接口来保业务逻辑能够可靠地运行)?J2EE 模型的一部分。JTA h的三个主要的接口分别?UserTransaction 接口、TransactionManager 接口?Transaction 接口。这些接口共享公q事务操作Q例?commit() ?rollback()Q?但是也包含特D的事务操作Q例?suspend()Qresume() ?enlist()Q它们只出现在特定的接口上,以便在实C允许一定程度的讉K控制。例如,UserTransaction 能够执行事务划分和基本的事务操作Q?TransactionManager 能够执行上下文管理?

  应用E序可以调用UserTransaction.begin()Ҏ开始一个事务,该事务与应用E序正在其中q行的当前线E相兌。底层的事务理器实际处理线E与事务之间的关联。UserTransaction.commit()Ҏl止与当前线E关联的事务。UserTransaction.rollback()Ҏ放弃与当前U程兌的当前事务?

public int delete(int sID) {
 DataBaseConnection dbc = null;
 dbc = new DataBaseConnection();
 dbc.getConnection();
 UserTransaction transaction = sessionContext.getUserTransaction();//获得JTA事务
 try {
  transaction.begin(); //开始JTA事务
  dbc.executeUpdate("delete from bylaw where ID=" + sID);
  dbc.executeUpdate("delete from bylaw _content where ID=" + sID);
  dbc.executeUpdate("delete from bylaw _affix where bylawid=" + sID);
  transaction.commit(); //提交JTA事务
  dbc.close();
  return 1;
 }
 catch (Exception exc) {
  try {
   transaction.rollback();//JTA事务回滚
  }
  catch (Exception ex) {
   //JTA事务回滚出错处理
   ex.printStackTrace();
  }
  exc.printStackTrace();
  dbc.close();
  return -1;
 }
}
加上的一些心?br /> 1.在数据库中,开启了事物Q如果事物在提交之前发生了错误,如果pȝ回滚了,相应的数据不会提交?br /> 2.如果在事物提交了后发生了异常Q即使在catch块中捕获了异常,pȝ也回滚不了?br /> 3.pȝ在回滚后Q其以后的代码可以l执行?br />

fly 2010-06-19 21:07 发表评论
]]>
oracle SQL性能优化(?http://www.tkk7.com/jlin/articles/322785.htmlflyflyFri, 04 Jun 2010 10:00:00 GMThttp://www.tkk7.com/jlin/articles/322785.htmlhttp://www.tkk7.com/jlin/comments/322785.htmlhttp://www.tkk7.com/jlin/articles/322785.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/322785.htmlhttp://www.tkk7.com/jlin/services/trackbacks/322785.htmloracle SQL性能优化 收藏
        我们要做C但会写SQL,q要做到写出性能优良的SQL,以下为笔者学习、摘录、ƈ汇总部分资料与大家分nQ?
Q?Q?nbsp;     选择最有效率的表名序(只在Z规则的优化器中有?Q?br /> ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名QFROM子句中写在最后的?基础?driving table)被最先处理,在FROM子句中包含多个表的情况下,你必选择记录条数最的表作为基表。如果有3个以上的表连接查? 那就需要选择交叉?intersection table)作ؓ基础? 交叉表是指那个被其他表所引用的表.
Q?Q?nbsp;     WHERE子句中的q接序Q:
ORACLE采用自下而上的顺序解析WHERE子句,Ҏq个原理,表之间的q接必须写在其他WHERE条g之前, 那些可以qo掉最大数量记录的条g必须写在WHERE子句的末?
Q?Q?nbsp;     SELECT子句中避免?‘ * ‘Q?br /> ORACLE在解析的q程? 会将'*' 依次转换成所有的列名, q个工作是通过查询数据字典完成? q意味着耗费更多的时?br /> Q?Q?nbsp;     减少讉K数据库的ơ数Q?br /> ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, l定变量 , L据块{;
Q?Q?nbsp;     在SQL*Plus , SQL*Forms和Pro*C中重新设|ARRAYSIZE参数, 可以增加每次数据库访问的索数据量 ,gؓ200
Q?Q?nbsp;     使用DECODE函数来减处理时_
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的?
Q?Q?nbsp;     整合?无关联的数据库访问:
如果你有几个单的数据库查询语?你可以把它们整合C个查询中(即它们之间没有关系)
Q?Q?nbsp;     删除重复记录Q?br /> 最高效的删除重复记录方?( 因ؓ使用了ROWID)例子Q?br /> DELETE  FROM  EMP E  WHERE  E.ROWID > (SELECT MIN(X.ROWID)
FROM  EMP X  WHERE  X.EMP_NO = E.EMP_NO);
Q?Q?nbsp;     用TRUNCATE替代DELETEQ?br /> 当删除表中的记录?在通常情况? 回滚D?rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状?准确地说是恢复到执行删除命o之前的状? 而当q用TRUNCATE? 回滚D不再存放Q何可被恢复的信息.当命令运行后,数据不能被恢?因此很少的资源被调用,执行旉也会很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
Q?0Q?量多用COMMITQ?br /> 只要有可?在程序中量多用COMMIT, q样E序的性能得到提高,需求也会因为COMMIT所释放的资源而减?
COMMIT所释放的资?
a. 回滚D上用于恢复数据的信?
b. 被程序语句获得的?
c. redo log buffer 中的I间
d. ORACLE为管理上q?U资源中的内部花?br /> Q?1Q?用Where子句替换HAVING子句Q?br /> 避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集q行qo. q个处理需要排?总计{操? 如果能通过WHERE子句限制记录的数?那就能减这斚w的开销. (非oracle?on、where、havingq三个都可以加条件的子句中,on是最先执行,whereơ之Qhaving最后,因ؓon是先把不W合条g的记录过滤后才进行统计,它就可以减少中间q算要处理的数据Q按理说应该速度是最快的Qwhere也应该比having快点的,因ؓ它过滤数据后才进行sumQ在两个表联接时才用on的,所以在一个表的时候,剩下where跟having比较了。在q单表查询统计的情况下,如果要过滤的条g没有涉及到要计算字段Q那它们的结果是一LQ只是where可以使用rushmore技术,而having׃能,在速度上后者要慢如果要涉及到计的字段Q就表示在没计算之前Q这个字D늚值是不确定的Q根据上写的工作流E,where的作用时间是在计之前就完成的,而having是在计后才v作用的,所以在q种情况下,两者的l果会不同。在多表联接查询Ӟon比where更早起作用。系l首先根据各个表之间的联接条Ӟ把多个表合成一个时表后,再由whereq行qoQ然后再计算Q计完后再由havingq行qo。由此可见,要想qo条g起到正确的作用,首先要明白这个条件应该在什么时候v作用Q然后再军_攑֜那里
Q?2Q?减少对表的查询:
在含有子查询的SQL语句?要特别注意减对表的查询.例子Q?br />      SELECT  TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM  TAB_COLUMNS  WHERE  VERSION = 604)
Q?3Q?通过内部函数提高SQL效率.Q?br /> 复杂的SQL往往牺牲了执行效? 能够掌握上面的运用函数解决问题的Ҏ在实际工作中是非常有意义?br /> Q?4Q?使用表的别名(Alias)Q?br /> 当在SQL语句中连接多个表? 请用表的别名ƈ把别名前~于每个Column?q样一?可以减解析的旉q减那些由Column歧义引v的语法错?
Q?5Q?用EXISTS替代IN、用NOT EXISTS替代NOT INQ?br /> 在许多基于基表的查询?Z满一个条?往往需要对另一个表q行联接.在这U情况下, 使用EXISTS(或NOT EXISTS)通常提高查询的效率. 在子查询?NOT IN子句执行一个内部的排序和合q? 无论在哪U情况下,NOT IN都是最低效?(因ؓ它对子查询中的表执行了一个全表遍?. Z避免使用NOT IN ,我们可以把它改写成外q接(Outer Joins)或NOT EXISTS.
例子Q?br /> Q高效)SELECT * FROM  EMP (基础?  WHERE  EMPNO > 0  AND  EXISTS (SELECT ‘X'  FROM DEPT  WHERE  DEPT.DEPTNO = EMP.DEPTNO  AND  LOC = ‘MELB')
(低效)SELECT  * FROM  EMP (基础?  WHERE  EMPNO > 0  AND  DEPTNO IN(SELECT DEPTNO  FROM  DEPT  WHERE  LOC = ‘MELB')
Q?6Q?识别'低效执行'的SQL语句Q?br /> 虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始l是一个最好的ҎQ?br /> SELECT  EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM  V$SQLAREA
WHERE  EXECUTIONS>0
AND  BUFFER_GETS > 0
AND  (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY  4 DESC;
Q?7Q?用烦引提高效率:
索引是表的一个概念部?用来提高索数据的效率QORACLE使用了一个复杂的自^衡B-treel构. 通常,通过索引查询数据比全表扫描要? 当ORACLE扑և执行查询和Update语句的最佌\径时, ORACLE优化器将使用索引. 同样在联l多个表时用烦引也可以提高效率. 另一个用烦引的好处?它提供了主键(primary key)的唯一性验?。那些LONG或LONG RAW数据cd, 你可以烦引几乎所有的? 通常, 在大型表中用烦引特别有? 当然,你也会发? 在扫描小表时,使用索引同样能提高效? 虽然使用索引能得到查询效率的提高,但是我们也必L意到它的代h. 索引需要空间来存储,也需要定期维? 每当有记录在表中增减或烦引列被修Ҏ, 索引本n也会被修? q意味着每条记录的INSERT , DELETE , UPDATEؓ此多付出4 , 5 ơ的盘I/O . 因ؓ索引需要额外的存储I间和处?那些不必要的索引反而会使查询反应时间变?。定期的重构索引是有必要?Q?br /> ALTER  INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
Q?8Q?用EXISTS替换DISTINCTQ?br /> 当提交一个包含一对多表信?比如部门表和雇员?的查询时,避免在SELECT子句中用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更?因ؓRDBMS核心模块在子查询的条g一旦满_,立刻q回l果. 例子Q?br />        (低效):
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);
Q?9Q?sql语句用大写的Q因为oracleL先解析sql语句Q把写的字母{换成大写的再执行
Q?0Q?在java代码中尽量少用连接符“Q?#8221;q接字符Ԍ
Q?1Q?避免在烦引列上用NOT 通常Q 
我们要避免在索引列上使用NOT, NOT会生在和在索引列上使用函数相同的媄? 当ORACLE”遇到”NOT,他就会停止用烦引{而执行全表扫?
Q?2Q?避免在烦引列上用计.
WHERE子句中,如果索引列是函数的一部分Q优化器不使用索引而用全表扫描.
举例:
低效Q?
SELECT … FROM  DEPT  WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
Q?3Q??gt;=替代>
高效:
SELECT * FROM  EMP  WHERE  DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMS直接蟩到第一个DEPT{于4的记录而后者将首先定位到DEPTNO=3的记录ƈ且向前扫描到W一个DEPT大于3的记?
Q?4Q?用UNION替换OR (适用于烦引列)
通常情况? 用UNION替换WHERE子句中的OR会起到较好的效? 对烦引列使用OR造成全表扫描. 注意, 以上规则只针对多个烦引列有效. 如果有column没有被烦? 查询效率可能会因Z没有选择OR而降? 在下面的例子? LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你坚持要用OR, 那就需要返回记录最的索引列写在最前面.
Q?5Q?用IN来替换OR 
q是一条简单易记的规则Q但是实际的执行效果q须验,在ORACLE8i下,两者的执行路径g是相同的Q 
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT… FROM LOCATION WHERE LOC_IN  IN (10,20,30);
Q?6Q?避免在烦引列上用IS NULL和IS NOT NULL
避免在烦引中使用M可以为空的列QORACLE无法用该索引Q对于单列烦引,如果列包含空|索引中将不存在此记录. 对于复合索引Q如果每个列都ؓI,索引中同样不存在此记? 如果臛_有一个列不ؓI,则记录存在于索引中.举例: 如果唯一性烦引徏立在表的A列和B列上, q且表中存在一条记录的A,Bgؓ(123,null) , ORACLE不接受下一条具有相同A,B|123,nullQ的记录(插入). 然而如果所有的索引列都为空QORACLE认为整个键gؓI空不等于空. 因此你可以插?000 条具有相同键值的记录,当然它们都是I? 因ؓIg存在于烦引列?所以WHERE子句中对索引列进行空值比较将使ORACLE停用该烦?
低效: (索引失效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE >=0;
Q?7Q?L使用索引的第一个列Q?br /> 如果索引是徏立在多个列上, 只有在它的第一个列(leading column)被where子句引用?优化器才会选择使用该烦? q也是一条简单而重要的规则Q当仅引用烦引的W二个列?优化器用了全表扫描而忽略了索引
Q?8Q?用UNION-ALL 替换UNION ( 如果有可能的?Q?br /> 当SQL语句需要UNION两个查询l果集合?q两个结果集合会以UNION-ALL的方式被合ƈ, 然后在输出最l结果前q行排序. 如果用UNION ALL替代UNION, q样排序׃是必要了. 效率׃因此得到提高. 需要注意的是,UNION ALL 重复输Z个结果集合中相同记录. 因此各位q是要从业务需求分析用UNION ALL的可行? UNION 对l果集合排序,q个操作会用到SORT_AREA_SIZEq块内存. 对于q块内存的优化也是相当重要的. 下面的SQL可以用来查询排序的消耗量
低效Q?
SELECT  ACCT_NUM, BALANCE_AMT
FROM  DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
高效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
Q?9Q?用WHERE替代ORDER BYQ?br /> ORDER BY 子句只在两种严格的条件下使用索引.
ORDER BY中所有的列必d含在相同的烦引中q保持在索引中的排列序.
ORDER BY中所有的列必d义ؓ非空.
WHERE子句使用的烦引和ORDER BY子句中所使用的烦引不能ƈ?
例如:
表DEPT包含以下?
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效: (索引不被使用)
SELECT DEPT_CODE FROM  DEPT  ORDER BY  DEPT_TYPE
高效: (使用索引)
SELECT DEPT_CODE  FROM  DEPT  WHERE  DEPT_TYPE > 0
Q?0Q?避免改变索引列的cd.:
当比较不同数据类型的数据? ORACLE自动对列q行单的cd转换.
假设 EMPNO是一个数值类型的索引?
SELECT …  FROM EMP  WHERE  EMPNO = ‘123'
实际?l过ORACLEcd转换, 语句转化?
SELECT …  FROM EMP  WHERE  EMPNO = TO_NUMBER(‘123')
q运的是,cd转换没有发生在烦引列?索引的用途没有被改变.
现在,假设EMP_TYPE是一个字W类型的索引?
SELECT …  FROM EMP  WHERE EMP_TYPE = 123
q个语句被ORACLE转换?
SELECT …  FROM EMP  WHERETO_NUMBER(EMP_TYPE)=123
因ؓ内部发生的类型{? q个索引不会被用到! Z避免ORACLE对你的SQLq行隐式的类型{? 最好把cd转换用显式表现出? 注意当字W和数值比较时, ORACLE会优先{换数值类型到字符cd
Q?1Q?需要当心的WHERE子句:
某些SELECT 语句中的WHERE子句不用烦? q里有一些例?
在下面的例子? (1)‘!=' 不使用索引. C, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表? (2) ‘||'是字W连接函? p其他函数那样, 停用了烦? (3) ‘+'是数学函? p其他数学函数那样, 停用了烦? (4)相同的烦引列不能互相比较,q将会启用全表扫?
Q?2Q?a. 如果索数据量过30%的表中记录数.使用索引没有显著的效率提高.
b. 在特定情况下, 使用索引也许会比全表扫描? 但这是同一个数量上的区别. 而通常情况?使用索引比全表扫描要块几倍乃臛_千?
Q?3Q?避免使用耗费资源的操?
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎
执行耗费资源的排?SORT)功能. DISTINCT需要一ơ排序操? 而其他的臛_需要执行两ơ排? 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑? 毕竟它们的可L很?br /> Q?4Q?优化GROUP BY:
提高GROUP BY 语句的效? 可以通过不需要的记录在GROUP BY 之前qo?下面两个查询q回相同l果但第二个明显快了许?
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = ‘PRESIDENT'
OR JOB = ‘MANAGER'
GROUP JOB


本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/fuwei2241/archive/2006/09/06/1185198.aspx



fly 2010-06-04 18:00 发表评论
]]>
oracle procedure问题的解??http://www.tkk7.com/jlin/articles/321376.htmlflyflyWed, 19 May 2010 06:54:00 GMThttp://www.tkk7.com/jlin/articles/321376.htmlhttp://www.tkk7.com/jlin/comments/321376.htmlhttp://www.tkk7.com/jlin/articles/321376.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/321376.htmlhttp://www.tkk7.com/jlin/services/trackbacks/321376.html 可能会导致传入的参数起不了用处。例子如下:
建立一个表:
-- Create table
create table T_TEST12
(
  ID NUMBER,
  NO VARCHAR2(60)
);
往q个表里面插入一些数据,

insert into t_test12 (ID, NO)
values (1, 'lin');

insert into t_test12 (ID, NO)
values (2, '13800162');

insert into t_test12 (ID, NO)
values (3, '13800163');

insert into t_test12 (ID, NO)
values (4, '13800164');

insert into t_test12 (ID, NO)
values (5, '13800165');

insert into t_test12 (ID, NO)
values (6, '13800166');

~写一个删除的存储q程Q?br />  create or replace procedure delete_test(id in number) is  --变量名称id跟数据库的字D一?br /> begin
  delete from t_test12 where id =id;
  commit;
end delete_test;
执行以下操作Q?br /> exec delete_test(1); 执行完后Q发现ƈ不是只删除了id?的数据,
而是把整个表的数据都删除了,如果要想得到相应的结果,则变?br /> 的命名不能跟表的字段名一栗比如如下:
create or replace procedure delete_test(is_del_id in number) is  --变量名称id跟数据库的字D一?br /> begin
  delete from t_test12 where id =is_del_id;
  commit;
end delete_test;




fly 2010-05-19 14:54 发表评论
]]>
java.sql.SQLException: ORA-00911: invalid character 解决Ҏ(?http://www.tkk7.com/jlin/articles/317591.htmlflyflyTue, 06 Apr 2010 13:42:00 GMThttp://www.tkk7.com/jlin/articles/317591.htmlhttp://www.tkk7.com/jlin/comments/317591.htmlhttp://www.tkk7.com/jlin/articles/317591.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/317591.htmlhttp://www.tkk7.com/jlin/services/trackbacks/317591.htmljava.sql.SQLException: ORA-00911: invalid character
2008q?4?5?星期?10:37

控制台抛个异常:java.sql.SQLException: ORA-00911: invalid character
查了一下说是oracle字符集设|的问题。我抛异常的SQL语句在控制台输出如下Q?/p>

select count(t.id) as onerowc,t.id as areatravelid ,b.id as airpotid from base_areatravel t inner join base_airpot b on b.areaid=t.id group by t.id ,b.id;

以上是完完整整的输出l果Q然后我语句复制到PL/SQL中执行是完全可以的,没有M异常的。?/p>

而我在程序中定义的sql如下Q?/p>

String sql="select count(t.id) as onerowc,t.id as areatravelid ,b.id as airpotid from base_areatravel t"+
    " inner join base_airpot b on b.areaid=t.id group by t.id ,b.id;";

呵呵Q花费了半个多小时终于找到原因:Q:Q?/p>

哈哈Q,定义语句中sql后面多了一个分受(“Q?#8221;Q晕菜。。这L话在PL/SQL中是无所谓的Q可是Java 的数据库驱动却不识别q样的语句了。汗Q,Q太大意了。记录下来防止再ơ犯错,呵呵。。?/p>



fly 2010-04-06 21:42 发表评论
]]>
oracle sql in中数据不能超q?000个的解决Ҏ?/title><link>http://www.tkk7.com/jlin/articles/309076.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Mon, 11 Jan 2010 14:48:00 GMT</pubDate><guid>http://www.tkk7.com/jlin/articles/309076.html</guid><wfw:comment>http://www.tkk7.com/jlin/comments/309076.html</wfw:comment><comments>http://www.tkk7.com/jlin/articles/309076.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/jlin/comments/commentRss/309076.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jlin/services/trackbacks/309076.html</trackback:ping><description><![CDATA[在Oracle中,sql中in不能过1000个,比如Qselect  * from table  t where t.id in (1,2,3,......1001,1002)<br /> pȝ报错,解决办法如下Q写成两个或者多个。如Qt.id in (1,2,....1000) or t.id in (1001,1002)<br /> 实现代码如下Q?br />  public String DivString(){<br />   StringBuffer sb = new StringBuffer();<br />   StringBuffer sb2 = new StringBuffer();<br />   List agentList = new ArrayList();<br />   for(int i =0;i<1100;i++)  <br />    agentList.add(i);<br />   for(int i=0;i<agentList.size();i++){<br />    if(i==agentList.size()-1)<br />     sb.append("'").append(agentList.get(i)).append("')");<br />    else if(i%1000==0&&i>0)<br />     sb.append("'").append(agentList.get(i)).append("'")<br />     .append(") or t.id in (");<br />    else<br />     sb.append("'").append(agentList.get(i)).append("',");<br />   }<br />   sb2.append(" t.id  in ('',"+sb);<br />   System.out.println("sql is: "+sb2.toString());<br />   return sb2.toString();<br />  } <img src ="http://www.tkk7.com/jlin/aggbug/309076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jlin/" target="_blank">fly</a> 2010-01-11 22:48 <a href="http://www.tkk7.com/jlin/articles/309076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle用Start with...Connect By子句递归查询 (?http://www.tkk7.com/jlin/articles/300737.htmlflyflyMon, 02 Nov 2009 07:51:00 GMThttp://www.tkk7.com/jlin/articles/300737.htmlhttp://www.tkk7.com/jlin/comments/300737.htmlhttp://www.tkk7.com/jlin/articles/300737.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/300737.htmlhttp://www.tkk7.com/jlin/services/trackbacks/300737.html 
Start with...Connect By子句递归查询一般用于一个表l护树Şl构的应用?/div>
创徏CZ表:
CREATE TABLE TBL_TEST
(
  ID    NUMBER,
  NAME  VARCHAR2(100 BYTE),
  PID   NUMBER                                  DEFAULT 0
);
 
插入试数据Q?/div>
INSERT INTO TBL_TEST(ID,NAME,PID) VALUES('1','10','0');
INSERT INTO TBL_TEST(ID,NAME,PID) VALUES('2','11','1');
INSERT INTO TBL_TEST(ID,NAME,PID) VALUES('3','20','0');
INSERT INTO TBL_TEST(ID,NAME,PID) VALUES('4','12','1');
INSERT INTO TBL_TEST(ID,NAME,PID) VALUES('5','121','2');
 
从Root往树末梢递归
select * from TBL_TEST
 start with id=1
 connect by prior id = pid
 
从末梢往树ROOT递归
select * from TBL_TEST
 start with id=5
 connect by prior pid = id



fly 2009-11-02 15:51 发表评论
]]>oracle Oracle分页查询(?http://www.tkk7.com/jlin/articles/291681.htmlflyflyTue, 18 Aug 2009 10:06:00 GMThttp://www.tkk7.com/jlin/articles/291681.htmlhttp://www.tkk7.com/jlin/comments/291681.htmlhttp://www.tkk7.com/jlin/articles/291681.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/291681.htmlhttp://www.tkk7.com/jlin/services/trackbacks/291681.htmlOracle分页查询

一.引用文章

SELECT /*+ FIRST_ROWS */ * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A --不排?br /> WHERE ROWNUM <= 40
)
WHERE RN >= 21;

SELECT /*+ FIRST_ROWS */ *
FROM (SELECT a.*, row_number() over(ORDER BY 1) rn--假排序,速度同上
FROM t1 a)
WHERE rn BETWEEN 21 AND 40;

SELECT *
FROM (SELECT a.*, row_number() over(ORDER BY c1) rn --真实排序Q无法比较速度
FROM t1 a)
WHERE rn BETWEEN 21 AND 40;

 

Oracle的分|询语句基本上可以按照本文l出的格式来q行套用?br /> 分页查询格式Q?/p>


SELECT * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
WHERE ROWNUM <= 40
)
WHERE RN >= 21

其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻늚原始查询语句。ROWNUM <= 40和RN >= 21控制分页查询的每늚范围?/p>

上面l出的这个分|询语句,在大多数情况拥有较高的效率。分늚目的是控制输出l果集大,结果尽快的q回。在上面的分|询语句中Q这U考虑主要体现在WHERE ROWNUM <= 40q句上?/p>

选择W?1?0条记录存在两U方法,一U是上面例子中展C的在查询的W二层通过ROWNUM <= 40来控制最大|在查询的最外层控制最倹{而另一U方式是L查询W二层的WHERE ROWNUM <= 40语句Q在查询的最外层控制分页的最值和最大倹{这是,查询语句如下Q?/p>

SELECT * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
)
WHERE RN BETWEEN 21 AND 40

Ҏq两U写法,l大多数的情况下Q第一个查询的效率比第二个高得多?/p>

q是׃CBO优化模式下,Oracle可以外层的查询条g推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,W二层的查询条gWHERE ROWNUM <= 40可以被Oracle推入到内层查询中Q这样Oracle查询的结果一旦超q了ROWNUM限制条gQ就l止查询结果返回了?/p>

而第二个查询语句Q由于查询条件BETWEEN 21 AND 40是存在于查询的第三层Q而Oracle无法第三层的查询条件推到最内层Q即使推到最内层也没有意义,因ؓ最内层查询不知道RN代表什么)。因此,对于W二个查询语句,Oracle最内层q回l中间层的是所有满x件的数据Q而中间层q回l最外层的也是所有数据。数据的qo在最外层完成Q显然这个效率要比第一个查询低得多?/p>

上面分析的查询不仅仅是针对单表的单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一h效?/p>

q里׃对包含排序的查询q行说明了,下一文章会通过例子来详l说明。下面简单讨Z下多表联合的情况。对于最常见的等Dq接查询QCBO一般可能会采用两种q接方式NESTED LOOP和HASH JOINQMERGE JOIN效率比HASH JOIN效率低,一般CBO不会考虑Q。在q里Q由于用了分页Q因此指定了一个返回的最大记录数QNESTED LOOP在返回记录数过最大值时可以马上停止q将l果q回l中间层Q而HASH JOIN必须处理完所有结果集QMERGE JOIN也是Q。那么在大部分的情况下,对于分页查询选择NESTED LOOP作ؓ查询的连接方法具有较高的效率Q分|询的时候绝大部分的情况是查询前几页的数据,靠后面的页数访问几率越)?/p>

因此Q如果不介意在系l中使用HINT的话Q可以将分页的查询语句改写ؓQ?/p>

SELECT /*+ FIRST_ROWS */ * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A 
WHERE ROWNUM <= 40
)
WHERE RN >= 21

?我的存储q程

create or replace package  CJ_PageData is

TYPE type_cur IS REF CURSOR;     --建立游标

PROCEDURE CJ_GetDataByPage
(
tblName in  varchar2,       

strGetFields in varchar2,  

fldName in varchar2,        

PageSize in  number,        

PageIndex in  number,           

doCount  in number,   

OrderType in number,  

strWhere in varchar2,  

DataCount out number,              

DataSet out type_cur          

);
end CJ_PageData;

CREATE OR REPLACE PACKAGE BODY CJ_PageData
AS

PROCEDURE CJ_GetDataByPage
(
tblName in  varchar2,      --表名 

strGetFields in varchar2,  --q回字段

fldName in varchar2,       --排序字段?/p>

PageSize in  number,       --分页大小  

PageIndex in  number,      --늠    

doCount  in number,        --是否l计(0?1?

OrderType in number,       --排序cd(0?1?

strWhere in varchar2,      --{选条?/p>

DataCount out number,      --q回记录L   

DataSet out type_cur       --q回游标(指针)
)

as

strSQL   varchar2(5000) ;      -- 临时记录Sql语句

strOrder varchar2(400) ;       -- 临时记录排序语句

begin

if doCount <> 0 then
    begin
      if  strWhere <>  ' ' then
  
          strSQL := 'select count(*) as total from ' || tblName || ' where '||strWhere;
             
      else
          strSQL := 'select count(*) as total from ' || tblName;
      end if;
      
      execute immediate  strSQL into DataCount;--取出记录L攑օq回变量DataCount      
    end;

else

    begin
         
         strSQL := 'select ' ||strGetFields||' from (select T2.*,rownum rn from (select T1.* from ' || tblName||' T1 ';
         
        --得到排序cd语句
        if OrderType <> 0 then

           begin           
                 strOrder := ' order by ' || fldName ||' asc';              
           end;

        else

           begin
                  strOrder := ' order by ' || fldName ||' desc';           
           end;

        end if;
        
        begin
       --l装SQl语句

                 if strWhere <> ' ' then
                
                    strSQL := strSQL || ' where ' || strWhere || ') T2 where rownum <=' || TO_CHAR(PageIndex*PageSize) || ')'
                    || ' where rn >' || TO_CHAR((PageIndex-1)*PageSize) || strOrder;
                    
                else
                
                    strSQL := strSQL || ' ) T2 where rownum <=' || TO_CHAR(PageIndex*PageSize) || ')'
                    || ' where rn >' || TO_CHAR((PageIndex-1)*PageSize) || strOrder;
                    
                end if;
           
       end;
    end;
end if;
open DataSet for strSQL;
end;

end CJ_PageData;

?.Net中调用存储过E?/p>

1.Ҏ

/// <summary>
  /// 获得记录L和所有记录{q接字符?存储q程,?q回字段,排序字段,分页大小,늠,l计(1?0不是),排序(1升序,0降序),条g}
  /// </summary>
  /// <param name="strConn"></param>
  /// <param name="strSPName">存储q程名字</param>
  /// <param name="strTableName">表名</param>
  /// <param name="strGetFields">q回字段字符?lt;/param>
  /// <param name="strFieldName">排序字段</param>
  /// <param name="iPageIndex">늠</param>
  /// <param name="iPageSize">分页大小</param>
  /// <param name="iDoCount">是否l计记录L(1l计,0不统?</param>
  /// <param name="iOrderType">排序cd(0升序,1降序)</param>
  /// <param name="strWhere">{选条?不带where)</param>
  protected void BuildData(string strConn,string strSPName,string strTableName,string strGetFields,string strFieldName,int iPageSize,int  iPageIndex,int iDoCount,int iOrderType,string strWhere)
  {
   System.Data.OracleClient.OracleConnection conn = new OracleConnection();
   System.Data.OracleClient.OracleCommand cmd = new OracleCommand();
   System.Data.OracleClient.OracleDataReader dr;

   conn.ConnectionString = strConn;
   cmd.Connection = conn;
   cmd.CommandType = CommandType.StoredProcedure;

   conn.Open();

   cmd.CommandText = strSPName;

   cmd.Parameters.Add("tblName",OracleType.VarChar);//表名
   cmd.Parameters.Add("strGetFields",OracleType.VarChar);//q回字段?br />    cmd.Parameters.Add("fldName",OracleType.VarChar);//排序字段?br />    cmd.Parameters.Add("PageSize",OracleType.Number);//分页大小
   cmd.Parameters.Add("PageIndex",OracleType.Number);//늠
   cmd.Parameters.Add("doCount",OracleType.Number);//是否l计总记录数
   cmd.Parameters.Add("OrderType",OracleType.Number);//排序cd
   cmd.Parameters.Add("strWhere",OracleType.VarChar);//{选条?br />    cmd.Parameters.Add("DataCount",OracleType.Number);//q回得记录L
   cmd.Parameters.Add("DataSet",OracleType.Cursor);//q回得记录集


   cmd.Parameters["tblName"].Value = strTableName;
   cmd.Parameters["strGetFields"].Value = strGetFields;
   cmd.Parameters["fldName"].Value = strFieldName;
   cmd.Parameters["PageSize"].Value = iPageSize;
   
   cmd.Parameters["PageIndex"].Value = ( iOrderType == 0 ) ? (pager.PageCount+1-iPageIndex) : iPageIndex;//因ؓOracle中不支持子查询排?所以在q里如果需要倒序,则将늠按反序取数据,"以假q".嘿嘿!
   cmd.Parameters["doCount"].Value = iDoCount;
   cmd.Parameters["OrderType"].Value = iOrderType;
   cmd.Parameters["strWhere"].Value = strWhere;
   cmd.Parameters["DataCount"].Direction = ParameterDirection.Output;
   cmd.Parameters["DataSet"].Direction = ParameterDirection.Output;

   cmd.Parameters["tblName"].Size = 100;
   cmd.Parameters["strGetFields"].Size = 1000;
   cmd.Parameters["fldName"].Size = 100;
   cmd.Parameters["strWhere"].Size = 1000;
  
   //try
   {
    switch (iDoCount)
    {
     case 0:
     {
      dr = cmd.ExecuteReader();
      dgData.DataSource = dr;
      dgData.DataBind();//l定数据?br />       dr.Close();
      break;
     }
     case 1:
     { 
      cmd.ExecuteOracleScalar();
      pager.RecordCount = int.Parse(cmd.Parameters["DataCount"].Value.ToString());
      break;
     }
    }
    
   }
   //catch
   {
   }
   conn.Close();
 
  }

2.调用

A.面加蝲时候取得总记录数,以绑定分|?/p>

private void Page_Load(object src,EventArgs e)
  {
   if(!Page.IsPostBack)
   {
    string conn = "password=cqcj;user id=cqcj;data source=cqc1";
    this.BuildData(conn,"CJ_PageData.CJ_GetDataByPage","CJ_Log","","",0,0,1,0,"UserID = 'xxr'");
   
    BindData();//q里l分|?如DataGridl定数据?br />    }
  }

B.BindData()

protected void BindData()
  {
   string conn = "password=cqcj;user id=cqcj;data source=cqc1";

   this.BuildData(conn,"CJ_PageData.CJ_GetDataByPage","CJ_Log","*","LoginTime",pager.PageSize,pager.CurrentPageIndex,0,1,"UserID = 'xxr'");

   pager.CustomInfoText="记录LQ?lt;font color=\"blue\"><b>"+pager.RecordCount.ToString()+"</b></font>";
   pager.CustomInfoText+=" 总页敎ͼ<font color=\"blue\"><b>"+pager.PageCount.ToString()+"</b></font>";
   pager.CustomInfoText+=" 当前:<font color=\"red\"><b>"+pager.CurrentPageIndex.ToString()+"</b></font>";
  }

    Oracle中无法直接返回记录集,需利用游标q回.Oracle中不支持子查询排?临时表耗费资源不推荐?



fly 2009-08-18 18:06 发表评论
]]>
融会贯通Oracle数据库的25条基本知??http://www.tkk7.com/jlin/articles/288107.htmlflyflyThu, 23 Jul 2009 14:26:00 GMThttp://www.tkk7.com/jlin/articles/288107.htmlhttp://www.tkk7.com/jlin/comments/288107.htmlhttp://www.tkk7.com/jlin/articles/288107.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/288107.htmlhttp://www.tkk7.com/jlin/services/trackbacks/288107.html

2.每个数据库最有一个控制文Ӟ3个,分别攑֜不同的磁盘上Q?


3.每个数据库最有一个表I间QSYSTEM表空_?


4.建立SYSTEM表空间的目的是尽量将目的相同的表存放在一P以提高用效率,只应存放数据字典?


5.每个数据库最有两个联机日志l,每组最一个联机日志文件?


6.一个数据文件只能属于一个表I间?


7.一个数据文件一旦被加入C个表I间中,׃能再从这个表I间中移赎ͼ也不能再加入到其他表I间中?


8.建立新的表空间需要徏立新的数据文件?


9.数据文g被ORACLE格式化ؓORACLE块,Oracle9i以前版本中,ORACLE块的大小是在W一ơ创建数据库时设定的?


10.q且以后不能改变Q要x变,只能重徏数据库?


11.一个段segment只能属于一个表I间Q但可以属于多个数据文g?


12.一个区extent只能属于一个数据文Ӟ卛__extentQ不能跨数据文件?


13.PCTFREE和PCTUSEDd不能大于{于100?


14.单独一个事务不能跨多个回滚段?


15.索引表不含ROWID倹{?


16.拥有不同大小的回滚段没有M益处?


17.COMMIT后,数据不一定立卛_盘(数据文gQ?


18.一个事务即使不被提交,也会被写入到重做日志中?


19.Oracle 8.0.4中,在初始安装时建立的缺省数据库Q实例名为ORCL ?


20.一个块的最大长度ؓ16KB(?K?K?K?6K)?


每个数据库最大文件数Q按块大)

2K块        20000个文?

4K块        40000个文?

8K块或以上     65536个文?br />

21.oracle server可以同时启动多个数据??


22.一套操作系l上可以安装多个版本的ORACLE数据库系l(UNIX可以QNT不可以)?


23.一套ORACLE数据库系l中可以有多个ORACLE数据库及其相对应的实??


24.每个Oracle数据库拥有一个数据库实例QINSTANCEQ(OPS除外Q?


25.所以,一套操作系l上同时可以有多个Oracle数据库实例启动?


fly 2009-07-23 22:26 发表评论
]]>
数据库连接的区别??http://www.tkk7.com/jlin/articles/262412.htmlflyflyFri, 27 Mar 2009 06:15:00 GMThttp://www.tkk7.com/jlin/articles/262412.htmlhttp://www.tkk7.com/jlin/comments/262412.htmlhttp://www.tkk7.com/jlin/articles/262412.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/262412.htmlhttp://www.tkk7.com/jlin/services/trackbacks/262412.html 1 关系代数
合ƈ数据集合的理论基是关pM敎ͼ它是由E.F.Codd?970q提出的?br /> 在关pM数的形式化语a中:
?nbsp;        用表、或者数据集合表C关pL者实体?br /> ?nbsp;        用行表示元组?br /> ?nbsp;        用列表示属性?br /> 关系代数包含以下8个关p运符
?nbsp;        选取――返回满x定条件的行?br /> ?nbsp;        投媄――从数据集合中返回指定的列?br /> ?nbsp;        W卡积――是关系的乘法,它将分别来自两个数据集合中的行以所有可能的方式q行l合?br /> ?nbsp;        q――关pȝ加法和减法,它可以在行的方向上合q两个表中的数据Q就像把一个表垒在另一个表之上一栗?br /> ?nbsp;        交――返回两个数据集合所共有的行?br /> ?nbsp;        差――返回只属于一个数据集合的行?br /> ?nbsp;        q接――在水^方向上合q两个表Q其Ҏ是:两个表中在共同数据上怺匚w的那些行合ƈh?br /> ?nbsp;        除――返回两个数据集之间的精匹配?br /> 此外Q作ZU实现现代关pM数运的ҎQSQLq提供了Q?br /> ?nbsp;        子查询――类gq接Q但更灵z;在外部查询中Q方式可以用表辑ּ、列表或者数据集合的地方都可以用子查询的结果?br /> 本章主要讲q多U类型的q接、简单的和相关的子查询、几U类型的q、关p除以及其他的内宏V?br /> 2 使用q接
2.1 q接cd
在关pMCQ连接运是׃个笛卡尔U运和一个选取q算构成的。首先用W卡积完成对两个数据集合的乘运,然后对生成的l果集合q行选取q算Q确保只把分别来自两个数据集合ƈ且具有重叠部分的行合q在一赗连接的全部意义在于在水qx向上合ƈ两个数据集合Q通常是表Q,q生一个新的结果集合,其方法是一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组?br /> SQL提供了多U类型的q接方式Q它们之间的区别在于Q从怺交叠的不同数据集合中选择用于q接的行时所采用的方法不同?br /> q接cd         定义
内连?nbsp;        只连接匹配的?br /> 左外q接         包含左边表的全部行(不管双的表中是否存在与它们匚w的行Q,以及双表中全部匚w的行
叛_q接         包含双表的全部行(不管左边的表中是否存在与它们匚w的行Q,以及左边表中全部匚w的行
全外q接         包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行?br /> (H)(theta)q接         使用{g外的条g来匹配左、右两个表中的行
交叉q接         生成W卡积Q它不用Q何匹配或者选取条gQ而是直接一个数据源中的每个行与另一个数据源的每个行都一一匚w
在INFORMIX中连接表的查?br /> 如果FROM子句指定了多于一个表引用Q则查询会连接来自多个表的行。连接条件指定各列之_每个表至一列)q行q接的关pR因为正在比较连接条件中的列Q所以它们必d有一致的数据cd?br /> SELECT语句的FROM子句可以指定以下几种cd的连?br /> FROM子句关键?nbsp;        相应的结果集
CROSS JOIN         W卡乘U(所有可能的行对Q?br /> INNER JOIN         仅对满q接条g的CROSS中的?br /> LEFT OUTER JOIN         一个表满条g的行Q和另一个表的所有行
RIGHT OUTER JOIN         与LEFT相同Q但两个表的角色互换
FULL OUTER JOIN         LEFT OUTER ?RIGHT OUTER中所有行的超?br />
其中的outerQ如果不写则表示默认?br /> 2.2 内连接(Inner JoinQ?br /> 内连接是最常见的一U连接,它页被称为普通连接,而E.FCodd最早称之ؓ自然q接?br /> 下面是ANSI SQLQ?2标准
select *
from   t_institution i
inner join t_teller t
on i.inst_no = t.inst_no
where i.inst_no = "5801"
其中inner可以省略?br /> {h于早期的q接语法
select *
from t_institution i, t_teller t
where i.inst_no = t.inst_no
and i.inst_no = "5801"

2.3 外连?br /> 2.3.1         左外q接(Left Outer Jion)
select *
from   t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
其中outer可以省略?br /> 2.3.2         叛_q接(Rigt Outer Jion)
select *
from   t_institution i
right outer join t_teller t
on i.inst_no = t.inst_no
2.3.3         全外q接(Full Outer)
全外q接q回参与q接的两个数据集合中的全部数据,无论它们是否h与之相匹配的行。在功能上,它等价于对这两个数据集合分别q行左外q接和右外连接,然后再用消去重复行的ƈ操作上qC个结果集合ƈZ个结果集?br /> 在现实生zMQ参照完整性约束可以减对于全外连接的使用Q一般情况下左外q接p够了。在数据库中没有利用清晰、规范的U束来防范错误数据情况下Q全外连接就变得非常有用了,你可以用它来清理数据库中的数据?br /> select *
from   t_institution i
full outer join t_teller t
on i.inst_no = t.inst_no
2.3.4         外连接与条g配合使用
当在内连接查询中加入条g是,无论是将它加入到join子句Q还是加入到where子句Q其效果是完全一LQ但对于外连接情况就不同了。当把条件加入到join子句ӞSQL Server、Informix会返回外q接表的全部行,然后使用指定的条件返回第二个表的行。如果将条g攑ֈwhere子句中,SQL Server会首先q行q接操作Q然后用where子句对连接后的行q行{选。下面的两个查询展示了条件放|位子对执行l果的媄响:
条g在join子句
select *
from   t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
and i.inst_no = “5801”
l果是:
inst_no     inst_name             inst_no     teller_no   teller_name
5801        天河?nbsp;               5801        0001        tom
5801        天河?nbsp;               5801        0002        david
5802        秀?br /> 5803        白云?br /> 条g在where子句
select *
from   t_institution i
left outer join t_teller t
on i.inst_no = t.inst_no
where i.inst_no = “5801”
l果是:
inst_no     inst_name             inst_no     teller_no   teller_name
5801        天河?nbsp;               5801        0001        tom
5801        天河?nbsp;               5801        0002        david

2.4 自nq接
自nq接是指同一个表自己与自p行连接。这U一元连接通常用于从自反关p(也称作递归关系Q中抽取数据。例如h力资源数据库中雇员与老板的关pR?br /> 下面例子是在机构表中查找本机构和上机构的信息?br /> select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name
from t_institution i
join t_institution s
on i.superior_inst = s.inst_no

l果是:
superior_inst sup_inst_name         inst_no     inst_name
800            q州?nbsp;               5801        天河?br /> 800            q州?nbsp;               5802        秀?br /> 800            q州?nbsp;               5803        白云?br />
2.5 交叉(无限? q接
交叉q接用于对两个源表进行纯关系代数的乘q算。它不用连接条件来限制l果集合Q而是分别来自两个数据源中的行以所有可能的方式q行l合。数据集合中一的每个行都要与数据集合二中的每一个行分别l成一个新的行。例如,如果W一个数据源中有5个行Q而第二个数据源中?个行Q那么在它们之间q行交叉q接׃产生20个行。h们将q种cd的结果集UCؓW卡乘U?br /> 大多C叉连接都是由于错误操作而造成的;但是它们却非帔R合向数据库中填充例子数据,或者预先创Z些空行以便ؓE序执行期间所要填充的数据保留I间?br /> select *
from   t_institution i
cross join t_teller t
在交叉连接中没有on条g子句

3 APPENDIX
3.1 A 参考资料与资源
?nbsp;        《Microsoft SQL Server 2000 Bile》Paul Nielsen
?nbsp;        Paul Nielsen的Web站点
www.isnotnull.com
3.2 注文章所有SQL在IBM Informix Dynamic Server Version 9.40.TC2E1试通过  

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=940779



fly 2009-03-27 14:15 发表评论
]]>
单讲q基于SQL SERVER 分页的存储过E??http://www.tkk7.com/jlin/articles/231463.htmlflyflySat, 27 Sep 2008 03:52:00 GMThttp://www.tkk7.com/jlin/articles/231463.htmlhttp://www.tkk7.com/jlin/comments/231463.htmlhttp://www.tkk7.com/jlin/articles/231463.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/231463.htmlhttp://www.tkk7.com/jlin/services/trackbacks/231463.html阅读全文

fly 2008-09-27 11:52 发表评论
]]>
MS SQL 2000 存储q程http://www.tkk7.com/jlin/articles/63054.htmlflyflyFri, 11 Aug 2006 09:09:00 GMThttp://www.tkk7.com/jlin/articles/63054.htmlhttp://www.tkk7.com/jlin/comments/63054.htmlhttp://www.tkk7.com/jlin/articles/63054.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/63054.htmlhttp://www.tkk7.com/jlin/services/trackbacks/63054.html------------------------------------------------------------------------------------------------------------------------------------------------------
自己写的存储q程Q?br />use test
go

if exists (select name from sysobjects where name='v_order' and type='p')
DROP PROCEDURE v_order
go

create procedure v_order
 @serverid varchar(30),
 @jtype   int
 as
 select * from
 order_form
where jtype= @jtype and serverid=@serverid

select * from sysobjects where type='p' and name='v_order'

exec v_order 'hcair','3'
go
exec v_order hcair,3

exec v_order @serverid=hcair,@jtype=3


drop proc v_order_in
go
create procedure v_order_in
@user_name varchar(20),
@pnr_list  varchar(20),
@air_list  varchar(20),
@arri_list  varchar(20),
@dp_time    timestamp,
@lxname   varchar(20)
as
insert into order_form(user_name,pnr_list,air_list,arri_list,dp_time,lxname) values (@user_name,@pnr_list,@air_list,@arri_list,@dp_time,@lxname )
go

exec v_order_in 0000,rksts,MF8587,'KHN,PEK,',convert('2006-7-16 13:03:53'),linsanfu
-------------------------------------------------------------------------------------------------------------------------------------------------------
CZ
A. 使用带有复杂 SELECT 语句的简单过E?br />下面的存储过E从四个表的联接中返回所有作者(提供了姓名)、出版的书籍以及出版C。该存储q程不用Q何参数?/p>

USE pubs
IF EXISTS (SELECT name FROM sysobjects
         WHERE name = 'au_info_all' AND type = 'P')
   DROP PROCEDURE au_info_all
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
   FROM authors a INNER JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER JOIN titles t
      ON t.title_id = ta.title_id INNER JOIN publishers p
      ON t.pub_id = p.pub_id
GO

au_info_all 存储q程可以通过以下Ҏ执行Q?/p>

EXECUTE au_info_all
-- Or
EXEC au_info_all

如果该过E是批处理中的第一条语句,则可使用Q?/p>

au_info_all

B. 使用带有参数的简单过E?br />下面的存储过E从四个表的联接中只q回指定的作者(提供了姓名)、出版的书籍以及出版C。该存储q程接受与传递的参数_匚w的倹{?/p>

USE pubs
IF EXISTS (SELECT name FROM sysobjects
         WHERE name = 'au_info' AND type = 'P')
   DROP PROCEDURE au_info
GO
USE pubs
GO
CREATE PROCEDURE au_info
   @lastname varchar(40),
   @firstname varchar(20)
AS
SELECT au_lname, au_fname, title, pub_name
   FROM authors a INNER JOIN titleauthor ta
      ON a.au_id = ta.au_id INNER JOIN titles t
      ON t.title_id = ta.title_id INNER JOIN publishers p
      ON t.pub_id = p.pub_id
   WHERE  au_fname = @firstname
      AND au_lname = @lastname
GO

au_info 存储q程可以通过以下Ҏ执行Q?/p>

EXECUTE au_info 'Dull', 'Ann'
-- Or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- Or
EXEC au_info 'Dull', 'Ann'
-- Or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'

如果该过E是批处理中的第一条语句,则可使用Q?/p>

au_info 'Dull', 'Ann'
-- Or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- Or
au_info @firstname = 'Ann', @lastname = 'Dull'

C. 使用带有通配W参数的单过E?br />下面的存储过E从四个表的联接中只q回指定的作者(提供了姓名)、出版的书籍以及出版C。该存储q程对传递的参数q行模式匚wQ如果没有提供参敎ͼ则用预讄默认倹{?/p>

USE pubs
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'au_info2' AND type = 'P')
   DROP PROCEDURE au_info2
GO
USE pubs
GO
CREATE PROCEDURE au_info2
   @lastname varchar(30) = 'D%',
   @firstname varchar(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
   ON a.au_id = ta.au_id INNER JOIN titles t
   ON t.title_id = ta.title_id INNER JOIN publishers p
   ON t.pub_id = p.pub_id
WHERE au_fname LIKE @firstname
   AND au_lname LIKE @lastname
GO

au_info2 存储q程可以用多U组合执行。下面只列出了部分组合:

EXECUTE au_info2
-- Or
EXECUTE au_info2 'Wh%'
-- Or
EXECUTE au_info2 @firstname = 'A%'
-- Or
EXECUTE au_info2 '[CK]ars[OE]n'
-- Or
EXECUTE au_info2 'Hunter', 'Sheryl'
-- Or
EXECUTE au_info2 'H%', 'S%'

D. 使用 OUTPUT 参数
OUTPUT 参数允许外部q程、批处理或多?Transact-SQL 语句讉K在过E执行期间设|的某个倹{下面的CZ创徏一个存储过E?(titles_sum)Qƈ使用一个可选的输入参数和一个输出参数?/p>

首先Q创E:

USE pubs
GO
IF EXISTS(SELECT name FROM sysobjects
      WHERE name = 'titles_sum' AND type = 'P')
   DROP PROCEDURE titles_sum
GO
USE pubs
GO
CREATE PROCEDURE titles_sum @@TITLE varchar(40) = '%', @@SUM money OUTPUT
AS
SELECT 'Title Name' = title
FROM titles
WHERE title LIKE @@TITLE
SELECT @@SUM = SUM(price)
FROM titles
WHERE title LIKE @@TITLE
GO

接下来,该 OUTPUT 参数用于控制语a?

 

说明  OUTPUT 变量必须在创和用该变量旉q行定义?/p>


参数名和变量名不一定要匚wQ不q数据类型和参数位置必须匚wQ除非?@@SUM = variable 形式Q?

DECLARE @@TOTALCOST money
EXECUTE titles_sum 'The%', @@TOTALCOST OUTPUT
IF @@TOTALCOST < 200
BEGIN
   PRINT ' '
   PRINT 'All of these titles can be purchased for less than $200.'
END
ELSE
   SELECT 'The total cost of these titles is $'
         + RTRIM(CAST(@@TOTALCOST AS varchar(20)))

下面是结果集Q?/p>

Title Name                                                              
------------------------------------------------------------------------
The Busy Executive's Database Guide
The Gourmet Microwave
The Psychology of Computer Cooking

(3 row(s) affected)

Warning, null value eliminated from aggregate.
 
All of these titles can be purchased for less than $200.

E. 使用 OUTPUT 游标参数
OUTPUT 游标参数用来存储过E的局部游标传递回调用批处理、存储过E或触发器?/p>

首先Q创Z下过E,?titles 表上声明q打开一个游标:

USE pubs
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'titles_cursor' and type = 'P')
DROP PROCEDURE titles_cursor
GO
CREATE PROCEDURE titles_cursor @titles_cursor CURSOR VARYING OUTPUT
AS
SET @titles_cursor = CURSOR
FORWARD_ONLY STATIC FOR
SELECT *
FROM titles

OPEN @titles_cursor
GO

接下来,执行一个批处理Q声明一个局部游标变量,执行上述q程以将游标赋值给局部变量,然后从该游标提取行?/p>

USE pubs
GO
DECLARE @MyCursor CURSOR
EXEC titles_cursor @titles_cursor = @MyCursor OUTPUT
WHILE (@@FETCH_STATUS = 0)
BEGIN
   FETCH NEXT FROM @MyCursor
END
CLOSE @MyCursor
DEALLOCATE @MyCursor
GO

F. 使用 WITH RECOMPILE 选项
如果E提供的参数不是典型的参敎ͼq且新的执行计划不应高速缓存或存储在内存中QWITH RECOMPILE 子句会很有帮助?/p>

USE pubs
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'titles_by_author' AND type = 'P')
   DROP PROCEDURE titles_by_author
GO
CREATE PROCEDURE titles_by_author @@LNAME_PATTERN varchar(30) = '%'
WITH RECOMPILE
AS
SELECT RTRIM(au_fname) + ' ' + RTRIM(au_lname) AS 'Authors full name',
   title AS Title
FROM authors a INNER JOIN titleauthor ta
   ON a.au_id = ta.au_id INNER JOIN titles t
   ON ta.title_id = t.title_id
WHERE au_lname LIKE @@LNAME_PATTERN
GO

G. 使用 WITH ENCRYPTION 选项
WITH ENCRYPTION 子句对用户隐藏存储过E的文本。下例创建加密过E,使用 sp_helptext pȝ存储q程获取关于加密q程的信息,然后试直接?syscomments 表中获取关于该过E的信息?/p>

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'encrypt_this' AND type = 'P')
   DROP PROCEDURE encrypt_this
GO
USE pubs
GO
CREATE PROCEDURE encrypt_this
WITH ENCRYPTION
AS
SELECT *
FROM authors
GO

EXEC sp_helptext encrypt_this

下面是结果集Q?/p>

The object's comments have been encrypted.

接下来,选择加密存储q程内容的标识号和文本?/p>

SELECT c.id, c.text
FROM syscomments c INNER JOIN sysobjects o
   ON c.id = o.id
WHERE o.name = 'encrypt_this'

下面是结果集Q?/p>

 

说明  text 列的输出昄在单独一行中。执行时Q该信息与 id 列信息出现在同一行中?/p>


id         text                                                       
---------- ------------------------------------------------------------
1413580074 ?????????????????????????????????e??????????????????????????????????????????????????????????????????????????

(1 row(s) affected)

H. 创徏用户定义的系l存储过E?br />下面的示例创Z个过E,昄表名?emp 开头的所有表及其对应的烦引。如果没有指定参敎ͼ该过E将q回表名?sys 开头的所有表Q及索引Q?/p>

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'sp_showindexes' AND type = 'P')
   DROP PROCEDURE sp_showindexes
GO
USE master
GO
CREATE PROCEDURE sp_showindexes
   @@TABLE varchar(30) = 'sys%'
AS
SELECT o.name AS TABLE_NAME,
   i.name AS INDEX_NAME,
   indid AS INDEX_ID
FROM sysindexes i INNER JOIN sysobjects o
   ON o.id = i.id
WHERE o.name LIKE @@TABLE
GO        
USE pubs
EXEC sp_showindexes 'emp%'
GO

下面是结果集Q?/p>

TABLE_NAME       INDEX_NAME       INDEX_ID
---------------- ---------------- ----------------
employee         employee_ind     1
employee         PK_emp_id        2

(2 row(s) affected)

I. 使用延迟名称解析
下面的示例显C四个过E以及gq名U解析的各种可能使用方式。尽引用的表或列在~译时不存在Q但每个存储q程都可创徏?/p>

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'proc1' AND type = 'P')
   DROP PROCEDURE proc1
GO
-- Creating a procedure on a nonexistent table.
USE pubs
GO
CREATE PROCEDURE proc1
AS
   SELECT *
   FROM does_not_exist
GO 
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
   ON o.id = c.id
WHERE o.type = 'P' AND o.name = 'proc1'
GO
USE master
GO
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'proc2' AND type = 'P')
   DROP PROCEDURE proc2
GO
-- Creating a procedure that attempts to retrieve information from a
-- nonexistent column in an existing table.
USE pubs
GO
CREATE PROCEDURE proc2
AS
   DECLARE @middle_init char(1)
   SET @middle_init = NULL
   SELECT au_id, middle_initial = @middle_init
   FROM authors
GO 
-- Here is the statement to actually see the text of the procedure.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
   ON o.id = c.id
WHERE o.type = 'P' and o.name = 'proc2'

 



fly 2006-08-11 17:09 发表评论
]]>
MSSQL数据cdhttp://www.tkk7.com/jlin/articles/63051.htmlflyflyFri, 11 Aug 2006 09:06:00 GMThttp://www.tkk7.com/jlin/articles/63051.htmlhttp://www.tkk7.com/jlin/comments/63051.htmlhttp://www.tkk7.com/jlin/articles/63051.html#Feedback0http://www.tkk7.com/jlin/comments/commentRss/63051.htmlhttp://www.tkk7.com/jlin/services/trackbacks/63051.html4.3.1 整数数据cd
    整数数据cd是最常用的数据类型之一?br />     1、INT QINTEGERQ?br />INT Q或INTEGERQ数据类型存储从-2?1ơ方 Q?2 Q?47 Q?83 Q?48Q???1ơ方-1 Q? Q?47 Q?83Q?47Q?之间的所有正负整数。每个INT cd的数据按4 个字节存储,其中1 位表C整数值的正负P其它31 位表C整数值的长度和大?
     2、SMALLINT
SMALLINT 数据cd存储?2?5ơ方Q?-32Q?768Q???5ơ方-1Q?32 Q?67 Q之间的所有正负整数。每个SMALLINT cd的数据占? 个字节的存储I间Q其? 位表C整数值的正负P其它15 位表C整数值的长度和大?br />     3、TINYINT
TINYINT数据cd存储? ?55 之间的所有正整数。每个TINYINTcd的数据占? 个字节的存储I间?br />     4、BIGINT
BIGINT 数据cd存储?2^63 Q?9 Q?23Q?372Q?036Q?854Q?775Q?807Q??^63-1Q?9Q?223Q?372Q?036 Q?54 Q?75Q?807Q?之间的所有正负整数。每个BIGINT cd的数据占?个字节的存储I间?/p>

4.3.2 点数据cd
    点数据cd用于存储十进制小数。QҎ值的数据在SQL Server 中采用上舍入QRound up 或称为只入不舍)方式q行存储。所谓上舍入是指Q当Q且仅当Q要舍入的数是一个非零数Ӟ对其保留数字部分的最低有效位上的数值加1 Qƈq行必要的进位。若一个数是上舍入敎ͼ其绝对g会减。如Q对3.14159265358979 分别q行2 位和12位舍入,l果?.15 ?.141592653590?br />     1、REAL 数据cd
REAL数据cd可精到W? 位小敎ͼ其范围ؓ?3.40E -38 ?.40E +38?每个REALcd的数据占? 个字节的存储I间?br />     2、FLOAT
FLOAT数据cd可精到W?5 位小敎ͼ其范围ؓ?1.79E -308 ?.79E +308?每个FLOAT cd的数据占? 个字节的存储I间?FLOAT数据cd可写为FLOAT[ n ]的Ş式。n 指定FLOAT 数据的精度。n ??5 之间的整数倹{当n ? ? Ӟ实际上是定义了一个REAL cd的数据,pȝ? 个字节存储它Q当n ? ?5 Ӟpȝ认ؓ其是FLOAT cdQ用8 个字节存储它?br />     3、DECIMAL
DECIMAL数据cd可以提供数所需要的实际存储I间Q但也有一定的限制Q您可以? ?7 个字节来存储?10?8ơ方-1 ?0?8ơ方-1 之间的数倹{可其写ؓDECIMAL[ p [s] ]的Ş式,p 和s 定了精的比例和数位。其中p 表示可供存储的值的M敎ͼ不包括小数点Q,~省gؓ18Q?s 表示数点后的位敎ͼ~省gؓ0?例如Qdecimal Q?5 5Q,表示共有15 位数Q其中整?0 位,数5?位表4-3 列出了各_度所需的字节数之间的关pR?br /> 
     4、NUMERIC
NUMERIC数据cd与DECIMAL数据cd完全相同?br />注意QSQL Server Z和前端的开发工具配合,其所支持的数据精度默认最大ؓ28位。但可以通过使用命o来执行sqlserver.exeE序以启动SQL ServerQ可改变默认_ֺ。命令语法如下:SQLSERVR[/D master_device_path][/P precisim_leve1]
    ?-4: 用最大数据精?8 启动SQL Server
sqlservr /d c:\ Mssql2000\data\master.dat /p38
/*在用了/P 参数?如果其后没有指定具体的精度数?则默认ؓ38 ?/*
4.3.3 二进制数据类?br />     1、BINARY
BINARY 数据cd用于存储二进制数据。其定义形式为BINARYQ?nQ, n 表示数据的长度,取gؓ1 ?000 。在使用时必L定BINARY cd数据的大,臛_应ؓ1 个字节。BINARY cd数据占用n+4 个字节的存储I间。在输入数据时必d数据前加上字W?X?作ؓ二进制标识,如:要输入“abc ”则应输入?xabc ”。若输入的数据过长将会截掉其出部分。若输入的数据位Cؓ奇数Q则会在起始W号?X ”后d一?Q如上述的?xabc ”会被系l自动变为?x0abc”?
     2、VARBINARY
VARBINARY数据cd的定义Ş式ؓVARBINARYQnQ?它与BINARY cd怼Qn 的取g? ?000Q?若输入的数据q长Q将会截掉其出部分。不同的是VARBINARY数据cdh变动长度的特性,因ؓVARBINARY数据cd的存储长度ؓ实际数值长?4个字节。当BINARY数据cd允许NULL 值时Q将被视为VARBINARY数据cd?br />一般情况下Q由于BINARY 数据cd长度固定Q因此它比VARBINARY cd的处理速度快?/p>

4.3.4 逻辑数据cd
    BITQ?BIT数据cd占用1 个字节的存储I间Q其gؓ0 ? 。如果输? ? 以外的|被视ؓ1?BIT cd不能定义为NULL |所谓NULL 值是指空值或无意义的|?/p>

4.3.5 字符数据cd
    字符数据cd是用最多的数据cd。它可以用来存储各种字母、数字符受特D符受一般情况下Q用字W类型数据时d其前后加上单引号’或双引号??
     1 CHAR
CHAR 数据cd的定义Ş式ؓCHAR[ QnQ?]?以CHAR cd存储的每个字W和W号占一个字节的存储I间。n 表示所有字W所占的存储I间Qn 的取gؓ1 ?000Q?卛_容纳8000 个ANSI 字符。若不指定n |则系l默认gؓ1?若输入数据的字符数小于nQ则pȝ自动在其后添加空格来填满讑֮好的I间。若输入的数据过长,会截掉其超出部分?br />     2、NCHAR
NCHAR数据cd的定义Ş式ؓNCHAR[ QnQ?]?它与CHAR cd怼。不同的是NCHAR数据cdn 的取gؓ1 ?000?因ؓNCHAR cd采用UNICODE 标准字符集(CharacterSetQ?UNICODE 标准规定每个字符占用两个字节的存储空_所以它比非UNICODE 标准的数据类型多占用一倍的存储I间。用UNICODE 标准的好处是因其使用两个字节做存储单位,其一个存储单位的容纳量就大大增加了,可以全世界的语a文字都囊括在内,在一个数据列中就可以同时出现中文、英文、法文、d文等Q而不会出现编码冲H?br />     3、VARCHAR
VARCHAR数据cd的定义Ş式ؓVARCHAR [ QnQ?]?它与CHAR cd怼Qn 的取g? ?000Q?若输入的数据q长Q将会截掉其出部分。不同的是,VARCHAR数据cdh变动长度的特性,因ؓVARCHAR数据cd的存储长度ؓ实际数值长度,若输入数据的字符数小于n Q则pȝ不会在其后添加空格来填满讑֮好的I间?br />一般情况下Q由于CHAR 数据cd长度固定Q因此它比VARCHAR cd的处理速度快?br />     4、NVARCHAR
NVARCHAR数据cd的定义Ş式ؓNVARCHAR[ QnQ?]?它与VARCHAR cd怼。不同的是,NVARCHAR数据cd采用UNICODE 标准字符集(Character SetQ, n 的取gؓ1 ?000?/p>

4.3.6 文本和图形数据类?br />    q类数据cd用于存储大量的字W或二进制数据?br />     1、TEXT
TEXT数据cd用于存储大量文本数据Q其定w理论上ؓ1 ??1ơ方-1 Q?Q?147Q?483Q?647Q个字节Q在实际应用旉要视盘的存储空间而定?br />SQL Server 2000 以前的版本中Q数据库中一个TEXT 对象存储的实际上是一个指针,它指向一个个?KB Q?192 个字节)为单位的数据(Data PageQ?q些数据|动态增加ƈ被逻辑链接h的。在SQL Server 2000 中,则将TEXT 和IMAGE cd的数据直接存攑ֈ表的数据行中Q而不是存攑ֈ不同的数据页中?q就减少了用于存储TEXT 和IMA- GE cd的空_q相应减了盘处理q类数据的I/O 数量?br />    2 NTEXT
NTEXT数据cd与TEXT.cd怼不同?是NTEXT cd采用UNICODE 标准字符?Character Set), 因此其理论容量ؓ230-1(1, 073, 741, 823)个字节?br />    3 IMAGE
IMAGE数据cd用于存储大量的二q制数据Binary Data?其理论容量ؓ2?1ơ方-1(2,147,483,647)个字节。其存储数据的模式与TEXT 数据cd相同。通常用来存储囑Ş{OLE Object Linking and EmbeddingQ对象连接和嵌入Q对象。在输入数据时同BINARY数据cd一P必须在数据前加上字符?X”作Zq制标识

4.3.7 日期和时间数据类?br />    1 DATETIME
DATETIME 数据cd用于存储日期和时间的l合体。它可以存储从公?753 q? ? 日零时v到公?999 q?2 ?1 ?3 ?9 ?9 U之间的所有日期和旉Q其_度可达三癑ֈ之一U,?.33 毫秒。DATETIME 数据cd所占用的存储空间ؓ8 个字节。其中前4 个字节用于存?900 q? ? 日以前或以后的天敎ͼ数值分正负Q正数表C在此日期之后的日期Q负数表C在此日期之前的日期。后4 个字节用于存储从此日零时h指定的时间经q的毫秒数。如果在输入数据时省略了旉部分Q则pȝ?2:00:00:000AM作ؓ旉~省|如果省略了日期部分,则系l将1900 q? ? 日作为日期缺省倹{?br />    2 SMALLDATETIME
SMALLDATETIME 数据cd与DATETIME 数据cd怼Q但其日期时间范围较,Z1900 q? ? 日到2079 q? ?Q日_ֺ较低Q只能精到分钟Q其分钟个位上ؓҎU数四舍五入的?即以30 Uؓ界四舍五入。如QDATETIME 旉?4:38:30.283
时SMALLDATETIME 认ؓ?4:39:00 SMALLDATETIME 数据cd使用4 个字节存储数据。其中前2 个字节存储从基础日期1900 q? ? 日以来的天数Q后两个字节存储此日零时h指定的时间经q的分钟数?br />    下面介绍日期和时间的输入格式
    日期输入格式
    日期的输入格式很多大致可分ؓ三类Q?

英文+数字格式
此类格式中月份可用英文全名或~写Q且不区分大写Q年和月日之间可不用逗号Q?br />q䆾可ؓ4 位或2 位;当其Z位时Q若值小?0 则视?0xx q_若大于或{于50 ?br />视ؓ19xx q_若日部分省略Q则视ؓ当月?受以下格式均为正的日期格式Q?br />June 21 2000 Oct 1 1999 January 2000 2000 February
2000 May 1 2000 1 Sep 99 June July 00
数字+分隔W格?br />允许把斜杠(/Q、连接符Q?Q和数点(.Q作为用数字表示的年、月、日之间的分
隔符。如Q?br />YMDQ?000/6/22 2000-6-22 2000.6.22
MDYQ?/5/2000 3-5-2000 3.5.2000
DMYQ?1/12/1999 31-12-1999 31.12.2000
U数字格?br />U数字格式是以连l的4 ?、位? 位数字来表示日期。如果输入的? 位或8 ?br />数字Q系l将按年、月、日来识别,即YMD 格式Qƈ且月和日都是用两位数字来表示Q?br />如果输入的数字是4 位数Q系l认4 位数代表q䆾,其月份和日缺省ؓ此年度的1 ?br />1 日。如:
20000601---2000 q? ? ?991212---1999 q?2 ?2 ?1998---1998 q?
????
旉输入格式
在输入时间时必须按“小时、分钟、秒、毫U”的序来输入。在光用冒号“:”隔开。但可将毫秒部分用小数点??分,隔其后第一位数字代表十分之一U,W二位数字代表百分之一U,W三位数字代表千分之一U。当使用12 时制时用AM。am 和PMQpmQ分别指定时间是午前或午后,若不指定Q系l默认ؓAM。AM 与PM 均不区分大小写。如Q?br />    3:5:7.2pm---下午3 ? ? U?00 毫秒
    10:23:5.123Am---上午10 ?3 ? U?23 毫秒
    可以使用SET DATEFORMAT 命o来设定系l默认的日期-旉格式?

4.3.8 货币数据cd
货币数据cd用于存储货币倹{在使用货币数据cdӞ应在数据前加上货币符Ppȝ才能辨识其ؓ哪国的货币,如果不加货币W号Q则默认为“E”。各货币W号如图4-2所C?br />    1 MONEY
MONEY 数据cd的数据是一个有4 位小数的DECIMAL |其取g-2?3ơ方Q?922Q?37Q?03Q?85Q?77.5808??3ơ方-1Q?922Q?37Q?03Q?85Q?77.5807Q,数据_ֺZ分之一货币单位。MONEY 数据cd使用8个字节存储?br /> 
    2 SMALLMONEY
SMALLMONEY数据cdcM于MONEY cdQ但其存储的货币D围比MONEY数据cd?其取g-214,748.3648?214,748.3647,存储I间? 个字节?/p>

4.3.9 特定数据cd
SQL Server 中包含了一些用于数据存储的Ҏ数据cd?br />    1 TIMESTAMP
TIMESTAMP数据cd提供数据库范围内的惟一值此cd相当于BINARY8或VARBINARYQ?Q,但当它所定义的列在更新或插入数据行时Q此列的g被自动更斎ͼ一个计数值将自动地添加到此TIMESTAMP数据列中。每个数据库表中只能有一个TIMESTAMP数据列。如果徏立一个名为“TIMESTAMP”的列,则该列的cd被自动设ؓTIMESTAMP数据cd?/p>

    2 UNIQUEIDENTIFIER
UNIQUEIDENTIFIER 数据cd存储一?6 位的二进制数字。此数字UCؓQGUIDGlobally Unique Identifier Q即全球惟一鉴别P。此数字由SQLServer 的NEWID函数产生的全球惟一的编码,在全球各地的计算机经由此函数产生的数字不会相同?/p>

4.3.10 用户自定义数据类?br />SYSNAME SYSNAME 数据cd是系l提供给用户的,便于用户自定义数据类型。它被定义ؓNVARCHARQ?28Q,卛_可存?28个UNICODE字符?56个一般字W。其具体使用Ҏ请参见第7章“管理数据库表”中的“自定义数据cd”章节?/p>

4.3.11 新数据类?br />SQL Server 2000 中增加了3 U数据类型:BIGINT、SQL_VARIANT和TABLE。其中BIGINT数据cd已在整数cd中介l,下面介绍其余两种Q?br />    1 SQL_VARIANT
SQL_VARIANT数据cd可以存储除文本、图形数据(TEXT、NTEXT、IMAGEQ和TIMESTAMPcd数据外的其它M合法的SQL Server数据。此数据cd大大方便了SQL Server的开发工作?br />    2 TABLE
TABLE 数据cd用于存储对表或视囑֤理后的结果集。这一新类型得变量可以存储一个表Q从而函数或过E返回查询结果更加方便快、捷其、用请参见W?3章“游标、视囑֒自定义函数”?/p>

 



fly 2006-08-11 17:06 发表评论
]]>
վ֩ģ壺 ˾þAV| ۺϺݺݰ| ھƷһëƬѿ| ۺһ| պ޲߹ۿ| ޾Ʒվ߹ۿ㶮| ޹Ʒר߹ۿ| պƵһ| ѿ߿Aվ| 99߹ۿƷ99| ѿƵ| һƵ| ëƬAV뾫Ʒҹ| þþþseɫ͵͵޾Ʒav| ޹AVרAV| ëbbw| ޹ۺ˳ۺվ| Ƭ51Ʒѹۿ| ³˿Ƭһۿ| ѵɬɬƵ߲| Ů18ëƬˮѿ| ŮvƬ| ҹҹƵ| þþwwwëƬ| | ֻ߿avƬ| aëƬƵ| ŷߵӰ| ҹƵѹۿƵ| ˳վѲ| ѿĿһ| Ѹ߹ۿ| auƵӰԺ| þþþѿ| ѾþþƷƬ㽶| ޹˾Ʒ91þþ| ˵va| Ʒަv| ۺɫӰ| ۺϳ߹ۿ| һ鶹|