ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>精品亚洲aⅴ在线观看,国内不卡的二区三区中文字幕,久久精品国产在热久久http://www.aygfsteel.com/jlin/articles/334529.htmlflyflyTue, 12 Oct 2010 03:59:00 GMThttp://www.aygfsteel.com/jlin/articles/334529.htmlhttp://www.aygfsteel.com/jlin/comments/334529.htmlhttp://www.aygfsteel.com/jlin/articles/334529.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/334529.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/334529.html  我们要做åˆîC¸ä½†ä¼šå†™SQL,˜q˜è¦åšåˆ°å†™å‡ºæ€§èƒ½ä¼˜è‰¯çš„SQL,ä»¥ä¸‹ä¸ºç¬”è€…å­¦ä¹ ã€æ‘˜å½•ã€åÆˆæ±‡æ€»éƒ¨åˆ†èµ„æ–™ä¸Žå¤§å®¶åˆ†äínåQ?
åQ?åQ?nbsp;     选择最有效率的表名™åºåº(只在åŸÞZºŽè§„则的优化器中有æ•?åQ?br /> ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名åQŒFROM子句中写在最后的è¡?基础è¡?driving table)ž®†è¢«æœ€å…ˆå¤„理,在FROM子句中包含多个表的情况下,ä½ å¿…™å»é€‰æ‹©è®°å½•条数最ž®‘的表作为基¼‹€è¡¨ã€‚如果有3个以上的表连接查è¯? 那就需要选择交叉è¡?intersection table)ä½œäØ“åŸºç¡€è¡? 交叉表是指那个被其他表所引用的表.
åQ?åQ?nbsp;     WHERE子句中的˜qžæŽ¥™åºåºåQŽï¼š
ORACLE采用自下而上的顺序解析WHERE子句,æ ÒŽ®˜q™ä¸ªåŽŸç†,表之间的˜qžæŽ¥å¿…须写在其他WHERE条äšg之前, 那些可以˜q‡æ×o掉最大数量记录的条äš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替代DELETEåQ?br /> 当删除表中的记录æ—?在通常情况ä¸? 回滚ŒD?rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状æ€?准确地说是恢复到执行删除命ä×o之前的状å†? 而当˜qç”¨TRUNCATEæ—? 回滚ŒDµä¸å†å­˜æ”¾ä“Q何可被恢复的信息.当命令运行后,数据不能被恢å¤?因此很少的资源被调用,执行旉™—´ä¹Ÿä¼šå¾ˆçŸ­. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
åQ?0åQ?ž®½é‡å¤šä‹É用COMMITåQ?br /> 只要有可èƒ?在程序中ž®½é‡å¤šä‹É用COMMIT, ˜q™æ ·½E‹åºçš„æ€§èƒ½å¾—到提高,需求也会因为COMMIT所释放的资源而减ž®?
COMMIT所释放的资�
a. 回滚ŒDµä¸Šç”¨äºŽæ¢å¤æ•°æ®çš„ä¿¡æ?
b. 被程序语句获得的�
c. redo log buffer 中的½Iºé—´
d. ORACLE为管理上˜q?¿Uèµ„源中的内部花è´?br /> åQ?1åQ?用Where子句替换HAVING子句åQ?br /> 避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集˜q›è¡Œ˜q‡æ×o. ˜q™ä¸ªå¤„理需要排åº?总计½{‰æ“ä½? 如果能通过WHERE子句限制记录的数ç›?那就能减ž®‘这斚w¢çš„开销. (非oracleä¸?on、where、having˜q™ä¸‰ä¸ªéƒ½å¯ä»¥åŠ æ¡ä»¶çš„å­å¥ä¸­ï¼Œon是最先执行,where‹Æ¡ä¹‹åQŒhavingæœ€åŽï¼Œå› äØ“on是先把不½W¦åˆæ¡äšg的记录过滤后才进行统计,它就可以减少中间˜qç®—要处理的数据åQŒæŒ‰ç†è¯´åº”该速度是最快的åQŒwhere也应该比havingå¿«ç‚¹çš„ï¼Œå› äØ“å®ƒè¿‡æ»¤æ•°æ®åŽæ‰è¿›è¡ŒsumåQŒåœ¨ä¸¤ä¸ªè¡¨è”接时才用on的,所以在一个表的时候,ž®±å‰©ä¸‹whereè·Ÿhaving比较了。在˜q™å•表查询统计的情况下,如果要过滤的条äšg没有涉及到要计算字段åQŒé‚£å®ƒä»¬çš„结果是一æ ïLš„åQŒåªæ˜¯where可以使用rushmore技术,而havingž®×ƒ¸èƒ½ï¼Œåœ¨é€Ÿåº¦ä¸ŠåŽè€…要慢如果要涉及到计½Ž—的字段åQŒå°±è¡¨ç¤ºåœ¨æ²¡è®¡ç®—之前åQŒè¿™ä¸ªå­—ŒD늚„值是不确定的åQŒæ ¹æ®ä¸Š½‹‡å†™çš„工作流½E‹ï¼Œwhere的作用时间是在计½Ž—之前就完成的,而havingž®±æ˜¯åœ¨è®¡½Ž—后才è“v作用的,所以在˜q™ç§æƒ…况下,两者的¾l“果会不同。在多表联接查询æ—Óž¼Œon比where更早起作用。系¾lŸé¦–先根据各个表之间的联接条ä»Óž¼ŒæŠŠå¤šä¸ªè¡¨åˆæˆä¸€ä¸ªäÍ时表后,再由where˜q›è¡Œ˜q‡æ×oåQŒç„¶åŽå†è®¡ç®—åQŒè®¡½Ž—完后再由having˜q›è¡Œ˜q‡æ×o。由此可见,要想˜q‡æ×o条äšg起到正确的作用,首先要明白这个条件应该在什么时候è“v作用åQŒç„¶åŽå†å†›_®šæ”‘Öœ¨é‚£é‡Œ
åQ?2åQ?减少对表的查询:
在含有子查询的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?3åQ?通过内部函数提高SQL效率.åQ?br /> 复杂的SQL往往牺牲了执行效çŽ? 能够掌握上面的运用函数解决问题的æ–ÒŽ³•在实际工作中是非常有意义çš?br /> åQ?4åQ?使用表的别名(Alias)åQ?br /> 当在SQL语句中连接多个表æ—? 请ä‹Éç”¨è¡¨çš„åˆ«ååÆˆæŠŠåˆ«åå‰¾~€äºŽæ¯ä¸ªColumnä¸?˜q™æ ·ä¸€æ?ž®±å¯ä»¥å‡ž®‘解析的旉™—´òq¶å‡ž®‘那些由Column歧义引è“v的语法错è¯?
åQ?5åQ?用EXISTS替代IN、用NOT EXISTS替代NOT INåQ?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?6åQ?识别'低效执行'çš„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?7åQ?用烦引提高效率:
索引是表的一个概念部åˆ?用来提高‹‚€ç´¢æ•°æ®çš„æ•ˆçއåQŒORACLE使用了一个复杂的自åã^è¡¡B-tree¾l“æž„. 通常,通过索引查询数据比全表扫描要å¿? 当ORACLE扑ևºæ‰§è¡ŒæŸ¥è¯¢å’ŒUpdate语句的最佌™µ\径时, ORACLE优化器将使用索引. 同样在联¾l“多个表时ä‹É用烦引也可以提高效率. 另一个ä‹É用烦引的好处æ˜?它提供了主键(primary key)的唯一性验è¯?。那些LONG或LONG RAW数据¾cÕdž‹, 你可以烦引几乎所有的åˆ? 通常, 在大型表中ä‹É用烦引特别有æ•? 当然,你也会发çŽ? 在扫描小表时,使用索引同样能提高效çŽ? 虽然使用索引能得到查询效率的提高,但是我们也必™åÀL³¨æ„åˆ°å®ƒçš„代ä­h. 索引需要空间来存储,也需要定期维æŠ? 每当有记录在表中增减或烦引列被修æ”ÒŽ—¶, 索引本èín也会被修æ”? ˜q™æ„å‘³ç€æ¯æ¡è®°å½•çš„INSERT , DELETE , UPDATEž®†äؓ此多付出4 , 5 ‹Æ¡çš„¼‚ç›˜I/O . å› äØ“ç´¢å¼•éœ€è¦é¢å¤–çš„å­˜å‚¨½Iºé—´å’Œå¤„ç?那些不必要的索引反而会使查询反应时间变æ…?。定期的重构索引是有必要çš?åQ?br /> ALTER  INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
åQ?8åQ?用EXISTS替换DISTINCTåQ?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?9åQ?sql语句用大写的åQ›å› ä¸ºoracleæ€ÀL˜¯å…ˆè§£æžsql语句åQŒæŠŠž®å†™çš„字母è{换成大写的再执行
åQ?0åQ?在java代码中尽量少用连接符“åQ?#8221;˜qžæŽ¥å­—符ä¸ÔŒ¼
åQ?1åQ?避免在烦引列上ä‹É用NOT 通常åQŒã€€
我们要避免在索引列上使用NOT, NOT会äñ”生在和在索引列上使用函数相同的媄å“? 当ORACLE”遇到”NOT,他就会停止ä‹É用烦引è{而执行全表扫æ?
åQ?2åQ?避免在烦引列上ä‹É用计½Ž—.
WHERE子句中,如果索引列是函数的一部分åQŽä¼˜åŒ–器ž®†ä¸ä½¿ç”¨ç´¢å¼•而ä‹É用全表扫描.
举例:
低效åQ?
SELECT … FROM  DEPT  WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
åQ?3åQ?ç”?gt;=替代>
高效:
SELECT * FROM  EMP  WHERE  DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMSž®†ç›´æŽ¥èŸ©åˆ°ç¬¬ä¸€ä¸ªDEPT½{‰äºŽ4的记录而后者将首先定位到DEPTNO=3çš„è®°å½•åÆˆä¸”å‘å‰æ‰«æåˆ°½W¬ä¸€ä¸ªDEPT大于3的记å½?
åQ?4åQ?用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?5åQ?用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?6åQ?避免在烦引列上ä‹É用IS NULLå’ŒIS NOT NULL
避免在烦引中使用ä»ÖM½•可以为空的列åQŒORACLEž®†æ— æ³•ä‹É用该索引åQŽå¯¹äºŽå•列烦引,如果列包含空å€û|¼Œç´¢å¼•中将不存在此记录. 对于复合索引åQŒå¦‚æžœæ¯ä¸ªåˆ—éƒ½äØ“½Iºï¼Œç´¢å¼•中同样不存在此记å½? 如果臛_°‘æœ‰ä¸€ä¸ªåˆ—ä¸äØ“½Iºï¼Œåˆ™è®°å½•存在于索引中.举例: 如果唯一性烦引徏立在表的A列和B列上, òq¶ä¸”表中存在一条记录的A,Bå€égØ“(123,null) , ORACLEž®†ä¸æŽ¥å—下一条具有相同A,Bå€û|¼ˆ123,nullåQ‰çš„记录(插入). 然而如果所有的索引列都为空åQŒORACLEž®†è®¤ä¸ºæ•´ä¸ªé”®å€égØ“½Iø™€Œç©ºä¸ç­‰äºŽç©º. 因此你可以插å…?000 条具有相同键值的记录,当然它们都是½I? 因䨓½Iºå€ég¸å­˜åœ¨äºŽçƒ¦å¼•列ä¸?所以WHERE子句中对索引列进行空值比较将使ORACLE停用该烦å¼?
低效: (索引失效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE >=0;
åQ?7åQ?æ€ÀL˜¯ä½¿ç”¨ç´¢å¼•的第一个列åQ?br /> 如果索引是徏立在多个列上, 只有在它的第一个列(leading column)被where子句引用æ—?优化器才会选择使用该烦å¼? ˜q™ä¹Ÿæ˜¯ä¸€æ¡ç®€å•而重要的规则åQŒå½“仅引用烦引的½W¬äºŒä¸ªåˆ—æ—?优化器ä‹É用了全表扫描而忽略了索引
åQ?8åQ?用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_SIZE˜q™å—内存. 对于˜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?9åQ?用WHERE替代ORDER BYåQ?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?0åQ?避免改变索引列的¾cÕdž‹.:
当比较不同数据类型的数据æ—? ORACLE自动对列˜q›è¡Œ½Ž€å•çš„¾cÕdž‹è½¬æ¢.
假设 EMPNO是一个数值类型的索引�
SELECT …  FROM EMP  WHERE  EMPNO = ‘123'
实际ä¸?¾lè¿‡ORACLE¾cÕdž‹è½¬æ¢, 语句转化ä¸?
SELECT …  FROM EMP  WHERE  EMPNO = TO_NUMBER(‘123')
òq¸è¿çš„æ˜¯,¾cÕdž‹è½¬æ¢æ²¡æœ‰å‘生在烦引列ä¸?索引的用途没有被改变.
现在,假设EMP_TYPE是一个字½W¦ç±»åž‹çš„索引åˆ?
SELECT …  FROM EMP  WHERE EMP_TYPE = 123
˜q™ä¸ªè¯­å¥è¢«ORACLE转换ä¸?
SELECT …  FROM EMP  WHERETO_NUMBER(EMP_TYPE)=123
å› äØ“å†…éƒ¨å‘ç”Ÿçš„ç±»åž‹è{æ? ˜q™ä¸ªç´¢å¼•ž®†ä¸ä¼šè¢«ç”¨åˆ°! ä¸ÞZº†é¿å…ORACLE对你的SQL˜q›è¡Œéšå¼çš„类型è{æ? 最好把¾cÕdž‹è½¬æ¢ç”¨æ˜¾å¼è¡¨çŽ°å‡ºæ? 注意当字½W¦å’Œæ•°å€¼æ¯”较时, ORACLE会优先è{换数值类型到字符¾cÕdž‹
åQ?1åQ?需要当心的WHERE子句:
某些SELECT 语句中的WHERE子句不ä‹É用烦å¼? ˜q™é‡Œæœ‰ä¸€äº›ä¾‹å­?
在下面的例子é‡? (1)‘!=' ž®†ä¸ä½¿ç”¨ç´¢å¼•. è®îC½, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表ä¸? (2) ‘||'是字½W¦è¿žæŽ¥å‡½æ•? ž®Þp±¡å…¶ä»–函数那样, 停用了烦å¼? (3) ‘+'是数学函æ•? ž®Þp±¡å…¶ä»–数学函数那样, 停用了烦å¼? (4)相同的烦引列不能互相比较,˜q™å°†ä¼šå¯ç”¨å…¨è¡¨æ‰«æ?
åQ?2åQ?a. 如果‹‚€ç´¢æ•°æ®é‡­‘…过30%的表中记录数.使用索引ž®†æ²¡æœ‰æ˜¾è‘—的效率提高.
b. 在特定情况下, 使用索引也许会比全表扫描æ…? 但这是同一个数量çñ”上的区别. 而通常情况ä¸?使用索引比全表扫描要块几倍乃臛_‡ åƒå€?
åQ?3åQ?避免使用耗费资源的操ä½?
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎
执行耗费资源的排åº?SORT)功能. DISTINCT需要一‹Æ¡æŽ’序操ä½? 而其他的臛_°‘需要执行两‹Æ¡æŽ’åº? 通常, 带有UNION, MINUS , INTERSECTçš„SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑çš? 毕竟它们的可è¯ÀL€§å¾ˆå¼?br /> åQ?4åQ?优化GROUP BY:
提高GROUP BY 语句的效çŽ? 可以通过ž®†ä¸éœ€è¦çš„记录在GROUP BY 之前˜q‡æ×oæŽ?下面两个查询˜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Œè{载请标明出处åQšhttp://blog.csdn.net/fuwei2241/archive/2006/09/06/1185198.aspx



fly 2010-10-12 11:59 发表评论
]]>
Oracle中的BLOBå’ŒCLOBè¯Õd–http://www.aygfsteel.com/jlin/articles/328130.htmlflyflyFri, 06 Aug 2010 06:20:00 GMThttp://www.aygfsteel.com/jlin/articles/328130.htmlhttp://www.aygfsteel.com/jlin/comments/328130.htmlhttp://www.aygfsteel.com/jlin/articles/328130.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/328130.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/328130.html一、区别和定义

      LONG: 可变长的字符ä¸?/font>数据åQŒæœ€é•?GåQŒLONGå…ähœ‰VARCHAR2列的ç‰ÒŽ€§ï¼Œå¯ä»¥å­˜å‚¨é•¿æ–‡æœ¬ä¸€ä¸ªè¡¨ä¸­æœ€å¤šä¸€ä¸ª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字段实际的文件存储在文äšg¾pȝ»Ÿä¸?字段中存储的是文件定位指é’?bfile对oracle来说是只è¯Èš„,也不参与事务性控制和数据恢复.
  
  CLOBåQŒNCLOBåQŒBLOB都是内部çš?font color="#993300">LOB(Large Object)
¾cÕdž‹åQŒæœ€é•?GåQŒæ²¡æœ‰LONG只能有一列的限制

  要保存图片、文本文件、Wordæ–‡äšg各自最好用哪种数据¾cÕdž‹?
  --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是传入的字符ä¸ÔŒ¼Œå®šä¹‰åQšString 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();


]]>
jdbc事务处理机制(�http://www.aygfsteel.com/jlin/articles/323881.htmlflyflySat, 19 Jun 2010 13:07:00 GMThttp://www.aygfsteel.com/jlin/articles/323881.htmlhttp://www.aygfsteel.com/jlin/comments/323881.htmlhttp://www.aygfsteel.com/jlin/articles/323881.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/323881.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/323881.html  事务处理

  信息是ä“Q何企事业单位的重要资产,ä»ÖM½•企业部门都包含着信息的流入、流出,ä»ÖM½•企业部门都控制着某些信息。同æ—Óž¼Œä¿¡æ¯å¿…须在适当的时æœÞZ¼ æ’­ç»™éœ€è¦çš„人。而且åQŒä¿¡æ¯è¿˜éœ€è¦å®‰å…¨çº¦æŸï¼Œé€šå¸¸æ ÒŽ®ä¿¡æ¯çš„类型和内容实施讉K—®æŽ§åˆ¶ã€‚äØ“äº†ä¿è¯æ•°æ®çš„å®‰å…¨æœ‰æ•ˆå’Œæ­£¼‹®å¯é ï¼Œæ•°æ®åº“管理系¾lŸï¼ˆDBMSåQ‰å¿…™åÀLä¾›ç»Ÿä¸€çš„æ•°æ®ä¿æŠ¤åŠŸèƒ½ã€?

  事务是现代数据库理论中的核心概念之一。如果一¾l„处理步骤或者全部发生或者一步也不执行,我们¿U°è¯¥¾l„å¤„ç†æ­¥éª¤äØ“ä¸€ä¸ªäº‹åŠ¡ã€‚å½“æ‰€æœ‰çš„æ­¥éª¤åƒä¸€ä¸ªæ“ä½œä¸€æ ¯‚¢«å®Œæ•´åœ°æ‰§è¡Œï¼Œæˆ‘们¿U°è¯¥äº‹åŠ¡è¢«æäº¤ã€‚ç”±äºŽå…¶ä¸­çš„ä¸€éƒ¨åˆ†æˆ–å¤šæ­¥æ‰§è¡Œå¤±è´¥ï¼Œå¯ÆD‡´æ²¡æœ‰æ­¥éª¤è¢«æäº¤ï¼Œåˆ™äº‹åŠ¡å¿…™åÕd›žæ»šï¼ˆå›žåˆ°æœ€åˆçš„¾pȝ»ŸçŠ¶æ€ï¼‰ã€‚äº‹åŠ¡å¿…™åÀLœä»ŽISO/IEC所制定的ACID原则。ACID是原子性(atomicityåQ‰ã€ä¸€è‡´æ€§ï¼ˆconsistencyåQ‰ã€é𔼛ÀL€§ï¼ˆisolationåQ‰å’ŒæŒä¹…性(durabilityåQ‰çš„¾~©å†™ã€‚事务的原子性表½CÞZº‹åŠ¡æ‰§è¡Œè¿‡½E‹ä¸­çš„ä“Q何失败都ž®†å¯¼è‡´äº‹åŠ¡æ‰€åšçš„ä»ÖM½•修改失效。一致性表½Cºå½“事务执行å¤ÞpÓ|æ—Óž¼Œæ‰€æœ‰è¢«è¯¥äº‹åŠ¡åª„å“çš„æ•°æ®éƒ½åº”è¯¥æ¢å¤åˆ°äº‹åŠ¡æ‰§è¡Œå‰çš„çŠ¶æ€ã€‚éš”¼›ÀL€§è¡¨½Cºåœ¨äº‹åŠ¡æ‰§è¡Œ˜q‡ç¨‹ä¸­å¯¹æ•°æ®çš„修改,在事务提交之前对其他事务不可见。持久性表½Cºå·²æäº¤çš„æ•°æ®åœ¨äº‹åŠ¡æ‰§è¡Œå¤ÞpÓ|æ—Óž¼Œæ•°æ®çš„状态都应该正确ã€?

  在下面我们列举一个ä‹É用SQL Server数据库进行事务处理的例子。主表是一个规章制度信息表åQˆbylawåQ‰ï¼Œä¸»è¦å­—段有记录编受÷€æ ‡é¢˜ã€ä½œè€…、书写日期等。两个子表分别是附äšg表(bylaw_affixåQ‰å’Œæ–‡æœ¬ä¿¡æ¯è¡¨ï¼ˆbylaw_contentåQ‰ã€‚表¾l“构见图1所½Cºã€‚bylaw表的记录¾~–号与bylaw_affix表的记录¾~–号、bylaw_content表的记录¾~–号是对应的åQŒæ¯‹Æ¡å¯¹è§„章制度信息的操作也ž®±æ˜¯å¯¹è¿™ä¸‰ä¸ªè¡¨çš„联合操作。例如要删除规章制度中的一条记录,如果不ä‹É用事务,ž®±å¯èƒ½ä¼šå‡ºçް˜q™æ ·çš„æƒ…况:½W¬ä¸€ä¸ªè¡¨ä¸­æˆåŠŸåˆ é™¤åŽåQŒæ•°æ®åº“½Hç„¶å‡ºçŽ°æ„å¤–çŠ¶å†µåQŒè€Œç¬¬äºŒã€ä¸‰ä¸ªè¡¨ä¸­çš„æ“ä½œæ²¡æœ‰å®ŒæˆåQŒè¿™æ øP¼Œåˆ é™¤æ“ä½œòq¶æ²¡æœ‰å®Œæˆï¼Œç”šè‡³å·²ç»ç ´åæ•°æ®åº“中的数据。要避免˜q™ç§æƒ…况åQŒå°±åº”该使用事务åQŒå®ƒçš„作用是åQšè¦ä¹ˆä¸‰ä¸ªè¡¨éƒ½æ“ä½œæˆåŠŸï¼Œè¦ä¹ˆéƒ½å¤±è´¥ã€‚æ¢å¥è¯è¯ß_¼Œž®±æ˜¯ä¿æŒæ•°æ®çš„一致性。所以,ä¸ÞZº†¼‹®ä¿å¯ÒŽ•°æ®æ“ä½œçš„完整和一è‡ß_¼Œåœ¨ç¨‹åºè®¾è®¡æ—¶è¦å……分考虑åˆîCº‹åŠ¡å¤„ç†æ–¹é¢çš„é—®é¢˜ã€?


å›? ½CÞZ¾‹è¡¨ç»“æž?

  Java中的事务处理

  一般情况下åQŒJ2EE应用服务器支持JDBC事务、JTAåQˆJava Transaction APIåQ‰äº‹åŠ¡ã€å®¹å™¨ç®¡ç†äº‹åŠ¡ã€‚ä¸€èˆ¬æƒ…å†µä¸‹åQŒæœ€å¥½ä¸è¦åœ¨½E‹åºä¸­åŒæ—¶ä‹É用上˜qîC¸‰¿Uäº‹åŠ¡ç±»åž‹ï¼Œæ¯”å¦‚åœ¨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()æ–ÒŽ³•åQŒSQL语句不会得到事务¼‹®è®¤ã€‚在最˜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Œå®ƒæ˜¯æ˜qîCº‹åŠ¡æŽ¥å£ï¼ˆæ¯”å¦‚ UserTransaction 接口åQŒå¼€å‘äh员直接ä‹É用该接口或者通过 J2EE 容器使用该接口来¼‹®ä¿ä¸šåŠ¡é€»è¾‘èƒ½å¤Ÿå¯é åœ°è¿è¡Œï¼‰çš?J2EE 模型的一部分。JTA å…ähœ‰çš„三个主要的接口分别æ˜?UserTransaction 接口、TransactionManager 接口å’?Transaction 接口。这些接口共享公å…Þqš„事务操作åQŒä¾‹å¦?commit() å’?rollback()åQ?但是也包含特ŒDŠçš„事务操作åQŒä¾‹å¦?suspend()åQŒresume() å’?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 />

]]>
oracle SQL性能优化(�http://www.aygfsteel.com/jlin/articles/322785.htmlflyflyFri, 04 Jun 2010 10:00:00 GMThttp://www.aygfsteel.com/jlin/articles/322785.htmlhttp://www.aygfsteel.com/jlin/comments/322785.htmlhttp://www.aygfsteel.com/jlin/articles/322785.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/322785.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/322785.htmloracle SQL性能优化 收藏
        我们要做åˆîC¸ä½†ä¼šå†™SQL,˜q˜è¦åšåˆ°å†™å‡ºæ€§èƒ½ä¼˜è‰¯çš„SQL,ä»¥ä¸‹ä¸ºç¬”è€…å­¦ä¹ ã€æ‘˜å½•ã€åÆˆæ±‡æ€»éƒ¨åˆ†èµ„æ–™ä¸Žå¤§å®¶åˆ†äínåQ?
åQ?åQ?nbsp;     选择最有效率的表名™åºåº(只在åŸÞZºŽè§„则的优化器中有æ•?åQ?br /> ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名åQŒFROM子句中写在最后的è¡?基础è¡?driving table)ž®†è¢«æœ€å…ˆå¤„理,在FROM子句中包含多个表的情况下,ä½ å¿…™å»é€‰æ‹©è®°å½•条数最ž®‘的表作为基¼‹€è¡¨ã€‚如果有3个以上的表连接查è¯? 那就需要选择交叉è¡?intersection table)ä½œäØ“åŸºç¡€è¡? 交叉表是指那个被其他表所引用的表.
åQ?åQ?nbsp;     WHERE子句中的˜qžæŽ¥™åºåºåQŽï¼š
ORACLE采用自下而上的顺序解析WHERE子句,æ ÒŽ®˜q™ä¸ªåŽŸç†,表之间的˜qžæŽ¥å¿…须写在其他WHERE条äšg之前, 那些可以˜q‡æ×o掉最大数量记录的条äš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替代DELETEåQ?br /> 当删除表中的记录æ—?在通常情况ä¸? 回滚ŒD?rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状æ€?准确地说是恢复到执行删除命ä×o之前的状å†? 而当˜qç”¨TRUNCATEæ—? 回滚ŒDµä¸å†å­˜æ”¾ä“Q何可被恢复的信息.当命令运行后,数据不能被恢å¤?因此很少的资源被调用,执行旉™—´ä¹Ÿä¼šå¾ˆçŸ­. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)
åQ?0åQ?ž®½é‡å¤šä‹É用COMMITåQ?br /> 只要有可èƒ?在程序中ž®½é‡å¤šä‹É用COMMIT, ˜q™æ ·½E‹åºçš„æ€§èƒ½å¾—到提高,需求也会因为COMMIT所释放的资源而减ž®?
COMMIT所释放的资�
a. 回滚ŒDµä¸Šç”¨äºŽæ¢å¤æ•°æ®çš„ä¿¡æ?
b. 被程序语句获得的�
c. redo log buffer 中的½Iºé—´
d. ORACLE为管理上˜q?¿Uèµ„源中的内部花è´?br /> åQ?1åQ?用Where子句替换HAVING子句åQ?br /> 避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集˜q›è¡Œ˜q‡æ×o. ˜q™ä¸ªå¤„理需要排åº?总计½{‰æ“ä½? 如果能通过WHERE子句限制记录的数ç›?那就能减ž®‘这斚w¢çš„开销. (非oracleä¸?on、where、having˜q™ä¸‰ä¸ªéƒ½å¯ä»¥åŠ æ¡ä»¶çš„å­å¥ä¸­ï¼Œon是最先执行,where‹Æ¡ä¹‹åQŒhavingæœ€åŽï¼Œå› äØ“on是先把不½W¦åˆæ¡äšg的记录过滤后才进行统计,它就可以减少中间˜qç®—要处理的数据åQŒæŒ‰ç†è¯´åº”该速度是最快的åQŒwhere也应该比havingå¿«ç‚¹çš„ï¼Œå› äØ“å®ƒè¿‡æ»¤æ•°æ®åŽæ‰è¿›è¡ŒsumåQŒåœ¨ä¸¤ä¸ªè¡¨è”接时才用on的,所以在一个表的时候,ž®±å‰©ä¸‹whereè·Ÿhaving比较了。在˜q™å•表查询统计的情况下,如果要过滤的条äšg没有涉及到要计算字段åQŒé‚£å®ƒä»¬çš„结果是一æ ïLš„åQŒåªæ˜¯where可以使用rushmore技术,而havingž®×ƒ¸èƒ½ï¼Œåœ¨é€Ÿåº¦ä¸ŠåŽè€…要慢如果要涉及到计½Ž—的字段åQŒå°±è¡¨ç¤ºåœ¨æ²¡è®¡ç®—之前åQŒè¿™ä¸ªå­—ŒD늚„值是不确定的åQŒæ ¹æ®ä¸Š½‹‡å†™çš„工作流½E‹ï¼Œwhere的作用时间是在计½Ž—之前就完成的,而havingž®±æ˜¯åœ¨è®¡½Ž—后才è“v作用的,所以在˜q™ç§æƒ…况下,两者的¾l“果会不同。在多表联接查询æ—Óž¼Œon比where更早起作用。系¾lŸé¦–先根据各个表之间的联接条ä»Óž¼ŒæŠŠå¤šä¸ªè¡¨åˆæˆä¸€ä¸ªäÍ时表后,再由where˜q›è¡Œ˜q‡æ×oåQŒç„¶åŽå†è®¡ç®—åQŒè®¡½Ž—完后再由having˜q›è¡Œ˜q‡æ×o。由此可见,要想˜q‡æ×o条äšg起到正确的作用,首先要明白这个条件应该在什么时候è“v作用åQŒç„¶åŽå†å†›_®šæ”‘Öœ¨é‚£é‡Œ
åQ?2åQ?减少对表的查询:
在含有子查询的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?3åQ?通过内部函数提高SQL效率.åQ?br /> 复杂的SQL往往牺牲了执行效çŽ? 能够掌握上面的运用函数解决问题的æ–ÒŽ³•在实际工作中是非常有意义çš?br /> åQ?4åQ?使用表的别名(Alias)åQ?br /> 当在SQL语句中连接多个表æ—? 请ä‹Éç”¨è¡¨çš„åˆ«ååÆˆæŠŠåˆ«åå‰¾~€äºŽæ¯ä¸ªColumnä¸?˜q™æ ·ä¸€æ?ž®±å¯ä»¥å‡ž®‘解析的旉™—´òq¶å‡ž®‘那些由Column歧义引è“v的语法错è¯?
åQ?5åQ?用EXISTS替代IN、用NOT EXISTS替代NOT INåQ?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?6åQ?识别'低效执行'çš„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?7åQ?用烦引提高效率:
索引是表的一个概念部åˆ?用来提高‹‚€ç´¢æ•°æ®çš„æ•ˆçއåQŒORACLE使用了一个复杂的自åã^è¡¡B-tree¾l“æž„. 通常,通过索引查询数据比全表扫描要å¿? 当ORACLE扑ևºæ‰§è¡ŒæŸ¥è¯¢å’ŒUpdate语句的最佌™µ\径时, ORACLE优化器将使用索引. 同样在联¾l“多个表时ä‹É用烦引也可以提高效率. 另一个ä‹É用烦引的好处æ˜?它提供了主键(primary key)的唯一性验è¯?。那些LONG或LONG RAW数据¾cÕdž‹, 你可以烦引几乎所有的åˆ? 通常, 在大型表中ä‹É用烦引特别有æ•? 当然,你也会发çŽ? 在扫描小表时,使用索引同样能提高效çŽ? 虽然使用索引能得到查询效率的提高,但是我们也必™åÀL³¨æ„åˆ°å®ƒçš„代ä­h. 索引需要空间来存储,也需要定期维æŠ? 每当有记录在表中增减或烦引列被修æ”ÒŽ—¶, 索引本èín也会被修æ”? ˜q™æ„å‘³ç€æ¯æ¡è®°å½•çš„INSERT , DELETE , UPDATEž®†äؓ此多付出4 , 5 ‹Æ¡çš„¼‚ç›˜I/O . å› äØ“ç´¢å¼•éœ€è¦é¢å¤–çš„å­˜å‚¨½Iºé—´å’Œå¤„ç?那些不必要的索引反而会使查询反应时间变æ…?。定期的重构索引是有必要çš?åQ?br /> ALTER  INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
åQ?8åQ?用EXISTS替换DISTINCTåQ?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?9åQ?sql语句用大写的åQ›å› ä¸ºoracleæ€ÀL˜¯å…ˆè§£æžsql语句åQŒæŠŠž®å†™çš„字母è{换成大写的再执行
åQ?0åQ?在java代码中尽量少用连接符“åQ?#8221;˜qžæŽ¥å­—符ä¸ÔŒ¼
åQ?1åQ?避免在烦引列上ä‹É用NOT 通常åQŒã€€
我们要避免在索引列上使用NOT, NOT会äñ”生在和在索引列上使用函数相同的媄å“? 当ORACLE”遇到”NOT,他就会停止ä‹É用烦引è{而执行全表扫æ?
åQ?2åQ?避免在烦引列上ä‹É用计½Ž—.
WHERE子句中,如果索引列是函数的一部分åQŽä¼˜åŒ–器ž®†ä¸ä½¿ç”¨ç´¢å¼•而ä‹É用全表扫描.
举例:
低效åQ?
SELECT … FROM  DEPT  WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
åQ?3åQ?ç”?gt;=替代>
高效:
SELECT * FROM  EMP  WHERE  DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMSž®†ç›´æŽ¥èŸ©åˆ°ç¬¬ä¸€ä¸ªDEPT½{‰äºŽ4的记录而后者将首先定位到DEPTNO=3çš„è®°å½•åÆˆä¸”å‘å‰æ‰«æåˆ°½W¬ä¸€ä¸ªDEPT大于3的记å½?
åQ?4åQ?用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?5åQ?用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?6åQ?避免在烦引列上ä‹É用IS NULLå’ŒIS NOT NULL
避免在烦引中使用ä»ÖM½•可以为空的列åQŒORACLEž®†æ— æ³•ä‹É用该索引åQŽå¯¹äºŽå•列烦引,如果列包含空å€û|¼Œç´¢å¼•中将不存在此记录. 对于复合索引åQŒå¦‚æžœæ¯ä¸ªåˆ—éƒ½äØ“½Iºï¼Œç´¢å¼•中同样不存在此记å½? 如果臛_°‘æœ‰ä¸€ä¸ªåˆ—ä¸äØ“½Iºï¼Œåˆ™è®°å½•存在于索引中.举例: 如果唯一性烦引徏立在表的A列和B列上, òq¶ä¸”表中存在一条记录的A,Bå€égØ“(123,null) , ORACLEž®†ä¸æŽ¥å—下一条具有相同A,Bå€û|¼ˆ123,nullåQ‰çš„记录(插入). 然而如果所有的索引列都为空åQŒORACLEž®†è®¤ä¸ºæ•´ä¸ªé”®å€égØ“½Iø™€Œç©ºä¸ç­‰äºŽç©º. 因此你可以插å…?000 条具有相同键值的记录,当然它们都是½I? 因䨓½Iºå€ég¸å­˜åœ¨äºŽçƒ¦å¼•列ä¸?所以WHERE子句中对索引列进行空值比较将使ORACLE停用该烦å¼?
低效: (索引失效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM  DEPARTMENT  WHERE  DEPT_CODE >=0;
åQ?7åQ?æ€ÀL˜¯ä½¿ç”¨ç´¢å¼•的第一个列åQ?br /> 如果索引是徏立在多个列上, 只有在它的第一个列(leading column)被where子句引用æ—?优化器才会选择使用该烦å¼? ˜q™ä¹Ÿæ˜¯ä¸€æ¡ç®€å•而重要的规则åQŒå½“仅引用烦引的½W¬äºŒä¸ªåˆ—æ—?优化器ä‹É用了全表扫描而忽略了索引
åQ?8åQ?用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_SIZE˜q™å—内存. 对于˜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?9åQ?用WHERE替代ORDER BYåQ?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?0åQ?避免改变索引列的¾cÕdž‹.:
当比较不同数据类型的数据æ—? ORACLE自动对列˜q›è¡Œ½Ž€å•çš„¾cÕdž‹è½¬æ¢.
假设 EMPNO是一个数值类型的索引�
SELECT …  FROM EMP  WHERE  EMPNO = ‘123'
实际ä¸?¾lè¿‡ORACLE¾cÕdž‹è½¬æ¢, 语句转化ä¸?
SELECT …  FROM EMP  WHERE  EMPNO = TO_NUMBER(‘123')
òq¸è¿çš„æ˜¯,¾cÕdž‹è½¬æ¢æ²¡æœ‰å‘生在烦引列ä¸?索引的用途没有被改变.
现在,假设EMP_TYPE是一个字½W¦ç±»åž‹çš„索引åˆ?
SELECT …  FROM EMP  WHERE EMP_TYPE = 123
˜q™ä¸ªè¯­å¥è¢«ORACLE转换ä¸?
SELECT …  FROM EMP  WHERETO_NUMBER(EMP_TYPE)=123
å› äØ“å†…éƒ¨å‘ç”Ÿçš„ç±»åž‹è{æ? ˜q™ä¸ªç´¢å¼•ž®†ä¸ä¼šè¢«ç”¨åˆ°! ä¸ÞZº†é¿å…ORACLE对你的SQL˜q›è¡Œéšå¼çš„类型è{æ? 最好把¾cÕdž‹è½¬æ¢ç”¨æ˜¾å¼è¡¨çŽ°å‡ºæ? 注意当字½W¦å’Œæ•°å€¼æ¯”较时, ORACLE会优先è{换数值类型到字符¾cÕdž‹
åQ?1åQ?需要当心的WHERE子句:
某些SELECT 语句中的WHERE子句不ä‹É用烦å¼? ˜q™é‡Œæœ‰ä¸€äº›ä¾‹å­?
在下面的例子é‡? (1)‘!=' ž®†ä¸ä½¿ç”¨ç´¢å¼•. è®îC½, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表ä¸? (2) ‘||'是字½W¦è¿žæŽ¥å‡½æ•? ž®Þp±¡å…¶ä»–函数那样, 停用了烦å¼? (3) ‘+'是数学函æ•? ž®Þp±¡å…¶ä»–数学函数那样, 停用了烦å¼? (4)相同的烦引列不能互相比较,˜q™å°†ä¼šå¯ç”¨å…¨è¡¨æ‰«æ?
åQ?2åQ?a. 如果‹‚€ç´¢æ•°æ®é‡­‘…过30%的表中记录数.使用索引ž®†æ²¡æœ‰æ˜¾è‘—的效率提高.
b. 在特定情况下, 使用索引也许会比全表扫描æ…? 但这是同一个数量çñ”上的区别. 而通常情况ä¸?使用索引比全表扫描要块几倍乃臛_‡ åƒå€?
åQ?3åQ?避免使用耗费资源的操ä½?
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎
执行耗费资源的排åº?SORT)功能. DISTINCT需要一‹Æ¡æŽ’序操ä½? 而其他的臛_°‘需要执行两‹Æ¡æŽ’åº? 通常, 带有UNION, MINUS , INTERSECTçš„SQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑çš? 毕竟它们的可è¯ÀL€§å¾ˆå¼?br /> åQ?4åQ?优化GROUP BY:
提高GROUP BY 语句的效çŽ? 可以通过ž®†ä¸éœ€è¦çš„记录在GROUP BY 之前˜q‡æ×oæŽ?下面两个查询˜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Œè{载请标明出处åQšhttp://blog.csdn.net/fuwei2241/archive/2006/09/06/1185198.aspx



]]>
oracle procedure问题的解��http://www.aygfsteel.com/jlin/articles/321376.htmlflyflyWed, 19 May 2010 06:54:00 GMThttp://www.aygfsteel.com/jlin/articles/321376.htmlhttp://www.aygfsteel.com/jlin/comments/321376.htmlhttp://www.aygfsteel.com/jlin/articles/321376.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/321376.htmlhttp://www.aygfsteel.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;




]]>
java.sql.SQLException: ORA-00911: invalid character 解决æ–ÒŽ³•(è½?http://www.aygfsteel.com/jlin/articles/317591.htmlflyflyTue, 06 Apr 2010 13:42:00 GMThttp://www.aygfsteel.com/jlin/articles/317591.htmlhttp://www.aygfsteel.com/jlin/comments/317591.htmlhttp://www.aygfsteel.com/jlin/articles/317591.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/317591.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/317591.htmljava.sql.SQLException: ORA-00911: invalid character
2008òq?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>



]]>
oracle sql in中数据不能超˜q?000个的解决æ–ÒŽ³•ã€?/title><link>http://www.aygfsteel.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.aygfsteel.com/jlin/articles/309076.html</guid><wfw:comment>http://www.aygfsteel.com/jlin/comments/309076.html</wfw:comment><comments>http://www.aygfsteel.com/jlin/articles/309076.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jlin/comments/commentRss/309076.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jlin/services/trackbacks/309076.html</trackback:ping><description><![CDATA[在Oracle中,sql中in不能­‘…过1000个,比如åQšselect  * from table  t where t.id in (1,2,3,......1001,1002)<br /> ¾pȝ»Ÿž®†æŠ¥é”™ï¼Œè§£å†³åŠžæ³•å¦‚ä¸‹åQŒå†™æˆä¸¤ä¸ªæˆ–者多个。如åQšt.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.aygfsteel.com/jlin/aggbug/309076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jlin/" target="_blank">fly</a> 2010-01-11 22:48 <a href="http://www.aygfsteel.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.aygfsteel.com/jlin/articles/300737.htmlflyflyMon, 02 Nov 2009 07:51:00 GMThttp://www.aygfsteel.com/jlin/articles/300737.htmlhttp://www.aygfsteel.com/jlin/comments/300737.htmlhttp://www.aygfsteel.com/jlin/articles/300737.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/300737.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/300737.html 
Start with...Connect By子句递归查询一般用于一个表¾l´æŠ¤æ ‘åÅž¾l“构的应用ã€?/div>
创徏½CÞZ¾‹è¡¨ï¼š
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

作者BlogåQ?/strong>http://blog.csdn.net/54powerman/


]]>oracle Oracle分页查询(�http://www.aygfsteel.com/jlin/articles/291681.htmlflyflyTue, 18 Aug 2009 10:06:00 GMThttp://www.aygfsteel.com/jlin/articles/291681.htmlhttp://www.aygfsteel.com/jlin/comments/291681.htmlhttp://www.aygfsteel.com/jlin/articles/291681.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/291681.htmlhttp://www.aygfsteel.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 <= 40˜q™å¥ä¸Šã€?/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限制条äšgåQŒå°±¾lˆæ­¢æŸ¥è¯¢ž®†ç»“果返回了ã€?/p>

而第二个查询语句åQŒç”±äºŽæŸ¥è¯¢æ¡ä»¶BETWEEN 21 AND 40是存在于查询的第三层åQŒè€ŒOracle无法ž®†ç¬¬ä¸‰å±‚的查询条件推到最内层åQˆå³ä½¿æŽ¨åˆ°æœ€å†…å±‚ä¹Ÿæ²¡æœ‰æ„ä¹‰ï¼Œå› äØ“æœ€å†…å±‚æŸ¥è¯¢ä¸çŸ¥é“RN代表什么)。因此,对于½W¬äºŒä¸ªæŸ¥è¯¢è¯­å¥ï¼ŒOracle最内层˜q”回¾l™ä¸­é—´å±‚的是所有满­‘Ïx¡ä»¶çš„æ•°æ®åQŒè€Œä¸­é—´å±‚˜q”回¾l™æœ€å¤–层的也是所有数据。数据的˜q‡æ×o在最外层完成åQŒæ˜¾ç„¶è¿™ä¸ªæ•ˆçŽ‡è¦æ¯”ç¬¬ä¸€ä¸ªæŸ¥è¯¢ä½Žå¾—å¤šã€?/p>

上面分析的查询不仅仅是针对单表的½Ž€å•查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一æ ähœ‰æ•ˆã€?/p>

˜q™é‡Œž®×ƒ¸å¯¹åŒ…含排序的查询˜q›è¡Œè¯´æ˜Žäº†ï¼Œä¸‹ä¸€½‹‡æ–‡ç« ä¼šé€šè¿‡ä¾‹å­æ¥è¯¦¾l†è¯´æ˜Žã€‚下面简单讨è®ÞZ¸€ä¸‹å¤šè¡¨è”åˆçš„æƒ…å†µã€‚å¯¹äºŽæœ€å¸¸è§çš„ç­‰å€ÆD¡¨˜qžæŽ¥æŸ¥è¯¢åQŒCBO一般可能会采用两种˜qžæŽ¥æ–¹å¼NESTED LOOPå’ŒHASH JOINåQˆMERGE JOIN效率比HASH JOIN效率低,一般CBO不会考虑åQ‰ã€‚在˜q™é‡ŒåQŒç”±äºŽä‹É用了分页åQŒå› æ­¤æŒ‡å®šäº†ä¸€ä¸ªè¿”回的最大记录数åQŒNESTED LOOP在返回记录数­‘…过最大值时可以马上停止òq¶å°†¾l“æžœ˜q”回¾l™ä¸­é—´å±‚åQŒè€ŒHASH JOIN必须处理完所有结果集åQˆMERGE 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,       --排序¾cÕdž‹(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 ';
         
        --得到排序¾cÕdž‹è¯­å¥
        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•°(1¾lŸè®¡,0不统è®?</param>
  /// <param name="iOrderType">排序¾cÕdž‹(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);//排序¾cÕdž‹
   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™åˆ†™å‰|ާä»?如DataGrid¾l‘定数据æº?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="记录æ€ÀL•°åQ?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中不支持子查询排åº?临时表耗费资源不推荐ä‹Éç”?



]]>
融会贯通Oracle数据库的25条基本知��http://www.aygfsteel.com/jlin/articles/288107.htmlflyflyThu, 23 Jul 2009 14:26:00 GMThttp://www.aygfsteel.com/jlin/articles/288107.htmlhttp://www.aygfsteel.com/jlin/comments/288107.htmlhttp://www.aygfsteel.com/jlin/articles/288107.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/288107.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/288107.html

2.每个数据库最ž®‘有一个控制文ä»Óž¼ˆå»ø™®®3个,分别攑֜¨ä¸åŒçš„磁盘上åQ‰ã€?


3.每个数据库最ž®‘有一个表½Iºé—´åQˆSYSTEM表空é—ß_¼‰ã€?


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只能属于一个数据文ä»Óž¼Œå›_Œºé—ß_¼ˆextentåQ‰ä¸èƒ½è·¨­‘Šæ•°æ®æ–‡ä»¶ã€?


13.PCTFREEå’ŒPCTUSEDæ€Õd’Œä¸èƒ½å¤§äºŽ½{‰äºŽ100ã€?


14.单独一个事务不能跨­‘Šå¤šä¸ªå›žæ»šæ®µã€?


15.索引表不含ROWID倹{€?


16.拥有不同大小的回滚段没有ä»ÖM½•益处ã€?


17.COMMIT后,数据不一定立卛_†™ç›˜ï¼ˆæ•°æ®æ–‡äšgåQ‰ã€?


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可以åQŒNT不可以)ã€?


23.一套ORACLE数据库系¾lŸä¸­å¯ä»¥æœ‰å¤šä¸ªORACLE数据库及其相对应的实ä¾?ã€?


24.每个Oracle数据库拥有一个数据库实例åQˆINSTANCEåQ‰ï¼ˆOPS除外åQ‰ã€?


25.所以,一套操作系¾lŸä¸ŠåŒæ—¶å¯ä»¥æœ‰å¤šä¸ªOracle数据库实例启动ã€?


]]>
数据库连接的区别??http://www.aygfsteel.com/jlin/articles/262412.htmlflyflyFri, 27 Mar 2009 06:15:00 GMThttp://www.aygfsteel.com/jlin/articles/262412.htmlhttp://www.aygfsteel.com/jlin/comments/262412.htmlhttp://www.aygfsteel.com/jlin/articles/262412.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/262412.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/262412.html 1 关系代数
åˆåÆˆæ•°æ®é›†åˆçš„ç†è®ºåŸº¼‹€æ˜¯å…³¾pÖM»£æ•ŽÍ¼Œå®ƒæ˜¯ç”±E.F.Coddäº?970òq´æå‡ºçš„ã€?br /> 在关¾pÖM»£æ•°çš„形式化语­a€ä¸­ï¼š
ï?nbsp;        用表、或者数据集合表½Cºå…³¾pÀLˆ–者实体ã€?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Œä½œä¸ÞZ¸€¿Uå®žçŽ°çŽ°ä»£å…³¾pÖM»£æ•°è¿½Ž—çš„æ–ÒŽ³•åQŒSQL˜q˜æä¾›äº†åQ?br /> ï?nbsp;        子查询――类ä¼égºŽ˜qžæŽ¥åQŒä½†æ›´çµ‹z»ï¼›åœ¨å¤–部查询中åQŒæ–¹å¼å¯ä»¥ä‹É用表辑ּã€åˆ—表或者数据集合的地方都可以ä‹É用子查询的结果ã€?br /> 本章ž®†ä¸»è¦è®²˜q°å¤š¿Uç±»åž‹çš„˜qžæŽ¥ã€ç®€å•的和相关的子查询、几¿Uç±»åž‹çš„òq¶ã€å…³¾p»é™¤ä»¥åŠå…¶ä»–的内宏V€?br /> 2 使用˜qžæŽ¥
2.1 ˜qžæŽ¥¾cÕdž‹
在关¾pÖM»£æ•îC¸­åQŒè¿žæŽ¥è¿½Ž—是ç”׃¸€ä¸ªç¬›å¡å°”¿U¯è¿½Ž—和一个选取˜qç®—构成的。首先用½W›å¡ž®”积完成对两个数据集合的乘运½Ž—,然后对生成的¾l“果集合˜q›è¡Œé€‰å–˜qç®—åQŒç¡®ä¿åªæŠŠåˆ†åˆ«æ¥è‡ªä¸¤ä¸ªæ•°æ®é›†åˆåƈ且具有重叠部分的行合òq¶åœ¨ä¸€èµ—÷€‚连接的全部意义在于在水òqÏx–¹å‘ä¸ŠåˆåÆˆä¸¤ä¸ªæ•°æ®é›†åˆåQˆé€šå¸¸æ˜¯è¡¨åQ‰ï¼Œòq¶äñ”生一个新的结果集合,其方法是ž®†ä¸€ä¸ªæ•°æ®æºä¸­çš„行于另一个数据源中和它匹配的行组合成一个新元组ã€?br /> SQL提供了多¿Uç±»åž‹çš„˜qžæŽ¥æ–¹å¼åQŒå®ƒä»¬ä¹‹é—´çš„区别在于åQšä»Žç›æ€º’交叠的不同数据集合中选择用于˜qžæŽ¥çš„行时所采用的方法不同ã€?br /> ˜qžæŽ¥¾cÕdž‹         定义
内连æŽ?nbsp;        只连接匹配的è¡?br /> 左外˜qžæŽ¥         包含左边表的全部行(不管双™¾¹çš„表中是否存在与它们匚w…çš„行åQ‰ï¼Œä»¥åŠåŒ™¾¹è¡¨ä¸­å…¨éƒ¨åŒšw…çš„行
叛_¤–˜qžæŽ¥         包含双™¾¹è¡¨çš„全部行(不管左边的表中是否存在与它们匚w…çš„行åQ‰ï¼Œä»¥åŠå·¦è¾¹è¡¨ä¸­å…¨éƒ¨åŒšw…çš„行
全外˜qžæŽ¥         包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行ã€?br /> (H)(theta)˜qžæŽ¥         使用½{‰å€ég»¥å¤–的条äšg来匹配左、右两个表中的行
交叉˜qžæŽ¥         生成½W›å¡ž®”积åQå®ƒä¸ä‹É用ä“Q何匹配或者选取条äšgåQŒè€Œæ˜¯ç›´æŽ¥ž®†ä¸€ä¸ªæ•°æ®æºä¸­çš„æ¯ä¸ªè¡Œä¸Žå¦ä¸€ä¸ªæ•°æ®æºçš„æ¯ä¸ªè¡Œéƒ½ä¸€ä¸€åŒšw…
在INFORMIX中连接表的查è¯?br /> 如果FROM子句指定了多于一个表引用åQŒåˆ™æŸ¥è¯¢ä¼šè¿žæŽ¥æ¥è‡ªå¤šä¸ªè¡¨çš„行。连接条件指定各列之é—ß_¼ˆæ¯ä¸ªè¡¨è‡³ž®‘一列)˜q›è¡Œ˜qžæŽ¥çš„å…³¾p…R€‚因为正在比较连接条件中的列åQŒæ‰€ä»¥å®ƒä»¬å¿…™åÕd…·æœ‰ä¸€è‡´çš„æ•°æ®¾cÕdž‹ã€?br /> SELECT语句的FROM子句可以指定以下几种¾cÕdž‹çš„连æŽ?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 />
其中的outeråQŒå¦‚果不写则表示默认ã€?br /> 2.2 内连接(Inner JoinåQ?br /> 内连接是最常见的一¿Uè¿žæŽ¥ï¼Œå®ƒé¡µè¢«ç§°ä¸ºæ™®é€šè¿žæŽ¥ï¼Œè€ŒE.FCoddæœ€æ—©ç§°ä¹‹äØ“è‡ªç„¶˜qžæŽ¥ã€?br /> 下面是ANSI SQLåQ?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žæŽ¥å’Œå³å¤–连接,然后再ä‹Éç”¨æ¶ˆåŽ»é‡å¤è¡Œçš„åÆˆæ“ä½œž®†ä¸Š˜qîC¸¤ä¸ªç»“æžœé›†åˆåÆˆä¸ÞZ¸€ä¸ªç»“果集ã€?br /> 在现实生‹zÖM¸­åQŒå‚照完整性约束可以减ž®‘对于全外连接的使用å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Œå…¶æ•ˆæžœæ˜¯å®Œå…¨ä¸€æ ïLš„åQŒä½†å¯¹äºŽå¤–连接情况就不同了。当把条件加入到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 自èín˜qžæŽ¥
自èín˜qžæŽ¥æ˜¯æŒ‡åŒä¸€ä¸ªè¡¨è‡ªå·±ä¸Žè‡ªå·Þp¿›è¡Œè¿žæŽ¥ã€‚è¿™¿Uä¸€å…ƒè¿žæŽ¥é€šå¸¸ç”¨äºŽä»Žè‡ªåå…³¾p»ï¼ˆä¹Ÿç§°ä½œé€’归关系åQ‰ä¸­æŠ½å–数据。例如äh力资源数据库中雇员与老板的关¾p…R€?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™ç§¾cÕdž‹çš„结果集¿UîCØ“½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



]]>
½Ž€å•讲˜q°åŸºäºŽSQL SERVER 分页的存储过½E?è½?http://www.aygfsteel.com/jlin/articles/231463.htmlflyflySat, 27 Sep 2008 03:52:00 GMThttp://www.aygfsteel.com/jlin/articles/231463.htmlhttp://www.aygfsteel.com/jlin/comments/231463.htmlhttp://www.aygfsteel.com/jlin/articles/231463.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/231463.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/231463.html阅读全文

]]>
MS SQL 2000 存储˜q‡ç¨‹http://www.aygfsteel.com/jlin/articles/63054.htmlflyflyFri, 11 Aug 2006 09:09:00 GMThttp://www.aygfsteel.com/jlin/articles/63054.htmlhttp://www.aygfsteel.com/jlin/comments/63054.htmlhttp://www.aygfsteel.com/jlin/articles/63054.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/63054.htmlhttp://www.aygfsteel.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
-------------------------------------------------------------------------------------------------------------------------------------------------------
½CÞZ¾‹
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›è¡Œæ¨¡å¼åŒšw…åQŒå¦‚果没有提供参敎ͼŒåˆ™ä‹É用预讄¡š„默认倹{€?/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‹æ‰§è¡ŒæœŸé—´è®¾¾|®çš„æŸä¸ªå€¹{€‚下面的½CÞZ¾‹åˆ›å¾ä¸€ä¸ªå­˜å‚¨è¿‡½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>


参数名和变量名不一定要匚w…åQŒä¸˜q‡æ•°æ®ç±»åž‹å’Œå‚数位置必须匚w…åQˆé™¤éžä‹Éç”?@@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¶ä¸”新的执行计划不应高速缓存或存储在内存中åQŒWITH 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‹ä»¥åŠåšg˜qŸå¿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'

 



]]>
MSSQL数据¾cÕdž‹http://www.aygfsteel.com/jlin/articles/63051.htmlflyflyFri, 11 Aug 2006 09:06:00 GMThttp://www.aygfsteel.com/jlin/articles/63051.htmlhttp://www.aygfsteel.com/jlin/comments/63051.htmlhttp://www.aygfsteel.com/jlin/articles/63051.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/63051.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/63051.html4.3.1 整数数据¾cÕdž‹
    整数数据¾cÕdž‹æ˜¯æœ€å¸¸ç”¨çš„æ•°æ®ç±»åž‹ä¹‹ä¸€ã€?br />     1、INT åQˆINTEGERåQ?br />INT åQˆæˆ–INTEGERåQ‰æ•°æ®ç±»åž‹å­˜å‚¨ä»Ž-2çš?1‹Æ¡æ–¹ åQ?2 åQ?47 åQ?83 åQ?48åQ?åˆ?çš?1‹Æ¡æ–¹-1 åQ? åQ?47 åQ?83åQ?47åQ?之间的所有正负整数。每个INT ¾cÕdž‹çš„æ•°æ®æŒ‰4 个字节存储,其中1 位表½Cºæ•´æ•°å€¼çš„æ­£è´ŸåøP¼Œå…¶å®ƒ31 位表½Cºæ•´æ•°å€¼çš„长度和大ž®ã€?
     2、SMALLINT
SMALLINT 数据¾cÕdž‹å­˜å‚¨ä»?2çš?5‹Æ¡æ–¹åQ?-32åQ?768åQ?åˆ?çš?5‹Æ¡æ–¹-1åQ?32 åQ?67 åQ‰ä¹‹é—´çš„æ‰€æœ‰æ­£è´Ÿæ•´æ•°ã€‚每个SMALLINT ¾cÕdž‹çš„æ•°æ®å ç”? 个字节的存储½Iºé—´åQŒå…¶ä¸? 位表½Cºæ•´æ•°å€¼çš„æ­£è´ŸåøP¼Œå…¶å®ƒ15 位表½Cºæ•´æ•°å€¼çš„长度和大ž®ã€?br />     3、TINYINT
TINYINT数据¾cÕdž‹å­˜å‚¨ä»? åˆ?55 之间的所有正整数。每个TINYINT¾cÕdž‹çš„æ•°æ®å ç”? 个字节的存储½Iºé—´ã€?br />     4、BIGINT
BIGINT 数据¾cÕdž‹å­˜å‚¨ä»?2^63 åQ?9 åQ?23åQ?372åQ?036åQ?854åQ?775åQ?807åQ?åˆ?^63-1åQ?9åQ?223åQ?372åQ?036 åQ?54 åQ?75åQ?807åQ?之间的所有正负整数。每个BIGINT ¾cÕdž‹çš„æ•°æ®å ç”?个字节的存储½Iºé—´ã€?/p>

4.3.2 ‹¹®ç‚¹æ•°æ®¾cÕdž‹
    ‹¹®ç‚¹æ•°æ®¾cÕdž‹ç”¨äºŽå­˜å‚¨åè¿›åˆ¶å°æ•°ã€‚æÕQç‚ÒŽ•°å€¼çš„æ•°æ®åœ¨SQL Server 中采用上舍入åQˆRound up 或称为只入不舍)方式˜q›è¡Œå­˜å‚¨ã€‚所谓上舍入是指åQŒå½“åQˆä¸”仅当åQ‰è¦èˆå…¥çš„æ•°æ˜¯ä¸€ä¸ªéžé›¶æ•°æ—Óž¼Œå¯¹å…¶ä¿ç•™æ•°å­—部分的最低有效位上的数值加1 åQŒåƈ˜q›è¡Œå¿…要的进位。若一个数是上舍入敎ͼŒå…¶ç»å¯¹å€ég¸ä¼šå‡ž®‘。如åQšå¯¹3.14159265358979 分别˜q›è¡Œ2 位和12位舍入,¾l“æžœä¸?.15 å’?.141592653590ã€?br />     1、REAL 数据¾cÕdž‹
REAL数据¾cÕdž‹å¯ç²¾¼‹®åˆ°½W? 位小敎ͼŒå…¶èŒƒå›´äØ“ä»?3.40E -38 åˆ?.40E +38ã€?每个REAL¾cÕdž‹çš„æ•°æ®å ç”? 个字节的存储½Iºé—´ã€?br />     2、FLOAT
FLOAT数据¾cÕdž‹å¯ç²¾¼‹®åˆ°½W?5 位小敎ͼŒå…¶èŒƒå›´äØ“ä»?1.79E -308 åˆ?.79E +308ã€?每个FLOAT ¾cÕdž‹çš„æ•°æ®å ç”? 个字节的存储½Iºé—´ã€?FLOAT数据¾cÕdž‹å¯å†™ä¸ºFLOAT[ n ]çš„åŞ式。n 指定FLOAT 数据的精度。n ä¸?åˆ?5 之间的整数倹{€‚当n å? åˆ? æ—Óž¼Œå®žé™…上是定义了一个REAL ¾cÕdž‹çš„æ•°æ®ï¼Œ¾pȝ»Ÿç”? 个字节存储它åQ›å½“n å? åˆ?5 æ—Óž¼Œ¾pȝ»Ÿè®¤äؓ其是FLOAT ¾cÕdž‹åQŒç”¨8 个字节存储它ã€?br />     3、DECIMAL
DECIMAL数据¾cÕdž‹å¯ä»¥æä¾›ž®æ•°æ‰€éœ€è¦çš„实际存储½Iºé—´åQŒä½†ä¹Ÿæœ‰ä¸€å®šçš„限制åQŒæ‚¨å¯ä»¥ç”? åˆ?7 个字节来存储ä»?10çš?8‹Æ¡æ–¹-1 åˆ?0çš?8‹Æ¡æ–¹-1 之间的数倹{€‚可ž®†å…¶å†™äØ“DECIMAL[ p [s] ]çš„åŞ式,p å’Œs ¼‹®å®šäº†ç²¾¼‹®çš„æ¯”例和数位。其中p 表示可供存储的值的æ€ÖM½æ•ŽÍ¼ˆä¸åŒ…括小数点åQ‰ï¼Œ¾~ºçœå€égØ“18åQ?s 表示ž®æ•°ç‚¹åŽçš„位敎ͼŒ¾~ºçœå€égØ“0ã€?例如åQšdecimal åQ?5 5åQ‰ï¼Œè¡¨ç¤ºå…±æœ‰15 位数åQŒå…¶ä¸­æ•´æ•?0 位,ž®æ•°5ã€?位表4-3 列出了各¾_„¡¡®åº¦æ‰€éœ€çš„字节数之间的关¾p…R€?br /> 
     4、NUMERIC
NUMERIC数据¾cÕdž‹ä¸ŽDECIMAL数据¾cÕdž‹å®Œå…¨ç›¸åŒã€?br />注意åQšSQL Server ä¸ÞZº†å’Œå‰ç«¯çš„å¼€å‘å·¥å…·é…åˆï¼Œå…¶æ‰€æ”¯æŒçš„æ•°æ®ç²¾åº¦é»˜è®¤æœ€å¤§äØ“28位。但可以通过使用命ä×o来执行sqlserver.exe½E‹åºä»¥å¯åЍSQL ServeråQŒå¯æ”¹å˜é»˜è®¤¾_‘Öº¦ã€‚命令语法如下: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 数据¾cÕdž‹ç”¨äºŽå­˜å‚¨äºŒè¿›åˆ¶æ•°æ®ã€‚其定义形式为BINARYåQ?nåQ‰ï¼Œ n 表示数据的长度,取å€égØ“1 åˆ?000 。在使用时必™åÀLŒ‡å®šBINARY ¾cÕdž‹æ•°æ®çš„大ž®ï¼Œè‡›_°‘åº”äØ“1 个字节。BINARY ¾cÕdž‹æ•°æ®å ç”¨n+4 个字节的存储½Iºé—´ã€‚在输入数据时必™åÕdœ¨æ•°æ®å‰åŠ ä¸Šå­—½W¦â€?Xâ€?ä½œäØ“äºŒè¿›åˆ¶æ ‡è¯†ï¼Œå¦‚ï¼šè¦è¾“å…¥â€œabc ”则应输入â€?xabc ”。若输入的数据过长将会截掉其­‘…出部分。若输入的数据位æ•îCؓ奇数åQŒåˆ™ä¼šåœ¨èµ·å§‹½W¦å·â€?X ”后æ·ÕdР䏀ä¸?åQŒå¦‚上述的â€?xabc ”会被系¾lŸè‡ªåŠ¨å˜ä¸ºâ€?x0abc”ã€?
     2、VARBINARY
VARBINARY数据¾cÕdž‹çš„定义åÅžå¼äØ“VARBINARYåQˆnåQ‰ã€?它与BINARY ¾cÕdž‹ç›æ€¼¼åQŒn 的取å€ég¹Ÿä¸? åˆ?000åQ?若输入的数据˜q‡é•¿åQŒå°†ä¼šæˆªæŽ‰å…¶­‘…出部分。不同的是VARBINARY数据¾cÕdž‹å…ähœ‰å˜åŠ¨é•¿åº¦çš„ç‰¹æ€§ï¼Œå› äØ“VARBINARY数据¾cÕdž‹çš„å­˜å‚¨é•¿åº¦äØ“å®žé™…æ•°å€¼é•¿åº?4个字节。当BINARY数据¾cÕdž‹å…è®¸NULL 值时åQŒå°†è¢«è§†ä¸ºVARBINARY数据¾cÕdž‹ã€?br />一般情况下åQŒç”±äºŽBINARY 数据¾cÕdž‹é•¿åº¦å›ºå®šåQŒå› æ­¤å®ƒæ¯”VARBINARY ¾cÕdž‹çš„处理速度快ã€?/p>

4.3.4 逻辑数据¾cÕdž‹
    BITåQ?BIT数据¾cÕdž‹å ç”¨1 个字节的存储½Iºé—´åQŒå…¶å€égØ“0 æˆ? 。如果输å…? æˆ? 以外的å€û|¼Œž®†è¢«è§†äØ“1ã€?BIT ¾cÕdž‹ä¸èƒ½å®šä¹‰ä¸ºNULL å€û|¼ˆæ‰€è°“NULL 值是指空值或无意义的å€û|¼‰ã€?/p>

4.3.5 字符数据¾cÕdž‹
    字符数据¾cÕdž‹æ˜¯ä‹É用最多的数据¾cÕdž‹ã€‚它可以用来存储各种字母、数字符受÷€ç‰¹ŒDŠç¬¦å—÷€‚一般情况下åQŒä‹É用字½W¦ç±»åž‹æ•°æ®æ—¶™åÕdœ¨å…¶å‰åŽåŠ ä¸Šå•å¼•å·â€™æˆ–åŒå¼•å·â€?ã€?
     1 CHAR
CHAR 数据¾cÕdž‹çš„定义åÅžå¼äØ“CHAR[ åQˆnåQ?]ã€?以CHAR ¾cÕdž‹å­˜å‚¨çš„æ¯ä¸ªå­—½W¦å’Œ½W¦å·å ä¸€ä¸ªå­—节的存储½Iºé—´ã€‚n 表示所有字½W¦æ‰€å çš„存储½Iºé—´åQŒn 的取å€égØ“1 åˆ?000åQ?卛_¯å®¹çº³8000 个ANSI 字符。若不指定n å€û|¼Œåˆ™ç³»¾lŸé»˜è®¤å€égØ“1ã€?若输入数据的字符数小于nåQŒåˆ™¾pȝ»Ÿè‡ªåŠ¨åœ¨å…¶åŽæ·»åŠ ç©ºæ ¼æ¥å¡«æ»¡è®‘Ö®šå¥½çš„½Iºé—´ã€‚若输入的数据过长,ž®†ä¼šæˆªæŽ‰å…¶è¶…出部分ã€?br />     2、NCHAR
NCHAR数据¾cÕdž‹çš„定义åÅžå¼äØ“NCHAR[ åQˆnåQ?]ã€?它与CHAR ¾cÕdž‹ç›æ€¼¼ã€‚不同的是NCHAR数据¾cÕdž‹n 的取å€égØ“1 åˆ?000ã€?因䨓NCHAR ¾cÕdž‹é‡‡ç”¨UNICODE 标准字符集(CharacterSetåQ‰ã€?UNICODE 标准规定每个字符占用两个字节的存储空é—ß_¼Œæ‰€ä»¥å®ƒæ¯”非UNICODE 标准的数据类型多占用一倍的存储½Iºé—´ã€‚ä‹É用UNICODE 标准的好处是因其使用两个字节做存储单位,其一个存储单位的容纳量就大大增加了,可以ž®†å…¨ä¸–界的语­a€æ–‡å­—都囊括在内,在一个数据列中就可以同时出现中文、英文、法文、å¯d文等åQŒè€Œä¸ä¼šå‡ºçŽ°ç¼–ç å†²½Hã€?br />     3、VARCHAR
VARCHAR数据¾cÕdž‹çš„定义åÅžå¼äØ“VARCHAR [ åQˆnåQ?]ã€?它与CHAR ¾cÕdž‹ç›æ€¼¼åQŒn 的取å€ég¹Ÿä¸? åˆ?000åQ?若输入的数据˜q‡é•¿åQŒå°†ä¼šæˆªæŽ‰å…¶­‘…出部分。不同的是,VARCHAR数据¾cÕdž‹å…ähœ‰å˜åŠ¨é•¿åº¦çš„ç‰¹æ€§ï¼Œå› äØ“VARCHAR数据¾cÕdž‹çš„å­˜å‚¨é•¿åº¦äØ“å®žé™…æ•°å€¼é•¿åº¦ï¼Œè‹¥è¾“å…¥æ•°æ®çš„å­—ç¬¦æ•°å°äºŽn åQŒåˆ™¾pȝ»Ÿä¸ä¼šåœ¨å…¶åŽæ·»åŠ ç©ºæ ¼æ¥å¡«æ»¡è®‘Ö®šå¥½çš„½Iºé—´ã€?br />一般情况下åQŒç”±äºŽCHAR 数据¾cÕdž‹é•¿åº¦å›ºå®šåQŒå› æ­¤å®ƒæ¯”VARCHAR ¾cÕdž‹çš„处理速度快ã€?br />     4、NVARCHAR
NVARCHAR数据¾cÕdž‹çš„定义åÅžå¼äØ“NVARCHAR[ åQˆnåQ?]ã€?它与VARCHAR ¾cÕdž‹ç›æ€¼¼ã€‚不同的是,NVARCHAR数据¾cÕdž‹é‡‡ç”¨UNICODE 标准字符集(Character SetåQ‰ï¼Œ n 的取å€égØ“1 åˆ?000ã€?/p>

4.3.6 文本和图形数据类åž?br />    ˜q™ç±»æ•°æ®¾cÕdž‹ç”¨äºŽå­˜å‚¨å¤§é‡çš„å­—½W¦æˆ–二进制数据ã€?br />     1、TEXT
TEXT数据¾cÕdž‹ç”¨äºŽå­˜å‚¨å¤§é‡æ–‡æœ¬æ•°æ®åQŒå…¶å®šw‡ç†è®ºä¸ŠäØ“1 åˆ?çš?1‹Æ¡æ–¹-1 åQ?åQ?147åQ?483åQ?647åQ‰ä¸ªå­—节åQŒåœ¨å®žé™…应用旉™œ€è¦è§†¼‹¬ç›˜çš„存储空间而定ã€?br />SQL Server 2000 以前的版本中åQŒæ•°æ®åº“中一个TEXT 对象存储的实际上是一个指针,它指向一个个ä»?KB åQ?192 个字节)为单位的数据™åµï¼ˆData PageåQ‰ã€?˜q™äº›æ•°æ®™å‰|˜¯åŠ¨æ€å¢žåŠ åÆˆè¢«é€»è¾‘é“¾æŽ¥èµäh¥çš„。在SQL Server 2000 中,则将TEXT å’ŒIMAGE ¾cÕdž‹çš„æ•°æ®ç›´æŽ¥å­˜æ”‘Öˆ°è¡¨çš„æ•°æ®è¡Œä¸­åQŒè€Œä¸æ˜¯å­˜æ”‘Öˆ°ä¸åŒçš„æ•°æ®é¡µä¸­ã€?˜q™å°±å‡å°‘了用于存储TEXT å’ŒIMA- GE ¾cÕdž‹çš„空é—ß_¼Œòq¶ç›¸åº”减ž®‘了¼‚ç›˜å¤„理˜q™ç±»æ•°æ®çš„I/O 数量ã€?br />    2 NTEXT
NTEXT数据¾cÕdž‹ä¸ŽTEXT.¾cÕdž‹ç›æ€¼¼ä¸åŒçš?是NTEXT ¾cÕdž‹é‡‡ç”¨UNICODE 标准字符é›?Character Set), å› æ­¤å…¶ç†è®ºå®¹é‡äØ“230-1(1, 073, 741, 823)个字节ã€?br />    3 IMAGE
IMAGE数据¾cÕdž‹ç”¨äºŽå­˜å‚¨å¤§é‡çš„二˜q›åˆ¶æ•°æ®Binary Dataã€?å…¶ç†è®ºå®¹é‡äØ“2çš?1‹Æ¡æ–¹-1(2,147,483,647)个字节。其存储数据的模式与TEXT 数据¾cÕdž‹ç›¸åŒã€‚通常用来存储囑ÖÅž½{‰OLE Object Linking and EmbeddingåQŒå¯¹è±¡è¿žæŽ¥å’ŒåµŒå…¥åQ‰å¯¹è±¡ã€‚在输入数据时同BINARY数据¾cÕdž‹ä¸€æ øP¼Œå¿…须在数据前加上字符â€?X”作ä¸ÞZºŒ˜q›åˆ¶æ ‡è¯†

4.3.7 日期和时间数据类�br />    1 DATETIME
DATETIME 数据¾cÕdž‹ç”¨äºŽå­˜å‚¨æ—¥æœŸå’Œæ—¶é—´çš„¾l“合体。它可以存储从公å…?753 òq? æœ? 日零时è“v到公å…?999 òq?2 æœ?1 æ—?3 æ—?9 åˆ?9 ¿U’之间的所有日期和旉™—´åQŒå…¶¾_„¡¡®åº¦å¯è¾¾ä¸‰ç™‘Öˆ†ä¹‹ä¸€¿U’,å?.33 毫秒。DATETIME 数据¾cÕdž‹æ‰€å ç”¨çš„å­˜å‚¨ç©ºé—´äØ“8 个字节。其中前4 个字节用于存å‚?900 òq? æœ? 日以前或以后的天敎ͼŒæ•°å€¼åˆ†æ­£è´ŸåQŒæ­£æ•°è¡¨½Cºåœ¨æ­¤æ—¥æœŸä¹‹åŽçš„æ—¥æœŸåQŒè´Ÿæ•°è¡¨½Cºåœ¨æ­¤æ—¥æœŸä¹‹å‰çš„æ—¥æœŸã€‚后4 个字节用于存储从此日零时èµäh‰€æŒ‡å®šçš„æ—¶é—´ç»˜q‡çš„æ¯«ç§’数。如果在输入数据时省略了旉™—´éƒ¨åˆ†åQŒåˆ™¾pȝ»Ÿž®?2:00:00:000AMä½œäØ“æ—‰™—´¾~ºçœå€û|¼šå¦‚果省略了日期部分,则系¾lŸå°†1900 òq? æœ? 日作为日期缺省倹{€?br />    2 SMALLDATETIME
SMALLDATETIME 数据¾cÕdž‹ä¸ŽDATETIME 数据¾cÕdž‹ç›æ€¼¼åQŒä½†å…¶æ—¥æœŸæ—¶é—´èŒƒå›´è¾ƒž®ï¼Œä¸ÞZ»Ž1900 òq? æœ? 日到2079 òq? æœ?åQšæ—¥¾_‘Öº¦è¾ƒä½ŽåQŒåªèƒ½ç²¾¼‹®åˆ°åˆ†é’ŸåQŒå…¶åˆ†é’Ÿä¸ªä½ä¸ŠäØ“æ ÒŽ®¿U’数四舍五入的å€?即以30 ¿U’äØ“ç•Œå››èˆäº”å…¥ã€‚å¦‚åQšDATETIME æ—‰™—´ä¸?4:38:30.283
æ—¶SMALLDATETIME è®¤äØ“æ˜?4:39:00 SMALLDATETIME 数据¾cÕdž‹ä½¿ç”¨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 />YMDåQ?000/6/22 2000-6-22 2000.6.22
MDYåQ?/5/2000 3-5-2000 3.5.2000
DMYåQ?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 å’ŒPMåQˆpmåQ‰åˆ†åˆ«æŒ‡å®šæ—¶é—´æ˜¯åˆå‰æˆ–午后,若不指定å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 货币数据¾cÕdž‹
货币数据¾cÕdž‹ç”¨äºŽå­˜å‚¨è´§å¸å€¹{€‚在使用货币数据¾cÕdž‹æ—Óž¼Œåº”åœ¨æ•°æ®å‰åŠ ä¸Šè´§å¸ç¬¦åøP¼Œ¾pȝ»Ÿæ‰èƒ½è¾¨è¯†å…¶äؓ哪国的货币,如果不加货币½W¦å·åQŒåˆ™é»˜è®¤ä¸ºâ€œïòE”。各货币½W¦å·å¦‚图4-2所½Cºã€?br />    1 MONEY
MONEY 数据¾cÕdž‹çš„æ•°æ®æ˜¯ä¸€ä¸ªæœ‰4 位小数的DECIMAL å€û|¼Œå…¶å–å€ég»Ž-2çš?3‹Æ¡æ–¹åQ?922åQ?37åQ?03åQ?85åQ?77.5808åˆ?çš?3‹Æ¡æ–¹-1åQ?922åQ?37åQ?03åQ?85åQ?77.5807åQ‰ï¼Œæ•°æ®¾_‘Öº¦ä¸ÞZ¸‡åˆ†ä¹‹ä¸€è´§å¸å•位。MONEY 数据¾cÕdž‹ä½¿ç”¨8个字节存储ã€?br /> 
    2 SMALLMONEY
SMALLMONEY数据¾cÕdž‹¾cÖM¼¼äºŽMONEY ¾cÕdž‹åQŒä½†å…¶å­˜å‚¨çš„è´§å¸å€ÆDŒƒå›´æ¯”MONEY数据¾cÕdž‹ž®?其取å€ég»Ž-214,748.3648åˆ?214,748.3647,存储½Iºé—´ä¸? 个字节ã€?/p>

4.3.9 特定数据¾cÕdž‹
SQL Server 中包含了一些用于数据存储的ç‰Òޮп•°æ®¾cÕdž‹ã€?br />    1 TIMESTAMP
TIMESTAMP数据¾cÕdž‹æä¾›æ•°æ®åº“范围内的惟一值此¾cÕdž‹ç›¸å½“于BINARY8或VARBINARYåQ?åQ‰ï¼Œä½†å½“它所定义的列在更新或插入数据行时åQŒæ­¤åˆ—çš„å€ég¼šè¢«è‡ªåŠ¨æ›´æ–ŽÍ¼Œä¸€ä¸ªè®¡æ•°å€¼å°†è‡ªåŠ¨åœ°æ·»åŠ åˆ°æ­¤TIMESTAMP数据列中。每个数据库表中只能有一个TIMESTAMP数据列。如果徏立一个名为“TIMESTAMP”的列,则该列的¾cÕdž‹ž®†è¢«è‡ªåŠ¨è®¾äØ“TIMESTAMP数据¾cÕdž‹ã€?/p>

    2 UNIQUEIDENTIFIER
UNIQUEIDENTIFIER 数据¾cÕdž‹å­˜å‚¨ä¸€ä¸?6 位的二进制数字。此数字¿UîCØ“åQˆGUIDGlobally Unique Identifier åQŒå³å…¨çƒæƒŸä¸€é‰´åˆ«åøP¼‰ã€‚此数字由SQLServer çš„NEWID函数产生的全球惟一的编码,在全球各地的计算机经由此函数产生的数字不会相同ã€?/p>

4.3.10 用户自定义数据类åž?br />SYSNAME SYSNAME 数据¾cÕdž‹æ˜¯ç³»¾lŸæä¾›ç»™ç”¨æˆ·çš„ï¼Œä¾¿äºŽç”¨æˆ·è‡ªå®šä¹‰æ•°æ®ç±»åž‹ã€‚å®ƒè¢«å®šä¹‰äØ“NVARCHARåQ?28åQ‰ï¼Œå›_®ƒå¯å­˜å‚?28个UNICODE字符æˆ?56个一般字½W¦ã€‚其具体使用æ–ÒŽ³•请参见第7章“管理数据库表”中的“自定义数据¾cÕdž‹â€ç« èŠ‚ã€?/p>

4.3.11 新数据类åž?br />SQL Server 2000 中增加了3 ¿Uæ•°æ®ç±»åž‹ï¼šBIGINT、SQL_VARIANTå’ŒTABLE。其中BIGINT数据¾cÕdž‹å·²åœ¨æ•´æ•°¾cÕdž‹ä¸­ä»‹¾lï¼Œä¸‹é¢ä»‹ç»å…¶ä½™ä¸¤ç§åQ?br />    1 SQL_VARIANT
SQL_VARIANT数据¾cÕdž‹å¯ä»¥å­˜å‚¨é™¤æ–‡æœ¬ã€å›¾å½¢æ•°æ®ï¼ˆTEXT、NTEXT、IMAGEåQ‰å’ŒTIMESTAMP¾cÕdž‹æ•°æ®å¤–的其它ä»ÖM½•合法的SQL Server数据。此数据¾cÕdž‹å¤§å¤§æ–¹ä¾¿äº†SQL Server的开发工作ã€?br />    2 TABLE
TABLE 数据¾cÕdž‹ç”¨äºŽå­˜å‚¨å¯¹è¡¨æˆ–视囑֤„理后的结果集。这一新类型ä‹É得变量可以存储一个表åQŒä»Žè€Œä‹É函数或过½E‹è¿”回查询结果更加方便快、捷其、ä‹É用请参见½W?3章“游标、视囑֒Œè‡ªå®šä¹‰å‡½æ•°â€ã€?/p>

 



]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º µ¤¶«ÊÐ| ÄÏÕÄÏØ| ·½³ÇÏØ| ¶¨°²ÏØ| ·áË³ÏØ| ·Ê¶«ÏØ| ׿ÄáÏØ| ÄÏÍ¶ÏØ| ¹þ°ÍºÓÏØ| Äþ½òÏØ| ÈÎÇðÊÐ| ÁÙãðÏØ| Ê¯ÈªÏØ| ÈýÌ¨ÏØ| ¿Ëʲ¿ËÌÚÆì| ̽Ë÷| ¼ªÁÖÊÐ| ×Ͳ©ÊÐ| Ó¢µÂÊÐ| ÎäÚìÏØ| ¿ÑÀûÏØ| ÆÜϼÊÐ| Û²³ÇÏØ| ÌúÁëÊÐ| °²»ÕÊ¡| µ¤·ïÏØ| ÐÅ·áÏØ| ÄþÏÄ| ÐÂÒ°ÏØ| ÃϽòÏØ| ¿Æ¶û| äÓÆÖÏØ| ɯ³µÏØ| ¿Ë¶«ÏØ| ÂêÇúÏØ| ̫ԭÊÐ| Áúº£ÊÐ| ¡°²ÏØ| ½´¨ÏØ| Èʲ¼ÏØ| ±±´¨|