??xml version="1.0" encoding="utf-8" standalone="yes"?> ---雇员?EMPLOYE)
--l理?MANAGER)
---雇员?EMPLOYE)
--l理?MANAGER)
--更新存在?/p>
---插入不存在的
--更新存在?/p>
---插入不存在的
上面的处理是可以的,但是我们q可以有更简单的Ҏ(gu)Q就是用Merge语句Q如下所C:(x)
以下是代码片D:(x)
不仔l的朋友可能没有看出上面两条语句的区别,哈哈Q请仔细Ҏ(gu)一下这两条语句。上面的语句中多?jin)ELSE IGNORE语句Q它的意思正如它英文的意思,其它情况忽略不处理。如果你认ؓ(f)理论上应该不存在EM.SALARY>MA.SALARY的数据,如果有,说明有问题,你想抛个异常Q怎么办?如下Q?/p>
对于EM.SALARY>MA.SALARY的情况,如果你不x(chng)异常Q而是删除EMPLOYE中的数据Q怎么办?如下Q?/p>
以上单介l了(jin)Merge语句的用,它的应用不只是上面介l的情况Q其实它可以应用在很多其他语句不好处理情况,q需要你d玎ͼC熟能生y MySQL PostgreSQL MSSQL Server SQLite MS Access 或是更简单的XMLQ文本文件等。这些数据库有优U的文档,背后有强大的C支持Q大部分行的CMS都用了(jin)其中之一或多个,它们都易于用,大多数托服务供应商都提供了(jin)相应的品,因此它们的用量很多Q名气也很大。但除了(jin)q些L的数据库外,q有很多其它非主数据库存在Q其中有一些也开始受Ch们的高度重视Q下面我们就一h看看吧,注意本文只介l开源数据库Q说不定在下一个项目中Q你有试它们的冲动?/font> 1、MongoDB MongoDB是一Ƒּ源,高性能Q可扩展Q无模式Q面向文?与JSONcM的数据模?的数据库Q它为时下最行的编E语a提供?jin)驱动,如PHPQPythonQPerlQRubyQJavaScriptQC++{,支持全文索引Q自动分片,跨LAN或WAN扩展Q采用Key/Value方式存储数据。MongoDB服务端可q行在Linux、Windows或OS Xq_Q支?2位和64位应用。世界上最大的单词收录|站Wordnik׃MySQL转向?jin)MongoDB?/font> 2、Hypertable Hypertable是一N性能分布式数据存储系l,旨在为应用程序提供最好的性能Q可扩展性和可靠性,它徏立在Google的BigTable之上Q主要面向大规模数据集应用,其目标是要成Z界上最好的大规模ƈ发高性能数据库^台。百度目前也使用?jin)HypertableQ也是它的赞助商?/font> 3、Apache CouchDB Apache CouchDB是一N向文档的数据库,可以使用JavaScript通过MapReduceҎ(gu)q行查询和烦(ch)引,它提供了(jin)一个RESTful JSON APIQ因此可以在M环境中通过HTTP讉KQCouchDB内置?jin)Web理控制収ͼ支持通过览器管理数据库。CouchDB使用Erlang~写QErlang是一U健壮的函数式编E语aQ非帔R合于构建ƈ发的分布式系l,Erlang的设计非常灵z,其可伸羃性与可扩展性都非常?/font> 4、Neo4j Neo4j是一个嵌入式Q基于磁盘的Q支持完整事务的Java持久化引擎,它在囑փ中而不是表中存储数据。Neo4j提供?jin)大规模可扩展性,在一台机器上可以处理数十亿节?关系/属性的囑փQ可以扩展到多台机器q行q行。相对于关系数据库来_(d)囑Ş数据库善于处理大量复杂、互q接、低l构化的数据Q这些数据变化迅速,需要频J的查询——在关系数据库中Q这些查询会(x)D大量的表q接Q因此会(x)产生性能上的问题。Neo4j重点解决?jin)拥有大量连接的传统RDBMS在查询时出现的性能衰退问题。通过围绕囑Şq行数据建模QNeo4j?x)以相同的速度遍历节点与边Q其遍历速度与构成图形的数据量没有Q何关pR此外,Neo4jq提供了(jin)非常快的囑Ş法、推荐系l和OLAP风格的分析,而这一切在目前的RDBMSpȝ中都是无法实现的?/font> 5、Riak Riak是一N帔R合于Web应用E序的数据库Q它提供?jin)去中?j)化的Key/Value存储Q灵zȝmap/reduce引擎和友好的HTTP/JSON查询接口。它是一个真正的定wpȝQ不?x)出现单?gu)障,在Riak世界中,没有哪台机器是特D的或属核心(j)服务器,它们都是对等的?/font> 6、Oracle Berkeley DB Oracle Berkeley DB是一pd开源的嵌入式数据库Q开发h员能够将一个快速、可伸羃、具有工业别的可靠性和可用性的事务处理数据库引擎结合进他们的应用程序中。Berkeley DB最先由伯克利加州大学ؓ(f)?jin)移除受到AT&T限制的程式码Q从BSD 4.3?.4时所改写的Y件。Berkeley DBq行在大多数的操作系l中Q例如大多数的UNIXpȝQ?和windowspȝQ以?qing)实时操作系l?/font> 7、Apache Cassandra Cassandra是一N可扩展性第二代分布式数据库Q属于合型的非关系的数据库Q类gGoogle的BigTableQ支持的数据l构非常松散Q类gJSON的BJSON格式Q因此可以存储比较复杂的数据cd。Cassandra最初由Facebook开发,后{变成?jin)开源项目。Cassandra的主要特点就是它不是一个数据库Q而是׃堆数据库节点共同构成的一个分布式|络服务Q对Cassandra 的一个写操作Q会(x)被复制到其他节点上去Q对Cassandra的读操作Q也?x)被路由到某个节点上面去d。对于一个Cassandra集来说Q扩展性能是比较简单的事情Q只在集里面d节点可以了(jin)。FacebookQDiggQTwitter和Cisco{大型网站都使用?jin)Cassandra?/font> 8、Memcached Memcached是开源的分布式cachepȝQ现在很多的大型web应用E序包括facebookQyoutubeQwikipediaQyahoo{等都在使用memcached来支持他们每天数亿的页面访问。通过把cache层与他们的web架构集成Q他们的应用E序在提高(sh)(jin)性能的同Ӟq大大降低了(jin)数据库的负蝲?/p>
Memcached处理的原子是每一个key/value对,key?x)通过一个hash法转化成hash-keyQ便于查找、对比以?qing)做到尽可能的散列。同Ӟmemcached用的是一个二U散列,通过一张大hash表来l护?/p>
9、Firebird Firebird是一个关pL据库Q可以运行在LinuxQW(xu)indows和各UUnixq_上,Firebird相对MySQL和PostgreSQL来说比较?yu),q也使其可以U得上是理想的嵌入式数据库,可用于与其它应用E序服务器和应用E序捆绑。Firebirdh大部分成熟数据库所h的功能,比如支持存储q程、SQL兼容{?/p>
10、Redis Redis是一Ƒֿ速的Key/Value数据库引擎,它在保持键值数据库单快L(fng)点的同时Q又吸收?jin)部分关pL据库的优点,从而它的位置处于关系数据库和键值数据库之间。Redis不仅能保存Stringscd的数据,q能保存Listscd(有序)和Setscd(无序)的数据,而且q能完成排序(SORT){高U功能,在实现INCRQSETNX{功能的时候,保证?jin)其操作的原子性,除此以外Q还支持M复制{功能。Redis使用C语言~写Q可以想memcached那样使用Q放在传l数据库的前端,它支持许多编E语aQ受到许多流行的目使用Q如GitHub和Engine YardQ有一个用PHP~写的客L(fng)叫做RediskaQ专门来理Redis数据库?/p>
11、HBase HBase是一个分布式Q面向列存储的数据库引擎Q也可以叫做Hadoop数据库,因ؓ(f)它是Hadoop的子目QHBase的目标是托管数十亿行Q数百万列的大表Q它提供?jin)一个REST风格的Web服务器网养I支持XMLQProtobuf和二q制数据~码选项?/p>
12、Keyspace Keyspace 是一家叫?Scalien 的创业公司开发的高可?key/value 存储pȝQKeyspace 的技术点是高可靠性,有以下一些特点:(x) Key/Value存储Q一?key/value 数据存储pȝQ只支持一些基本操作,如:(x)SET(key, value) ?GET(key) {? 分布式:(x)多台机器(nodes)同时存储数据和状态,彼此交换消息来保持数据一_(d)可视Z个完整的存储pȝ。ؓ(f)?jin)更可靠QKeyspace 推荐使用奇数?nodesQ比如:(x)3Q?Q?{? 数据一_(d)(x)所有机器上的数据都是同步更新的、不用担?j)得C一致的l果QKeyspace 使用著名?Paxos 分布式算? 冗余Q所有机?nodes)保存相同的数据,整个pȝ的存储能力取决于单台机器(node)的能? 定wQ如果有数 nodes 出错Q比如重启、当机、断|、网l丢包等各种 fault/fail 都不影响整个pȝ的运? 高可靠性:(x)定w、冗余等保证?Keyspace 的可靠性?/p>
13?store 4store是一个容URDF数据的数据库存储和查询引擎,它用ANSI C99~写Q可在类Unixpȝ上运行,提供一个高性能Q可扩展和稳定的q_?store专门为无׃n集群q行优化Q最大可支持32节点集群Q导入性能最大可以达?20kT/sQ它的查询性能也相当出众?/p>
14、MariaDB MariaDB是一个向后兼容的Q旨在替换MySQL数据库的MySQL分支Q它包括所有主要的开源存储引擎,另外也开发了(jin)属于自己的Maria存储引擎。MariaDB是由原来 MySQL 的作?Michael Widenius 创办的公司所开发的免费开源数据库服务器,?MySQL 相比较,MariaDB 更强的地方在于:(x) Maria 存储引擎 PBXT 存储引擎 XtraDB 存储引擎 FederatedX 存储引擎 更快的复制查询处?/p>
U程?/p>
更少的警告和bug q行速度更快 更多?Extensions (More index parts, new startup options etc) 更好的功能测?/p>
数据表消?/p>
慢查询日志的扩展l计 支持?Unicode 的排?/p>
15、Drizzle Drizzle是从MySQL衍生出来的一个数据库Q但它的目的不是要取代MySQLQ它的宗旨是构徏一?#8220;更精l、更轻量、更快?#8221;的MySQL版本Q它的扩展性和易用性与MySQL相当Q但Z(jin)提高性能和扩展性,它从原来的核?j)系l里U除?jin)部分功能。Drizzle是一Uؓ(f)云和|络E序q行?jin)特别优化的数据库,它是为在C多CPU/多核架构上实现大规模q发而设计的?/p>
16、HyperSQL HyperSQL是用Java~写的一ƾSQL关系数据库引擎,它的核心(j)完全是多U程的,支持双向锁和MVCC(多版本ƈ发控?Q几乎完整支持ANSI-92 SQLQ支持常见数据类型,最新版本增加了(jin)对BLOB和CLOB数据的支持,最高支持达64T的数据量。同ӞHyperSQL也是一个不错的嵌入式数据库?/p>
17、MonetDB MonetDB是一个高性能数据库引擎,主要用在数据挖掘QOLAPQGISQXML QueryQ文本和多媒体检索等领域。MonetDB对DBMS的各个层都进行创新设计,如基于垂直分片的存储层,为现代CPU优化的查询执行架构,自动和自助调整烦(ch)引,q行时查询优化,以及(qing)模块化的软g架构。MonetDB/SQL是MonetDB提供的关pL据库解决Ҏ(gu)QMonetDB/XQuery是XML数据库解x(chng)案,MonetDB Server是MonetDB的多模型数据库服务器?/p>
18、Persevere Persevere 是针对Javascript设计的基于REST的JSON数据库,分布式计,持久对象映射的框Ӟ提供独立的web服务器,主要用于设计富客L(fng)应用Q可以用在Q何框架和客户端上。Persevere Server是一个基于Java/Rhino的对象存储引擎,在交互式的客L(fng)JavaScript环境中提供持久性的JSON数据格式?/p>
19、eXist-db eXist-db是用XML技术构建的数据库存储引擎,它根据XML数据模型存储XML数据Q提供高效的Q基于烦(ch)引的XQuery查询。eXist-db支持许多Web技术标准,使得它非帔R合Web应用E序开发:(x) XQuery 1.0 / XPath 2.0 / XSLT 1.0 (使用pache Xalan)或XSLT 2.0 HTTP接口QRESTQW(xu)ebDAVQSOAPQXMLRPCQAtom发布协议 XML数据库规范:(x)XMLDBQXupdateQXQuery更新扩展 最新的1.4版本q增加了(jin)ZApache Lucene的全文烦(ch)引,轻量UURL重写和MVC框架Q以?qing)对XProc的支持。eXist-db与XQuery标准高度兼容(目前XQTS的得分是99.4%)?/p>
20、Gladius Gladius是用UPHP~写的^面文件数据库引擎Q它的SQL语法与SQL92的一个子集兼容,它捆l了(jin)一个轻量的adoDB驱动?/p>
21、CloudStore CloudStore(以前叫做Kosmos文gpȝ)是一个开源的高性能分布式文件系l,它是用C++~写的,CloudStore可以和Hadoop以及(qing)Hypertable集成Q这样就允许应用E序构徏在那些系l上Q而底层数据存储无~地使用CloudStore。CloudStore支持Linux和SolarisQ主要用来存储Web日志和W(xu)eb爬行数据?br> 22、OpenQM OpenQM是唯一一Ƒ时有商业支持和免费的开源多值数据库Q基于GPL协议发布Q多值数据库对NoSQLq动起到?jin)推动作用,它自w也因速度快,体积,比关pL据库便宜而很快得C(jin)认可。名UOpenQM中的Open表示开源版本,QM表示商业闭源QM数据库。商业版本支持WindowsQLinux(RedHatQFedoraQDebianQUbuntu)QFreeBSDQMac OS X和W(xu)indows MobileQ其列表hq(sh)到其它多g品的1/5Q商业版本还包括一个GUI理界面和终端模拟器Q开源版本仅包括核心(j)多值数据库引擎Q主要是为开发h员准备的?/p>
23、ScarletDME ScarletDME也是一个开源多值数据库Q它是OpenQM的社区分支版Q最初由Ladybridge开发,q个目创立?008q?1?8日,它既在独立开发自q功能Q也在ؓ(f)OpenQM贡献代码。这个项目最初的名字叫做Ladybridges GPL OpenQMQ现在正式改为ScarletDMEQ其中的DME是Data Management Environment(数据理环境)的首字母~写?/p>
24、SmallSQL SmallSQL是一?00%UJava~写的轻量数据库,一般用于嵌入式领域Q兼容SQL 99标准Q支持JDBC 3.0 APIQ定位于高端Java桌面SQL数据库。支持所有能q行Java的^収ͼ可直接嵌入到应用E序中。不q它也有一些不I如没有网l接口,必须安装Javaq行Ӟ同一旉不能在多个应用程序之间共享数据库Q没有用L(fng)理?/p>
25、LucidDB LucidDB是唯一一ƾ专注于数据仓库和商务智能的开源RDBMSQ它使用?jin)列存储架构Q支持位囄(ch)引,哈希q接/聚合和页面多版本,大部分数据库最初都注重事务处理能力Q而分析功能都是后来才加上ȝ。相反,LucidDB中的所有组件从一开始就是ؓ(f)满灉|的需求,高性能数据集成和大规模数据查询而设计的Q此外,其架构设计彻底从用户出发Q操作简单,完全无需DBA?/p>
LucidDB对硬件要求也极低Q即使不搭徏集群环境Q在单一的Linux或Windows服务器上也能获得极好的性能。最新版本还加入?jin)对Mac OS X和W(xu)indows 64位的支持Q官方网站上的文档和教程也非怸富,非常值得你体验一下?/p>
26、HyperGraphDB HyperGraphDB是一U通用的,可扩展的Q可UL的,分布式,嵌入式和开源数据存储机Ӟ它是一个图形数据库Q专门ؓ(f)人工和语义Web目而设计,它也可用于Q意规模的嵌入式面向对象的数据库。正如其名,HyperGraphDB是用来存储超囄Q但它也属于一般图形数据库家族Q作Z个图形数据库Q它不施加Q何限Ӟ相比其他囑Ş数据库它的功能更丰富?/p>
HyperGraphDB非常E_Q已l应用在多个生环境Q包括一个搜索引擎和Seco scripting IDE。它支持*nix和W(xu)indowsq_Q需要Java 5+?/p>
27、InfoGrid InfoGrid是一个互联网囑Ş数据库,它提供了(jin)许多额外的组Ӟ使得在图像基上开发RESTful Web应用E序变得更加Ҏ(gu)。InfoGrid是开源的Q包括一pd目Q?/p>
InfoGrid囑Ş数据库项?– InfoGrid的心(j)脏GraphDatabaseQ可以独立用,也可以附加到其它InfoGrid目?/p>
InfoGrid囑Ş数据库网格项?– 在GraphDatabase基础上增加了(jin)复制协议Q因此多个分布式GraphDatabase可以在一个非常大的图像管理环境中协作?/p>
InfoGrid存储目 –象SQL数据库和分布式NoSQL哈希表那P为存储技术提供一个抽象的通用接口Q这样InfoGrid GraphDatabase可以用Q何存储技术持久化数据?/p>
InfoGrid用户接口目 – GraphDatabase中的内容以REST风格映射成浏览器可访问的URL?/p>
InfoGrid轻量Un份识别项?– 实现以用户ؓ(f)中心(j)的n份识别技术,如LID和OpenID?/p>
InfoGrid模型库项?– 定义一个可复用对象模型库,作ؓ(f)InfoGrid应用E序的模式用?/p>
InfoGrid Probe目 – 实现Probe框架Q它允许开发h员将M互联|上的数据源当作一个图像对象看待?/p>
InfoGrid Utilities目 – 攉InfoGrid使用的常见对象框架和实用代码?/p>
28、Apache Derby Apache Derby是Apache DB的子目Q它完全用Java~写Q是一个开源关pL据库Q它的体U非常小Q基引擎加上JDBC驱动只有2.6MBQ它支持SQL标准Q它提供?jin)一个嵌入式JDBC驱动Q因此可以嵌入到MZJava的应用程序中QDerby也支持常见的客户?服务器模式,它也易于安装和用?/p>
29、hamsterdb Hamsterdb是一个轻量嵌入式NoSQL Key/Value存储引擎Q它已经?q历Ԍ现在它的开发重Ҏ(gu)在易用性,高性能Q稳定性和可扩展性上。Hamsterdb支持事务(同一旉只能处理一个事?Q支持内存数据库Q支持基于HTTP服务器的嵌入式远E数据库Q支持日?恢复QAES加密Q基于zlib的压~,支持C++QPythonQ?NET和Java~程语言?/p>
30、H2 Database H2 Database是一个开源的Java数据库,它的速度很快Q包括JDBC APIQ支持嵌入式和服务器模式Q内存数据库Q提供了(jin)一个基于浏览器的控制台E序Q它的体U也非常,只有一个大约1MB的jar文gQ它q支持ODBC驱动和全文搜索?/p>
31、EyeDB EyeDB是一Ƒ֟于ODMG 3规范的面向对象数据库理pȝQؓ(f)C++和Java提供?jin)编E接口,它功能非常强大,q且成熟Q稳定和安全Q实际上Q它h?992q的Genome View目Q?994q又q行?jin)重写,q泛用于生物信息目?/p>
32、txtSQL txtSQL是一个面向对象的q面文g数据库管理系l,它用PHP~写Q支持对普通文本文件的操作Q虽然是一个文本数据库Q但同样支持SQL的一个子集,q且执行效率非常高,txtSQL使用文gpȝ的方法与MySQL的表和数据库原理cMQ它有一个类gphpMyAdmin理界面?/p>
33、db4o db4o是一个面向对象的开源数据库Q允许Java?NET开发h员用一行代码存储和(g)索Q何应用程序对象,无需预定义或l护一个独立的Q僵化的数据模型Q因为模型现在是由db4oҎ(gu)需要自动创建和更新的。db4o成功的秘密是因ؓ(f)它的易用性,它原生ؓ(f)Java?NET设计Q存储数据对象的Ҏ(gu)直接在应用程序中定义Q因此db4o很容易集成到应用E序中,׃只需要一行代码,因此执行效率非常高?/p>
34、Tokyo Cabinet Tokyo Cabinet是一个Kay/Value型数据库Q每个Key和Value的长度都可以不同QKay和Value既可以是二进制数据,也可以是字符Ԍ无数据表和数据类型的概念Q记录是以哈希表、B+?wi)和固定长度数组形式l织的。Tokyo Cabineth以下优点Q?/p>
I间利用率高 – 数据文g寸更小; 执行效率?– 更快的处理速度; q发性能?– 在多U程环境性能更好; 改善的可用?– 化的API; 改善的可靠?– 即在发生灾隄情况下,数据文g也不?x)损? 支持64位架?– 支持量的存储空间和巨型数据库文件?/p>
Tokyo Cabinet是用C语言~写的,为CQPerlQRubyQJava和Lua提供?jin)API?/p>
35、Voldemort目 Voldemort是一个分布式Key/Value存储pȝQ它h以下特点Q?/p>
数据自动在多个服务器之间复制; 数据自动分区Q因此每个服务器只包括整体数据的一个子? 服务器故障处理是透明? 支持插入式序列化Q允怸富的Key和ValuecdQ包括列表和元组Q也可以集成常见的序列化框架Q如Protocol BuffersQThriftQAvro和Java Serialization 数据Ҏ(gu)持版本化Q即使在故障情况下,数据完整性也可以得到保障; 每个节点都是独立的,无需其他节点协调Q因此也没有中央节点; 单节Ҏ(gu)能优秀Q根据机器配|、网l、磁盘系l和数据复制因素的不同,每秒可以执行10-20k操作; 支持地理分散式部|Ӏ?/p>
LinkedIn目前׃用Voldemort解决?jin)高可~性存储问题?/p>
不知道你是否一口气看完本文Q我想你也一定会(x)惊讶于这么多开源数据库吧,事实上,本文也尚未完全罗列,Ƣ迎你的补充?/font> DECLARE CURSOR WITH HOLD 语句 当用包括 WITH HOLD 子句?DECLARE CURSOR 语句声明游标Ӟ在落实该事务时Q何打开的游标仍然打开Qƈ且释放所有锁定,除保护打开?WITH HOLD 游标的当前游标位|的锁定外?/p>
如果回滚事务Q则关闭所有打开的游标且释放所有锁定以?qing)释?LOB 定位器?/p>
用银行的例子来说明事务的重要性是很经典的。假定某个客户从他的储蓄账户向支̎戯{?00元。这个操作包括连l执行的两个独立步骤?/p>
(1) 储蓄账户?00元?/p>
(2) 支票账户?00元?/p>
?4-1昄?jin)这个事务的两条SQL语句。设惻I如果DBMS在执行了(jin)W一条语句,但没有执行第二条时突然发生故障——断c(din)系l崩溃、硬件出问题Q̎户在不知鬼不觉的情况下出现?jin)不q。渎职控告和牢狱之灾׃(x)接踵而至?/p>
?4-1 当银行客户从储蓄账户向支̎戯{账时Q必L两条SQL语句 Z(jin)避免q法记录Q应该用事务来保证两条SQL语句都被执行Q以l持账户q。如果事务中的一条语句无法执行时QDBMS撤销Q回滚)(j)事务中其他语句。如果一切顺利,变化被持久化(提交Q?/p>
执行事务 要了(jin)解事务如何工作,p?jin)解一些术语?/p>
提交。提交(committingQ事务是使自事务开始后修改的所有数据持久化在数据库中。在事务提交后,即发生崩溃或其他故障,事务带来的所有变化仍然对其他用户可见q能够保证持久化?/p>
回滚。回滚(rolling backQ事务是撤销事务中SQL语句带来的所有变化。事务回滚后Q此前媄(jing)响到的数据回到原Ӟ好像SQL语句从未执行一栗?/p>
事务日志。事务日志文Ӟtransaction logfileQ或日志QlogQ是有关事务Ҏ(gu)据库q行修改的一pd记录。事务日志记录了(jin)每个事务开始、数据的变化以及(qing)撤销或重新执行事务(如果来需要)(j)的够信息。日志随着数据库事务的执行不断增长?/p>
管保证每个事务本n的完整性是DBMS的职责,但依据组l或公司规章来开始和l束事务以保证数据逻辑的一致性则是数据库开发h员的责Q。事务应该仅包含能做Z致修改的必要的SQL语句——不多不。所有引用表中的数据在事务开始前和事务结束后必须保持一致?/p>
在设计和执行事务Ӟ要重点考虑以下斚w?/p>
l 事务相关的SQL语句?x)修?gu)据,所以执行事务要得到数据库管理员的授权?/p>
l 事务q程应用于那些改变数据和数据库对象的语句QINSERT、UPDATE、DELETE、CREATE、ALTER、DROP——因不同DBMS而异Q。对于工作中用到的数据库Q每一条这L(fng)语句都应该作Z务的一部分执行?/p>
l 提交?jin)的事务被称作持久化Q意味着怹性改变,即便pȝ发生故障仍能保持?/p>
l DBMS的数据恢复机制依赖于事务。当DBMS在故障之后被在线复原QDBMS(g)查事务日志确认是否所有事务都提交l了(jin)数据库。如发现没有提交Q部分执行)(j)的事务,依据日志它们回滚。必重新提交回滚的事务Q尽一些DBMS能够自动完成没有l束的事务)(j)?/p>
l DBMS的备?恢复讑֤依赖于事务。备份设备获得例行的数据库快照ƈ它们和随后的事务日志存储在备䆾盘(sh)。假定用的盘发生故障使得数据和事务日志不可读。可以借助于恢复设备,它将采用最q的数据库备份ƈ执行Q或前滚所有从快照到故障前最后执行ƈ在日志中提交的事务。这个恢复操作数据库恢复到故障发生前的正确状态(注意Q要再次提交没有提交的事务)(j)?/p>
l 昄Q应该将数据库和它的事务日志存储于不同的物理盘?/p>
q发控制 对h来说Q计机好像在同一旉q行着两个或更多进E。实际上Q计机操作q同时发生Q而是q箋(hu)的。同时发生的印象是因为微处理器在Z难以察觉的很短的旉D内工作。在DBMS里,q发控制是在两个或更多用户同时访问或修改相同的数据时为防止数据失d整性的一l策??/p>
DBMS使用锁定{略来保证事务完整性和数据库的一致性。在d操作Ӟ锁定限制数据的访问;于是Q它L用户读那些正在被其他用户修改的数据,q止多用户同时对同一数据修改。如果没有锁定,数据可能发生逻辑错误Q针对这些数据执行的语句返回不可预料的l果。偶?dng)?x)出现两个用户都锁定了(jin)Ҏ(gu)事务所需的数据ƈ试d到对方的解锁Q这时发生死锁问题。大多数DBMS能够侦测和解x(chng)锁问题,通过回滚一个用L(fng)事务让另一个事务可以运行(否则Q两个用户都要永q等Ҏ(gu)解锁Q。锁定机刉常复杂,h阅DBMS文档?jin)解锁定?/p>
q发透明性是从事务的角度看数据库上运行唯一事务的现象。DBMS分离事务变化与Q何其他ƈ发事务的变化。当?dng)事务永远见不到数据的中间状态;或在其他q发事务之前讉KQ或在其他ƈ发事务结束以后访问。分ȝ事务允许重蝲开始数据ƈ再次执行Q前滚)(j)一pd事务来达到它们在最初的事务被执行之后的状态?/p>
因ؓ(f)事务按照要么全部Q要么全不方式被执行Q事务的边界Q开始点和结束点Q必L晰。边界DBMS作ؓ(f)一个原子单元来执行q些语句。事务隐式开始于W一个可执行的SQL语句或显式?START TRANSACTION语句。事务显式结束于COMMIT或ROLLBACK语句Q无法隐式结束)(j)Q且无法在提交之后回滚事务?/p>
q þ 昑ּ开始一个事务中 在Microsoft Access或Microsoft SQL Server中,输入Q?/p>
BEGIN TRANSACTION; ?/p>
在MySQL or PostgreSQLQ输入:(x) START TRANSACTION; þ 提交事务?/p>
输入Q?/p>
COMMIT; þ 回滚事务?/p>
输入Q?/p>
ROLLBACK; 代码14-1中的SELECT语句昄UPDATE操作被DBMS执行后又被ROLLBACK语句取消。结果见?4-2?/p>
?4-2 q行代码14-1的结果。SELECT?br>句的l果昄DBMS取消?jin)操?/p>
代码14-1 在一个事务内Q更新操作(像插入和删除操作那样Q永q不是在最后出现。结果见?4-2 SELECT SUM(pages), AVG(price) FROM titles; BEGIN TRANSACTION; UPDATE titles SET pages = 0; UPDATE titles SET price = price * 2; SELECT SUM(pages), AVG(price) FROM titles; ROLLBACK; SELECT SUM(pages), AVG(price) FROM titles; 代码14-2昄更实用的事务例子。要从表publi- shers删除出版CP04而不产生引用完整性错误。因titles的有些外键值指向表publishers的出版社P04Q所以要先删除表titles、titles_authors、和royalties中相关的行。应该用事务保证所有DELETE语句都被执行。如果只有一些语句执行成功,数据无法保持一_(d)要了(jin)解更多有兛_用完整性检查的信息Q参?1.7节)(j)?/p>
代码14-2 使用事务从表publishers中删除出版社P04Q及(qing)删除其他表中与P04相关的行 BEGIN TRANSACTION; DELETE FROM title_authors WHERE title_id IN (SELECT title_id FROM titles WHERE pub_id = 'P04'); DELETE FROM royalties WHERE title_id IN (SELECT title_id FROM titles WHERE pub_id = 'P04'); DELETE FROM titles WHERE pub_id = 'P04'; DELETE FROM publishers WHERE pub_id = 'P04'; COMMIT; ACID ACID是首字母~写Q它概括?jin)事务的特点Q?/p>
原子性(AtomicityQ。要么事务中所有的数据修改都执行,要么都撤销?/p>
一致性(ConsistencyQ。完全的事务应让数据保持一致来保证数据完整。一致状态要保证满所有数据约束。(注意Qƈ不要求在M事务的中间点保持一致性)(j)?/p>
隔离性(IsolationQ。事务的影响独立Q或隐藏Q于其他事务Q参?4.1?#8220;q发控制”提要栏?/p>
持久性(DurakilityQ。在事务完成后,它的影响是永久和持箋(hu)的——即便是pȝ崩溃?/p>
事务理论是独立于关系模型的重大问题。由Jim Gray和Andreas Reuter所著的Transaction Processing: Concepts and TechniquesQMorgan KaufmannQ是一本很好的参考书?/p>
ü提示 l 不要忘记使用COMMIT或ROLLBACK昑ּl束事务。没有结束点导致回滚的最后未提交事务巨大Q可能带来意外的数据变化或程序异怸止。因Z务在生存期锁定行、整个表、烦(ch)引和其他资源Q所以要让事务尽可能。COMMIT或ROLLBACK为其他事务释放资源?/p>
l 可以嵌套事务。最大嵌套数因DBMS而异?/p>
使用一条SET语句的UPDATE更新多个列比使用多个UPDATE快。例如,查询Q?/p>
UPDATE mytable SET col1 = 1 col2 = 2 col3 = 3 WHERE col1 <> 1 OR col2 <> 2 OR col3 <> 3; ?个UPDATE语句好,因ؓ(f)它减了(jin)日志记录Q尽带来锁定)(j)?/p>
l 默认情况下,DBMSq行在自动提交模式(autocommit modeQ,除非被其他显式或隐式事务重写Q或被系l设|关闭)(j)。在q种模式下,每一条语句作Z个事务执行。如果语句执行成功,DBMS将它提交;如果DBMS遇到错误Q就回滚q条语句?/p>
l 对于长的事务Q可以设|称为存储点QsavepointsQ的中间标志Q将事务分割为小Dc(din)存储点允许回滚从事务当前点C务靠前的旉点之间的变化Q假定事务还没有提交Q。如果在一pd复杂的插入、更新、删除操作未提交Ӟ意识到最后的变化是不正确的或不必要的Q用存储点可以避免重新提交所有语句。Microsoft Access不支持存储点。在Oracle、DB2、MySQL和PostgreSQL中,使用语句Q?/p>
SAVEPOINT savepoint_name 对于Microsoft SQL ServerQ用:(x) SAVE TRANSACTION savepoint_name; 查阅DBMS文档来了(jin)解有兛_储点锁定的细节知识及(qing)如何COMMIT或ROLLBACK到特定的存储炏V?/p>
q Oracle和DB2是隐式开始事务的。ؓ(f)?jin)在Oracle ?DB2中运行代?4-1和代?4-2Q要删除语句QBEGIN TRANSACTIONQ?/p>
Z(jin)在MySQL中运行代?4-1和代?4-2Q将语句BEGIN TRANSACTION;变(sh)ؓ(f)START TRANSACTION;Q或BEGINQ?/p>
MySQL通过InnoDB和BDB表支持事务,h阅MySQL文档?jin)解事务。Microsoft SQL Server?Oracle、MySQL和PostgreSQL支持SET TRANSACTION语句讄事务特征。DB2通过服务器层和连接初始化讄控制事务特征?/p>
OLTPQOn_line Transaction Processing 联机事务处理 OLAPQOn_line Analytical Processing 联机分析处理 OLTP思义Q以业务处理Z。OLAP则是专门为支持复杂的分析操作而设计的Q侧重于对决{h员和高层理人员的决{支持,可以应分析h员的要求快速、灵zdq行大数据量的复杂查询处理,q以一直直观的形式把查询结果提供?/span> OLTP与OLAP 的主要区别有以下几点Q?/span> Q?Q、所面向的用户和pȝQOLTP是面向客L(fng)Q由职员或客戯行事务处理或者查询处理。OLAp是向向市(jng)场的Q由l理、主和分析人员q行数据分析和决{的?/span> Q?Q、数据内容:(x)OLTPpȝ理当前数据Q这些数据通常很琐,难以用于决策。OLAPpȝ理大量历史数据Q提供汇d聚集机制Qƈ在不同的_度U别上存储和理信息Q这些特点得数据适合于决{分析?/span> Q?Q、数据库设计Q通常QOLTP采用ER模型和面向应用的数据库设计,而OLAPpȝ通常采用星型模式或雪花模式和面向主题的数据库设计?/span> Q?Q、视图:(x)OLTPpȝ主要x(chng)一个企业或部门的当前数据,而不涉及(qing)历史数据或不同组l的数据。与之相反,OLAPpȝ常常跨越一个企业的数据库模式的多个版本QOLAPpȝ也处理来自不同组l的信息Q由多个数据源集成的信息?/span> Q?Q、访问模式:(x)OLTPpȝ的访问主要由短的原子事务l成Q这U系l需要ƈ发控制和恢复机制。而OLAPpȝ的访问大部䆾是只L作,其中大部份是复杂查询?/span> Q?Q、度量:(x)OLTP专注于日常时实操作,所以以事务吞吐量ؓ(f)度量QOLAP以查询吞吐量和响应时间来度量?/span> 以上初步辨识?jin)这二个概念Q以后对于满嘴跑概念的h可以略有防范?/span>
]]>
3.主键列不允许I|而唯一性烦(ch)引列允许I倹{?img src ="http://www.shnenglu.com/prayer/aggbug/162519.html" width = "1" height = "1" />
]]>
以下是代码片D:(x)
CREATE TABLE EMPLOYE (
EMPLOYEID INTEGER NOT NULL,---员工?
NAME VARCHAR(20) NOT NULL,---姓名
SALARY DOUBLE---薪水
);
INSERT INTO EMPLOYE (EMPLOYEID,NAME,SALARY) VALUES
(1,'张三',1000),
(2,'李四',2000),
(3,'王五',3000),
(4,'赵六',4000),
(5,'高(sh)',5000);
以下是代码片D:(x)
CREATE TABLE MANAGER (
EMPLOYEID INTEGER NOT NULL,---l理?
NAME VARCHAR(20) NOT NULL,---姓名
SALARY DOUBLE---薪水
);
INSERT INTO MANAGER (MANAGERID,NAME,SALARY) VALUES
(3,'王五',5000),
(4,'赵六',6000);
以下是代码片D:(x)
CREATE TABLE EMPLOYE (
EMPLOYEID INTEGER NOT NULL,---员工?
NAME VARCHAR(20) NOT NULL,---姓名
SALARY DOUBLE---薪水
);
INSERT INTO EMPLOYE (EMPLOYEID,NAME,SALARY) VALUES
(1,'张三',1000),
(2,'李四',2000),
(3,'王五',3000),
(4,'赵六',4000),
(5,'高(sh)',5000);
l过一D|_(d)你发现这L(fng)数据模型Q或者说表结构设计简直就是一大|W,l理和雇员都是员工嘛Qؓ(f)什么要设计两个表呢Q发现错误后需要改正,所以你军_Q删除经理表(MANAGER)表,MANAGER 表中的数据合q到EMPLOYE 表中Q仔l分析发玎ͼ王五在两个表中都存在(可能是干的好升官?sh)?Q而刘八在EMPLOYE 表中q不存在Q现在,我们要求把EMPLOYE 表中不存在的MANAGER都插入到EMPLOYE 表中Q存在的更新薪水。该怎么办呢Q这个问题ƈ不难Q通常Q我们可以分两步Q如下所C:(x)
以下是代码片D:(x)
CREATE TABLE MANAGER (
EMPLOYEID INTEGER NOT NULL,---l理?
NAME VARCHAR(20) NOT NULL,---姓名
SALARY DOUBLE---薪水
);
INSERT INTO MANAGER (MANAGERID,NAME,SALARY) VALUES
(3,'王五',5000),
(4,'赵六',6000);
以下是代码片D:(x)
UPDATE EMPLOYE AS EM SET SALARY=(SELECT SALARY FROM MANAGER WHERE MANAGERID=EM.EMPLOYEID)
WHERE EMPLOYEID IN (
SELECT MANAGERID FROM MANAGER
);
以下是代码片D:(x)
INSERT INTO EMPLOYE (EMPLOYEID,NAME,SALARY)
SELECT MANAGERID,NAME,SALARY FROM MANAGER WHERE MANAGERID NOT IN (
SELECT EMPLOYEID FROM EMPLOYE
);
以下是代码片D:(x)
UPDATE EMPLOYE AS EM SET SALARY=(SELECT SALARY FROM MANAGER WHERE MANAGERID=EM.EMPLOYEID)
WHERE EMPLOYEID IN (
SELECT MANAGERID FROM MANAGER
);
以下是代码片D:(x)
INSERT INTO EMPLOYE (EMPLOYEID,NAME,SALARY)
SELECT MANAGERID,NAME,SALARY FROM MANAGER WHERE MANAGERID NOT IN (
SELECT EMPLOYEID FROM EMPLOYE
);
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED THEN UPDATE SET EM.SALARY=MA.SALARY
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY);
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED THEN UPDATE SET EM.SALARY=MA.SALARY
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY);
在上面的处理中,我们用经理表(MANAGER)的薪水更C(jin)雇员?EMPLOYE)的薪_(d)假设现在要求Q如果经理表(MANAGER)的薪?gt;雇员?EMPLOYE)的薪水的时候更斎ͼ否则不更斎ͼ怎么办呢Q如下:(x)
以下是代码片D:(x)
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED AND EM.SALARY
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY);
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED AND EM.SALARY
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY);
以下是代码片D:(x)
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED AND EM.SALARY
WHEN MATCHED AND EM.SALARY>MA.SALARY THEN SIGNAL SQLSTATE '70001' SET MESSAGE_TEXT = 'EM.SALARY>MA.SALARY'
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY)
ELSE IGNORE;
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED AND EM.SALARY
WHEN MATCHED AND EM.SALARY>MA.SALARY THEN SIGNAL SQLSTATE '70001' SET MESSAGE_TEXT = 'EM.SALARY>MA.SALARY'
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY)
ELSE IGNORE;
以下是代码片D:(x)
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED AND EM.SALARY
WHEN MATCHED AND EM.SALARY>MA.SALARY THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY)
ELSE IGNORE;
MERGE INTO EMPLOYE AS EM
USING MANAGER AS MA
ON EM.EMPLOYEID=MA.MANAGERID
WHEN MATCHED AND EM.SALARY
WHEN MATCHED AND EM.SALARY>MA.SALARY THEN DELETE
WHEN NOT MATCHED THEN INSERT VALUES (MA.MANAGERID,MA.NAME,MA.SALARY)
ELSE IGNORE;
]]>
LDAP是一个协议,一个标准?br>Z(jin)实现q个协议Q需要一个实体,q就是LDAP的品。Server, Client, StorageQInterface.
|顶有一文? 讲述?jin)什么是LDAP服务?/span>, 看了(jin)一?我觉得作者在概念上还有些模糊的地斏V比如和数据?/span>的关pȝQ作者是用了(jin)一个MySQL作的比较和对比?br>我也看了(jin)一些这里的朋友提到的问题,其实如果?jin)解LDAP的内涵,很好解{这些问题(sh)(jin)?br>
下面我从自己的理解,来说一下,希望和大家共享?br>首先LDAP是一个轻量的?LightWeight)Q是一个Directory(D)Q存取的协议(Access Protocol)?
我要着重指出,LDAP是一?span class=t_tag onclick=tagshow(event) href="tag.php?name=%CA%FD%BE%DD">数据库,但是又不是一个数据库。说他是数据库,因ؓ(f)他是一个数据存储的东西。但是说他不是数据库Q是因ؓ(f)他的作用没有数据库这么强大,而是一个目录?br>Z(jin)理解Q给一个例子就是电(sh)话簿Q黄)(j)。我们用?sh)话的目的是?f)?jin)查找某个公司的电(sh)话Q在q个?sh)话中附带了(jin)一些这个公司的基本信息Q比如地址Q经营范_(d)联系方式{?br>其实q个例子是一个LDAP在现实生zM的表现。电(sh)话簿的组l结构是一条一条的信息l成Q信息按照行业,cLq行?jin)分cR每条记录都分成?jin)若q的区域Q其中涵盖了(jin)我们要的信息。这是一个Directory。一个树(wi)状的l构Q每个叶子都是由一条一条的分成若干区域的记录。LDAP是q么一个东ѝ?br>从概念上_(d)LDAP分成?jin)DN, OU{。OU是一个树(wi)QDN可以理解ؓ(f)是叶子,叶子q可以有更小的叶子。但是LDAP最大的分层按照IBM的文档是4层?br>
q是上面q个例子Q电(sh)话簿q(sh)话公司进行维护,因此写是׃们去写,ȝl。写完了(jin)Q组l好?jin),完成?jin)Q以后再写,再组l的ơ数是有限的。而其作用是ؓ(f)?jin)查找。LDAP也是cMQ目的不是ؓ(f)?jin)写Q主要是Z(jin)查找。这回{了(jin)有同志问Q有写有ȝq发怎么解决的问题。LDAP的用途不是针对这个来设计的,如果你有q样的需求,解决办法应该是数据库,而不是LDAP。这是另外一个例子,Access和SQL Server。Access是一个数据库产品Q但是主要用于家庭,功能和性能都比较弱。SQL Server是一个专业的数据?span class=t_tag onclick=tagshow(event) href="tag.php?name=%CF%B5%CD%B3">pȝQ功能强大。LDAP是一个轻量的品,主要目的是ؓ(f)?jin)查Q因此在架构和优化主要是针对读,而不是写。但q不是说LDAP不能满Q只是说强项不在q里?br>
LDAP作ؓ(f)一个统一认证的解?span class=t_tag onclick=tagshow(event) href="tag.php?name=%B7%BD%B0%B8">Ҏ(gu)Q主要的优点在能够快速响应用L(fng)查找需求。比如用L(fng)认证Q这可能?x)有大量的ƈ发。如果用数据库来实现Q由于数据库l构分成?jin)各个表Q要满认证q个非常单的需求,每次都需要去搜烦(ch)数据库,合成qo(h)Q效率慢也没有好处。虽然可以有CacheQ但是还是有Ҏ(gu)贏VLDAP是一张表Q只需要用户名和口令,加上一些其他的东西Q非常简单。从效率和结构上都可以满证的需求。这是Z么LDAP成ؓ(f)现在很h们的l一认证的解x(chng)案的优势所在?br>
当然LDAP也有数据写入的借口Q是可以满录入的要求的。这里就不多说了(jin)?br>我认为现在最大的LDAP ServerQ应该还是Microsoft的AD。虽然不一定是标准的,但是的确是用的最多的一个LDAP Server。每个公司只要用到域Q就肯定?x)用C(jin)?/td>
]]>
]]>
1、生命存在周期:(x)
Q、理Zpȝ临时表是不需要显C的drop的,它是Z?x)话的,当系l(f)时表Z的连接关闭的时候,pȝ临时表将l束它的生命Q这是最普通也是最常用的?br>
Q、当一个被调用对象的返回值是一个在临时表上执行的结果集Q这个被调用对象执行完毕的时候,是关闭连接的Q但是,q时候(f)时表是不消失的,q时候系l(f)时表在调用者结束的时候才消失。因回的l果集只是一个相当于指针的东西,指向临时表内存(sh)的地址Q指向(f)时表的指针还在用的时候,临时表是不能drop掉的。这带来?jin)很复杂的问题,首先Q存储过E中是不能drop临时表的Q而程序中没有创徏临时表,也应该是不drop的,临时表什么时间drop呢?其次Q我们在一个连接中Q无法2ơ调用一个存储过E,他将告诉你(f)时表已经存在。可以做一个简单的例子Q写一个带有(f)时表q回l果的存储过E,在调用存储存储过E的E序中,我们完全可以讉Kq个临时表?br>单例子:(x)
存储q程
/**
* JDBC 存储q程 ADMINISTRATOR.P1
*/
import java.sql.*; // JDBC c?br>
public class P1
{
public static void p1 ( ResultSet[] rs ) throws SQLException, Exception
{
// 获取与数据库的连?br> Connection con = DriverManager.getConnection("jdbc:default:connection");
PreparedStatement stmt = null;
String sql;
sql = "declare global temporary table session.temp(cc char(5)) not logged";
stmt = con.prepareStatement( sql );
stmt.executeUpdate();
sql = "insert into session.temp values ('1'),('2')";
stmt = con.prepareStatement( sql );
stmt.executeUpdate();
sql = "SELECT * from session.temp";
stmt = con.prepareStatement( sql );
rs[0] = stmt.executeQuery();
Q/关闭q接Q注意,q个地方在rs[0]Z(f)时表的结果集q回的时候,stmt是无法关闭的Q(f)时表是无法drop的,而con是可以关闭的Q关闭后临时表还存在Q?br> if (con != null) con.close();
}
}
客户端调用我直接用命令行调用的?br>db2 =>; connect to sample
数据库连接信?br>
数据库服务器 = DB2/NT 7.2.1
SQL 授权标识 = ADMINIST...
本地数据库别?nbsp; = SAMPLE
Q/自动提交设为false?br>db2 =>; update command options using c off
DB20000I UPDATE COMMAND OPTIONS 命o(h)成功完成?br>
Q/调用q程
db2 =>; call p1()
CC
1
2
"P1" RETURN_STATUSQ?0"
Q/看看存储q程中用的临时表,数据是可以看到的?br>db2 =>; select * from session.temp
CC
-----
1
2
2 条记录已选择?br>Q/一个连接中再次调用Q失败了(jin)
db2 =>; call p1()
SQL0601N 要创建的对象名与cd?DECLARED TEMPORARY TABLE" 的现存名U?"SESSION.TEMP" 相同?nbsp; SQLSTATE=42710
Q/drop一下?o(w)kQ可以的
db2 =>; drop table session.temp
DB20000I SQL 命o(h)成功完成?br>Q/看看q有吗?没了(jin)Q?br>db2 =>; select * from session.temp
SQL0204N "SESSION.TEMP" 是未定义的名U?nbsp; SQLSTATE=42704
Q/再次调用Q成功了(jin)
db2 =>; call p1()
CC
1
2
"P1" RETURN_STATUSQ?0"
Q、Websphere上的E序中用系l(f)时表Q因为websphere的连接用连接池的技术,q带来了(jin)好处Q但是同时也带来?jin)一些让人容易误解的地方Q我们在E序中要关闭q接Q很多时候看上去是关闭了(jin)数据库的q接Q事实上也是q样的,但是当websphere的连接数在websphereq接池规定的q接数的范围之内的时候,E序中关闭连接是不能直接关闭数据库的q接的,q接池ɘq接l箋(hu)保持Q这时候,我们的关闭连接释攄是该q接和相兛_素在websphere和javaE序中用的资源Q而该q接使用的数据库资源是无法得到释攄。也是_(d)当我们在该连接上使用临时表的时候,我们在程序中关闭?jin)连接,但是临时表是q存在的Q连接池中把q个q接分配l其他程序用的时候,其他E序q可以用这个(f)时表Q这q不是我们想要的。这要求我们在程序的中显式的drop掉(f)时表。(q是在南宁解决系l(f)时表使用问题?sh),到的一个问题,大家可以很容易的模拟出来Q?br>
同时q也让我们注意,一些设|,应该采取Zؓ(f)控制的方式,而不要采取默认,比如autoCommitQ我们不能觉得程序结束了(jin)Q就提交?jin),因?f)默认是程序结束提交的Q如果错?jin)就都回滚?jin)Q但是如果连接上讑֮的是autoCommit为true的话Q程序出错就只能回滚你的出错前最后一ơ未提交事务Q也怽q在ZE序中出现的q种错误头疼Q他Z么前面的?x)提交呢Q?br>一D代码,应尽可能的保持它的独立性,执行不要q多依赖于环境和其他的代码,我想q是应该考虑的。就象在oracle数据库上执行sql和在db2数据库上执行sql有很明显的区别一Poracle默认是不提交的,而db2默认是提交的Q这样在不主动控制事务的情况下,一个sql执行的结果是完全不同的?br>
2、数据存在周?br>临时表的数据是在内存?sh)的Q当你向一个(f)时表插入数据的时候,他同时是直接的写到硬盘(sh)的,如果你的~冲池可以满(f)时表的数据都存在内存?sh),它在使用的时候是不需要读盘?sh)的数据的,除非你的~冲池不能满Iq样?x)降低?f)时表的性能。我们知道,事务的提交和回滚是对数据库的更改做永久化Q从内存?sh)的更改到硬盘?sh)的更Ҏ(gu)者放弃更改(在更改实现的同时Q是回收曄占用的内存资源的Q。对一个永久表Q插入数据,是在你提交之前Q别的程序访问不?jin)你插入的数据,在你提交之后Q所有的E序都可以访问你插入的数据;而(f)时表不是q样的,无论执行提交q是回滚Q(f)时表数据占用的内存资源都被释放Q同时(f)时表写到盘?sh)的数据也全部删除?br>也就是说Q无论执行提交还是回滚,临时表的数据都没?jin),但是临时表还是存在的Q这一炚w要大家注意,在用的q程中说插入?jin)数据,但是没有数据Qؓ(f)什么呢Q?
看一个简单的命o(h)行模拟的例子Q?br>db2 =>; connect to sample
数据库连接信?br>
数据库服务器 = DB2/NT 7.2.1
SQL 授权标识 = ADMINIST...
本地数据库别?nbsp; = SAMPLE
//创徏临时?br>db2 =>; declare global temporary table session.test(col1 char(5)) not logged
DB20000I SQL 命o(h)成功完成?br>//插入数据
db2 =>; insert into session.test values('5')
DB20000I SQL 命o(h)成功完成?br>//选择数据Q没有数据?是的Q?br>db2 =>; select * from session.test
COL1
-----
0 条记录已选择?br>//我们把提交方式改为默认不提交
db2 =>; update command options using c off
DB20000I UPDATE COMMAND OPTIONS 命o(h)成功完成?br>//再次插入数据
db2 =>; insert into session.test values('5')
DB20000I SQL 命o(h)成功完成?br>//选择数据QokQ我们看到数据了(jin)Q?br>db2 =>; select * from session.test
COL1
-----
5
1 条记录已选择?br>//提交一下,或者执行rollback也可?nbsp;
db2 =>; commit
DB20000I SQL 命o(h)成功完成?br>//数据没了(jin)
db2 =>; select * from session.test
COL1
-----
0 条记录已选择?br>
以上是系l(f)时表使用的过E中我们E序开发者需要注意的可能出现的问题,知道问题是怎么出现的,我们应该如何解决出现的问题和如何更好的用(f)时表Q这是我们的目标?
]]>
from t_aatable
WITH HOLD 声明该游标可以在创徏它的事务成功提交后l用? WITHOUT HOLD 声明该游标不能在创徏它的的事务提交后使用?br>
~省? WITH HOLD ?!
DB2
Oracle和DB2的事务L隐式开始,q些DBMS没有用来开始事务的语句。在Microsoft Access、Microsoft SQL Server、MySQL和PostgreSQL中,可以使用BEGIN语句昑ּ开始事务。SQL:1999引入START TRANSACTION语句——由于这发生在DBMS使用BEGIN开始事务很久以后,因此不同DBMS扩展BEGIN的语法也各不相同。MySQL和PostgreSQL支持START TRANSACTIONQ作为BEGIN同义词)(j)?/p>
Microsoft Access中,通过SQL视图H口或DAO无法执行事务Q必M用Microsoft Jet OLE DB Provider和ADO?/p>
]]>
]]>
9i提供四种分区Ҏ(gu)Q范围分区,列表分区Q哈希分区和混合分区Q?br>
· 范围分区是根椐分区键的不同取D围来划分子集的,关键字RANGEQ?VALUES LESS THANQ?br>
· 列表分区是根椐分区键的一些离散的取值来划分子集的,关键字LISTQ?VALUESQ?br>
· 哈希分区是应用哈希算法将分区键对应到某个子集中去Q关键字HASHQ?PARTITIONSQ?br>
· 混合分区只能有两层,W一层是范围分区Q第二层可以是列表分区或者哈希分区;
· 范围分区和列表分ZQ如果插入记录的分区键没有对应的容纳分区Q会(x)产生ORA-14400Q?br>
· update操作如果?x)记录从一个分Ud另一个分区,且分的ROW MOVEMENT属性是DISABLEQ会(x)产ORA-14402Q?br>
· 分区表上的烦(ch)引有两大c:(x)普通的二叉?wi)?ch)引,分区索引Q下面讲到的都是分区索引Q?br>
· 按烦(ch)引分区和表分区间的对应关pd以分为局部烦(ch)引和全局索引Q?br>
Ø 局部烦(ch)引的索引分区和表分区间是一一对应的,全局索引则相反;
Ø 局部烦(ch)引的分区Ҏ(gu)可以用上面提到四U的M一U,全局索引的分区方法只有范围分区(而且最高的分区必须用MAXVALUE来定义)(j)Q?br>
Ø ORACLE自动l护局部烦(ch)引的分区Q当表分合ƈQ分裂或删除Ӟ兌的烦(ch)引分Z?x)被合ƈQ分裂或删除Q对分区表执行管理操作时?x)其上的全局索引失效Q?br>
Ø 建在分区表的位图索引必须是局部分区烦(ch)引;
Ø ORACLE推荐可能地使用局部烦(ch)引;
· 按烦(ch)引栏位和分区键间的关pd为前~索引和非前缀索引Q?br>
Ø 前缀索引最前面的栏位是分区键栏位,非前~索引相反Q?br>
· 在这两种分类Ҏ(gu)的四U组合中Q只有三U有效(局部前~索引Q局部非前缀索引Q全局前缀索引Q,不存在全局非前~索引Q?br>
· 分区表给C(j)BO带来很多选项Q如分区排除Qƈ行分接等?br>
一个硬盘经qFDISK的划分和高格式化以后,?x)在所属的操作pȝ中徏立分Q记录一些有关硬盘给哪一U操作系l用,盘的容量大以?qing)开始磁柱面和结束磁柱面的分配,哪一个硬盘启动,引导?/font>QBoot SectorQ,文g分配表(F(tun)ATQ、根目录和数据区{一pd数据。现分内的内容归纳如下Q?
A、分是创建在盘的第0柱面、第0道Q第1个扇Z?
B、记录操作系l的数据QDOSQOS2或其他OSQ?
C、记录分区硬盘的CQ磁柱面Q、HQ磁_(d)(j)QSQ扇区)(j)的数量?
D、记录分配的柱面(CylinderQ的开始。结束和定w?
E、记录可启动的硬盘(ActiveQ?
F、徏立引导区QBoot SectorQ?
G、徏立文件分配表QF(tun)ATQ?
H、徏立根目录?
I、徏立数据存储区?
]]>
create or replace view testview
as
select empno,ename from emp where ename like ‘M%’
with check option;
q里我们创徏?jin)一个视图,q用了(jin)with check option来限制了(jin)视图?然后我们来看一下视囑含的l果Q?br>select * from testview得到Q?br>EMPNO ENAME
——? ——?#8211;
7654 MARTIN
7934 MILLER
q两条记?/p>
然后我们在试囑ְ其中一条更斎ͼ(x)
update testview
set ename = ‘Mike’
where empno = 7654;
OK,q条更新语句可以执行Qƈ没有什么问题,但是当我们执行另一条更新时Q?br>update testview
set ename = ‘Robin’
where empno = ‘7654′;
׃(x)出现ORA-01402: 视图 WITH CHECK OPTIDN q反 where 子句的错误,q是因ؓ(f)什么呢Q?/p>
q是因ؓ(f)前面我们在创图时指定?jin)witch check option关键字,q也是_(d)更新后的每一条数据仍然要满创徏视图时指定的where条gQ所以我们这里发生了(jin)错误ORA-01402?/p>
但是需要说明的?Q虽然指定了(jin)with check optionQ我们还是可以删除视图中的数据。例如上例中Q我们可以?br>delete from test where where empno = 7654
--------------------------------------------------------------------------------
我创Z个视图:(x)
create view IS_student
as
select sno,sname,sage
from student
where sdept='IS'
with check option;
加上?jin)with check option;后,不能执行插入操作Q?nbsp;
insert into is_student
values('95100','李娜',12)
什么原因?不加上with check option则可以!
with check option可以q么解释Q通过视图q行的修改,必须也能通过该视囄C改后的结果。比如你insertQ那么加的这条记录在h视图后必d以看刎ͼ如果修改Q修改完的结果也必须能通过该视囄刎ͼ如果删除Q当然只能删除视N有显C的记录?nbsp;
--->而你只是查询出sdept='is'的纪录,你插入的Ҏ(gu)不符合sdept='is'呀Q所以就不行
默认情况下,׃行通过视图q行d或更斎ͼ当其不再W合定义视图的查询的条gӞ它们即从视图范围中消失。例如,可创Z个查询,从而定义一个视图以在表中检索所有员工薪水低?nbsp; $30,000 的行。如果该员工的薪水涨C(jin) $32,000Q则查询视图时该特定员工不再出玎ͼ因其薪水不符合视图所讄标准。但是,W(xu)ITH CHECK OPTION 子句强制所有数据修改语句均Ҏ(gu)视图执行Q以W合定义视图?nbsp; SELECT 语句中所讄条g。如果用该子句Q修改行旉考虑C让它在修改完后从视图中消失。Q何可能导致行消失的修攚w?x)被取消Qƈ昄错误信息?nbsp;
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/hippoppower/archive/2009/09/03/4516733.aspx
oracle 游标?个属性:(x)%ISOPENQ?FOUNDQ?NOTFOUNDQ?ROWCOUNT?/p>
%ISOPEN判断游标是否被打开Q如果打开%ISOPEN{于true,否则{于falseQ?/p>
%FOUND %NOTFOUND判断游标所在的行是否有效,如果有效Q则%FOUNDD{于trueQ否则等于falseQ?/p>
%ROWCOUNTq回当前位置为止游标d的记录行数?/p>
隐式游标和显式游?/p>
隐式游标
昑ּ游标
PL/SQLl护Q当执行查询时自动打开和关?
在程序中昑ּ定义、打开、关闭,游标有一个名字?
游标属性前~是SQL
游标属性的前缀是游标名
属?ISOPENL为FALSE
%ISOPENҎ(gu)游标的状态确定?
SELECT语句带有INTO子串Q只有一行数据被处理
可以处理多行数据Q在E序中设|@环,取出每一行数据?
记录变量
定义一个记录变量用TYPE命o(h)?ROWTYPEQ?/p>
DECLARER_emp EMP%ROWTYPE;CURSOR c_emp IS SELECT * FROM emp;
或:(x)
DECLARECURSOR c_emp IS SELECT ename,salary FROM emp;R_emp c_emp%ROWTYPE;
带参数的游标
与存储过E和函数怼Q可以将参数传递给游标q在查询中用。这对于处理在某U条件下打开游标的情况非常有用。它的语法如下:(x)
CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;
定义参数的语法如下:(x)
Parameter_name [IN] data_type[{:=|DEFAULT} value]
与存储过E不同的是,游标只能接受传递的|而不能返回倹{参数只定义数据cdQ没有大。
另外可以l参数设定一个缺省|当没有参数g递给游标Ӟ׃用缺省倹{游标中定义的参数只是一个占位符Q在别处引用该参C一定可靠?br>
在打开游标时给参数赋|语法如下Q?/p>
OPEN cursor_name[value[,value]....];
游标FOR循环
FOR循环的游标按照正常的声明方式声明Q它的优点在于不需要显式的打开、关闭、取数据Q测试数据的存在、定义存放数据的变量{等。游标FOR 循环的语法如下:(x)
FOR record_name IN(corsor_name[(parameter[,parameter]...)]| (query_difinition)LOOPstatementsEND LOOP;
2 游标的更新和删除
在PL/SQL中依然可以用UPDATE和DELETE语句更新或删除数据行。显式游标只有在需要获得多行数据的情况下用。PL/SQL提供?jin)仅仅用游标就可以执行删除或更新记录的?gu)?/p>
UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE操作的表中取出的最q的数据。要使用q个Ҏ(gu)Q在声明游标时必M用FOR UPDATE子串Q当对话使用FOR UPDATE子串打开一个游标时Q所有返回集中的数据行都处于行U(ROW-LEVELQ独占式锁定Q其他对象只能查询这些数据行Q不能进行UPDATE、DELETE或SELECT...FOR UPDATE操作?/strong>
语法Q?/p>
FOR UPDATE [OF [schema.]table.column[,[schema.]table.column]..
[nowait]
在多表查询中Q用OF子句来锁定特定的?如果忽略?jin)OF子句Q那么所有表中选择的数据行都将被锁定。如果这些数据行已经被其他会(x)话锁定,那么正常情况下ORACLE等待,直到数据行解锁?/p>
在UPDATE和DELETE中用WHERE CURRENT OF子串的语法如下:(x)
WHERE{CURRENT OF cursor_name|search_condition}
例:(x)
DELCARECURSOR c1 IS SELECT empno,salaryFROM empWHERE comm IS NULLFOR UPDATE OF comm;v_comm NUMBER(10,2);BEGINFOR r1 IN c1 LOOPIF r1.salary<500 THENv_comm:=r1.salary*0.25;ELSEIF r1.salary<1000 THENv_comm:=r1.salary*0.20;ELSEIF r1.salary<3000 THENv_comm:=r1.salary*0.15;ELSEv_comm:=r1.salary*0.12;END IF;UPDATE emp;SET comm=v_commWHERE CURRENT OF c1l;END
本篇文章来源?IT中国 转蝲请以链接形式注明出处 |址Q?a >http://www.it86.cc/oracle/2008/0410/30076.shtml
session: 一个由O(jin)RACLE用户产生的连接,一个用户可以生多个SESSION Q但怺之间是独立的?/p>
transaction:所有的改变都可以划分到transaction里,一?transaction包含一个或多个SQL。当一个SESSION建立的时候就是一个TRANSACTION开始的时刻Q此后transaction?开始和l束由DCL控制Q也是每个COMMIT/ROLLBACK都标C着一个transaction的结束?/p>
consistencyQ是对于statementU别而不是transactionU别来说的。sql statement 得到的数据都是以sql statement开始的IMAGE?/p>
LOCK的基本情况:(x)
update, insert ,delete, select ... for update?x)LOCK相应的ROW ?/p>
只有一个TRANSACTION可以LOCK相应的行Q也是说如果一个ROW已经LOCKED?jin),那就不能被其他TRANSACTION所LOCK?jin)?/p>
LOCK由statement产生但却由TRANSACTIONl尾QcommitQrollbackQ,也就是说一个SQL完成后LOCKq(sh)(x)存在Q只有在COMMIT/ROLLBACK后才?x)RELEASE?/p>
|
前面的FOR UPDATE省略Q下面我们来讲一下OF?/p>
|
则transaction B可以对b表wwm3的相应行q行DML操作,但不能对a表wwm2相应行进行DML操作.
反一下看看?/p>
|
则transaction B可以对a表wwm2的相应行q行DML操作,但不能对b表wwm3相应行进行DML操作.
也就是说LOCK的还是行,只是如果不加OF的话?x)对所有涉?qing)的表LOCK?加了(jin)OF后只?x)LOCK OF 字句所在的TABLE.
NOWAITQ如果一定要用FOR UPDATEQ我更徏议加上NOWAITQ?/p>
当有LOCK冲突时会(x)提示错误q结束STATEMENT而不是在那里{待.q回错误?ORA-00054: resource busy and acquire with NOWAIT specified"
另外如下用法也值得推荐Q应该酌情考虑使用?/p>
|
5U后?x)出现提C:(x)
|
出现提示Q?/p>
|
同样也是在transactionl束时才?x)释放lock?/p>
DEADLOCK:
|
?font size=2>是?/font>两个transaction都相互试囑֎lockҎ(gu)已经lock的ROWQ都在等待对斚w放自qlockQ这样就使死锁。另外,deadlock也会(x)?00提示?/p>
使用说明
Select…For Update语句的语法与select语句相同Q只是在select语句的后面加FOR UPDATE [NOWAIT]子句?/p>
该语句用来锁定特定的行(如果有where子句Q就是满where条g的那些行Q。当q些行被锁定后,其他?x)话可以选择q些行,但不能更Ҏ(gu)删除q些行,直到该语句的事务被commit语句或rollback语句l束为止?/span>
本章主要讲解如下内容Q?/p>
?nbsp; 隔离U别和锁
?nbsp; 加锁ȝ
?nbsp; 乐观?/p>
?nbsp; 内部?/p>
?nbsp; 讄锁相关的注册变量
要维护数据库的一致性和数据完整性,同时又允许多个应用程序同时访问一个数据库Q将q样的特性称为ƈ发性。DB2数据库尝试强制实施ƈ发性的Ҏ(gu)之一是用隔ȝ别,它决定在W一个事务访问数据时Q如何对其他事务锁定或隔该事务所使用的数据。DB2使用下列隔离U别来强制实施ƈ发性:(x)
?nbsp; 可重复读(Reapeatable ReadQRR)
?nbsp; ȝ定?Read StabilityQRS)
?nbsp; 游标E_?Cursor StabilityQCS)
?nbsp; 未提交的?Uncommitted ReadQUR)
隔离U别是根据称为现?Phenomena)的三个禁止操作序列来声明的:(x)
?nbsp; 脏读(Dirty Read)Q在事务A提交修改l果之前Q其他事务即可看C务A的修改结果?/p>
?nbsp; 不可重复?Non-Repeatable Read)Q在事务Q提交之前,允许其他事务修改和删除事务A涉及(qing)的数据,D事务Q中执行同样操作的结果集变小?/strong>
?nbsp; qd?Phantom Read)Q事务A在提交查询结果之前,其他事务可以插入或者更改事务A涉及(qing)的数据,D事务A中执行同h作的l果集增大?/strong>
数据库ƈ发?可以同时讉K同一资源的事务数?因隔ȝ别不同而有所差异Q可重复读隔ȝ别可以防止所有现象,但是?x)大大降低ƈ发性。未提交读隔ȝ别提供了(jin)最大的q发性,但可能会(x)造成“脏读”?#8220;qd?#8221;?#8220;不可重复?#8221;现象。DB2默认的隔ȝ别是CS?/p>
可重复读隔离U别是最严格的隔ȝ别。在使用它时Q一个事务的操作l果完全与其他ƈ发事务隔,脏读、不可重复读、像读都不?x)发生。当使用可重复读隔离U别Ӟ在事务执行期间会(x)׃n(S)锁定该事务以M方式引用的所有行Q在该事务中多次执行同一条SELECT语句Q得到的l果数据集L相同的。因此,使用可重复读隔离U别的事务可以多ơ检索同一行集Qƈ可以对它们执行Q意操作,直到提交或回滚操作终止事务。但是,在事务提交前Q不允许其他事务执行?x)?jing)响该事务正在讉K的Q何行的插入、更新或删除操作。ؓ(f)?jin)确保这U行为,需要锁定该事务所引用?em>每一行—?而不是仅锁定被实际检索或修改的那些行。因此,如果一个表中有1000行,但只(g)索两行,则整个表(1000行,而不仅是被检索的两行)都会(x)被锁定。输出结果如下:(x)
C:\>db2 +c select empno,firstnme,salary from employee where empno between '000010' and '000020' with rr
EMPNO FIRSTNME SALARY
------ ------------ -----------
000010 CHRISTINE 152750.00
000020 MICHAEL 94250.00
2 条记录已选择?/p>
我们通过“get snapshot for locks on sample”命o(h)来监控表加锁情况Q输出结果如下:(x)
C:\>db2 update monitor switches using lock on
DB20000I UPDATE MONITOR SWITCHES命o(h)成功完成?/p>
C:\>db2 get snapshot for locks on sample | more
--------------?-----------------
锁定列表
锁定名称 = 0x020006000E0040010000000052
锁定属?nbsp; = 0x00000010
发行版标?nbsp; = 0x00000004
锁定计数 = 1
挂v计数 = 0
锁定对象?nbsp; = 20971534
对象cd = ?/strong>
表空间名 = USERSPACE1
表模?nbsp; = DB2ADMIN
表名 = EMPLOYEE
方式 = S --注:(x)虽然d?jin)两行,但是整个表加S?/strong>
如果使用q种隔离U别Q不你从表中读多少数据Q?strong>整个表上都加S?/strong>Q直到该事务被提交或回滚Q表上的锁才?x)被释放。这样可以保证在一个事务中即多次d同一行,都会(x)得到相同l果集。另外,在同一事务中如果以同样的搜索标准重新打开已被处理q的游标Q那么得到的l果集不?x)改变。可重复ȝ对于ȝ定性而言Q加锁的范围更大Q对于读E_性,应用E序只对W合要求的所有行加锁Q而对于重复读Q应用程序将Ҏ(gu)个表都加S锁?/p>
可重复读?x)锁定应用程序在工作单元中引用的整个表。利用可重复读,一个应用程序在打开游标的相同工作单元内发出一个SELECT语句两次Q每ơ都q回相同的结果。利用可重复读隔ȝ别,不可能出C失更新、脏dqdȝ情况?/p>
在该工作单元完成之前Q?#8220;可重复读”应用E序可以多次(g)索和操作q些行。但是,在该工作单元完成之前其他应用E序均不能更新、删除或插入可能?x)?jing)响结果表的行?#8220;可重复读”应用E序不能查看其他应用E序未提交的更改?/p>
ȝ定性隔ȝ别没有可重复读隔ȝ别那么严|因此Q它没有事务与其他q发事务的效果完全隔R读E_性隔ȝ别可以防止脏d不可重复读,但是可能出现qd诅R在使用q个隔离U别Ӟ只锁定事务实际检索和修改的行。因此,如果一个表中有1000行,但只(g)索两?通过索引扫描)Q则只锁定被(g)索的两行(而不是所扫描?1000 ?。因此,如果在同一个事务中发出同一个SELECT语句两次或更多次Q那么每ơ生的l果数据集可能不同?/p>
与可重复读隔ȝ别一P在读E_性隔ȝ别下q行的事务可以检索一个行?ROWS SET)Qƈ可以对它们执行Q意操作,直到事务l止。在q个事务存在期间Q其他事务不能执行那些会(x)影响q个事务(g)索到的行集的更新或删除操作,但是可以执行插入操作。如果插入的行与W一个事务的查询的选择条g匚wQ那么这些行可能作ؓ(f)qd出现在后l生的l果数据集中。其他事务对其他行所作的更改Q在提交之前是不可见的。下面我们还用上面的那个例子锁定ȝ定性,输出l果如下Q?/p>
C:\>db2 +c select empno,firstnme,salary from employee where empno between '000010' and '000020' with rs
EMPNO FIRSTNME SALARY
------ ------------ -----------
000010 CHRISTINE 152750.00
000020 MICHAEL 94250.00
2 条记录已选择?/p>
我们通过“get snapshot for locks on sample”命o(h)来监控表加锁情况Q输出结果如下:(x)
C:\>db2 update monitor switches using lock on
DB20000I UPDATE MONITOR SWITCHES命o(h)成功完成?/p>
C:\>db2 get snapshot for locks on sample | more
--------------?-----------------
锁定列表
锁定名称 = 0x02000600050040010000000052
锁定属?nbsp; = 0x00000010
发行版标?nbsp; = 0x00000001
锁定计数 = 1
挂v计数 = 0
锁定对象?nbsp; = 20971525
对象cd = ?/strong>
表名 = EMPLOYEE
方式 = S --注:(x)只在d的行上加S?/strong>
锁定名称 = 0x02000600040040010000000052
锁定属?nbsp; = 0x00000010
发行版标?nbsp; = 0x00000001
锁定计数 = 1
挂v计数 = 0
锁定对象?nbsp; = 20971524
对象cd = ?/p>
表名 = EMPLOYEE
方式 = S --注:(x)只在d的行上加S?/p>
锁定名称 = 0x02000600000000000000000053
锁定属?nbsp; = 0x00000010
发行版标?nbsp; = 0x00000001
锁定计数 = 1
挂v计数 = 0
锁定对象?nbsp; = 6
对象cd = ?/strong>
表名 = EMPLOYEE
方式 = IS --注:(x)表上加I(yng)S?/strong>
如果使用q种隔离U,那么在一个事务中有N+1个锁Q?strong>其中N是所有被d(通过索引扫描)q的行的数目Q这些行上都?x)被加上NS锁,在表上加?个IS锁?/strong>q些锁直到该事务被提交或回滚才会(x)被释放。这样可以保证在一个事务中即多次d同一行,得到的g不会(x)改变。但是用这U隔ȝ别,在一个事务中Q如果用同L(fng)搜烦(ch)标准重新打开已被处理q的游标Q则l果集可能改?可能?x)增加某些行Q这些行被称为p(Phantom))。这是因为RS隔离U别不能L通过插入或更新操作在l果集中加入新行?/p>
注意Q?/p>
NS是下一键共享锁Q此旉拥有者和所有ƈ发的事务都可以读(但不能更?被锁定行中的数据。这U锁用来在用读E_性或游标E_性事务隔ȝ别读取的数据上代替共享锁?/p>
ȝ定?RS)只锁定应用程序在工作单元中检索的那些行。它保在某个工作单元完成之前,在该工作单元q行期间的Q何限定行d不被其他应用E序q程更改Q且保不会(x)d由另一个应用程序进E所更改的Q何行Q直臌q程提交?jin)这些更攏V也是_(d)不可能出?#8220;不可重复?#8221;情Ş?/p>
“ȝ定?#8221;隔离U别的其中一个目标是提供较高q行性以?qing)数据的E_视图Qؓ(f)?jin)有助于辑ֈ此目标,优化器确保在发生锁定升前不获取表锁定?/p>
“ȝ定?#8221;隔离U别最适用于包括下列所有特征的应用E序Q?
?nbsp; 在ƈ发环境下q行?/p>
?nbsp; 需要限定某些行在工作单元运行期间保持稳定?/p>
?nbsp; 在工作单元中不会(x)多次发出相同的查询,或者在同一工作单元中发出多ơ查询时q不要求该查询获得相同的回答?
游标E_性隔ȝ别在隔离事务效果斚w非常宽松。它可以防止脏读Q但有可能出C可重复读和像读。这是因为在大多数情况下Q游标稳定性隔ȝ别只锁定事务声明q打开的游标当前引用的行?
当用游标稳定性隔ȝ别的事务通过游标从表中检索行Ӟ其他事务不能更新或删除游标所引用的行。但是,如果被锁定的行本w不是用索引讉K的,那么其他事务可以新的行d到表中,以及(qing)对被游标锁定行前后的行进行更新或删除操作。所获取的锁一直有效,直到游标重定位或事务l止为止(如果游标重定位,原来行上的锁p释放Qƈ获得游标现在引用的行上的?。此外,如果事务修改?jin)它(g)索到的Q何行Q那么在事务l止之前Q其他事务不能更新或删除该行Q即使在游标不再位于被修改的行时。与可重复读和读E_性隔ȝ别一P其他事务在其他行上进行的更改Q在q些更改提交之前对于使用游标E_性隔ȝ别的事务(q是默认的隔ȝ?是不可见的。我们还用上面那个例子,一个表中有1000行数据,我们只检索其中两行数据。那么对于可重复读隔ȝ别会(x)锁住整个表,对于ȝ定性隔ȝ别会(x)对读到的数据(两行)加锁Q而对于游标稳定性隔ȝ别只Ҏ(gu)标当前所在那一行加锁,游标所在行的前一行和下一行都不加锁。下面我们D一个游标稳定性的例子Q输出结果如下:(x)
C:\>db2 +c declare c1 cursor for select empno,firstnme,salary from employee where empno between '000010' and '000020' with cs
C:\>db2 +c open c1
C:\>db2 +c fetch c1
EMPNO FIRSTNME SALARY
------ ------------ -----------
000010 CHRISTINE 152750.00 --注:(x)游标当前所在行QDB2只对q一行加锁。游标的
上一行和下一行都不加锁。当游标UdC一行时Q锁自动释放?/p>
1 条记录已选择?/p>
我们通过“get snapshot for locks on sample”命o(h)来监控表加锁情况Q输出结果如下:(x)
C:\>db2 update monitor switches using lock on
DB20000I UPDATE MONITOR SWITCHES命o(h)成功完成?/p>
C:\>db2 get snapshot for locks on sample | more
--------------?-----------------
锁定名称 = 0x02000600040040010000000052
锁定属?nbsp; = 0x00000010
发行版标?nbsp; = 0x00000001
锁定计数 = 1
挂v计数 = 0
锁定对象?nbsp; = 20971524
对象cd = ?/p>
表名 = EMPLOYEE
方式 = S --注:(x)只在游标所在行上加S?/p>
锁定名称 = 0x02000600000000000000000053
锁定属?nbsp; = 0x00000010
发行版标?nbsp; = 0x00000001
锁定计数 = 1
挂v计数 = 0
锁定对象?nbsp; = 6
对象cd = ?/p>
表名 = EMPLOYEE
方式 = IS --注:(x)表上加I(yng)S?/p>
如果使用q种隔离U,那么在一个事务中只有两个锁:(x)l果集中只有正在被读取的那一?游标指向的行)被加上NS锁,在表上加I(yng)S锁。其他未被处理的行上不加锁。这U隔ȝ别只能保证正在处理的行的g?x)被其他q发的程序所改变。该隔离U别是DB2默认的隔ȝ别?/p>
游标E_?CS)当在行上定位游标时会(x)锁定M由应用程序的事务所讉K的行。此锁定在读取下一行或l止事务之前有效。但是,如果更改?jin)某一行上的Q何数据,那么在对数据库提交更改之前必L赯锁定?/p>
对于h“游标E_?#8221;的应用程序已(g)索的行,当该行上有Q何可更新的游标时QQ何其他应用程序都不能更新或删除该行?#8220;游标E_?#8221;应用E序不能查看其他应用E序的未提交操作?/p>
使用“游标E_?#8221;Q可能会(x)出现不可重复dqdȝ象?#8220;游标E_?#8221;是默认隔ȝ别,应在需要最大ƈ行性,但只看到其他应用E序中的已提交行的情况下才用?/p>
未提交读隔离U别是最不严格的隔离U别。实际上Q在使用q个隔离U别Ӟ仅当另一个事务试囑ֈ除或更改被检索的行所在的表时Q才?x)锁定一个事务检索的行。因为在使用q种隔离U别Ӟ行通常保持未锁定状态,所以脏诅R不可重复读和像读都可能会(x)发生。因此,未提交读隔离U别通常用于那些讉K只读表和视图的事务,以及(qing)某些执行SELECT语句的事?只要其他事务的未提交数据对这些语句没有负面效??
思义Q其他事务对行所做的更改在提交之前对于用未提交读隔ȝ别的事务是可见的。但是,此类事务不能看见或访问其他事务DDL(CREATE、ALTER和DROP)语句所创徏的表、视图或索引Q直到那些事务被提交为止。类似地Q如果其他事务删除了(jin)现有的表、视图或索引Q那么仅当进行删除操作的事务l止Ӟ使用未提交读隔离U别的事务才能知道这些对象不再存在了(jin)?/p>
一定要注意一点:(x)当运行在未提交读隔离U别下的事务使用可更新游标时Q该事务的行为和在游标稳定性隔ȝ别下q行一Pq应用游标稳定性隔ȝ别的U束。下面我们D一个例子?/p>
我们~写一个SQL存储q程Q在存储q程中我们显式地在SELECT语句中用UR隔离U别?/p>
创徏一个存储过E,保存?sh)LOCKS.SQLQ输出结果如下:(x)
CREATE PROCEDURE locks()
LANGUAGE SQL
BEGIN
declare c1 cursor for select * from staff with UR;
open c1;
while 1=1 do ——注Q死循环
end while;
END @
Z(jin)方便抓住锁信息,我们在这个存储过E的l尾处用了(jin)一个死循环。利用一个命令窗口运行存储过E,输出l果如下Q?
C:\ >db2 –td@ -vf locks.sql
C:\ >db2 "call locks()"
再打开一个新的窗口,得到在STAFF表上的当前锁信息Q输出结果如下:(x)
C:\>db2pd -db sample -locks show detail
Locks:
Address TranHdl Lockname Type Mode Sts Owner Dur HldCnt Att ReleaseFlg
0x408E0290 2 00020003000000000000000054 Table .IS G 2 1 0 0x0000 0x00000001
TbspaceID 2 TableID 3
但是?x)发现此时在STAFF表上出现的是IS锁,而不是IN锁。是什么原因呢Q?strong>q是因ؓ(f)UR隔离U别允许应用E序存取其他事务的未落实的更改,但是对于只读和可更新q两U不同的游标cdQUR的工作方式有所不同。对于可更新的游标,当它使用隔离U别 UR q行E序Ӟ应用E序?x)自动用隔ȝ?CS?
在上面的例子当中Q虽然显式地指定?jin)SQL语句的隔ȝ别是URQ但是,׃在存储过E中使用的游标是模糊游标(也就是没有显式地声明游标是只ȝq是可更新的)Q因而系l会(x)默认地将q个模糊游标当成可更新游标处理,存储q程的隔ȝ别自动从UR升为CS。要防止此升U,可以采用以下办法Q?/p>
?nbsp; 修改应用E序中的游标Q以使这些游标是非模p游标。将SELECT语句更改为包括F(xin)OR READ ONLY子句?
?nbsp; 模p游标保留在应用E序中,但是预编译程序或使用BLOCKING ALL和STATIC READONLY YES选项l定它以允许在运行该E序时将M模糊游标视ؓ(f)只读游标?
我们q是使用上面的例子,昑ּ地将该游标声明成只读游标Q输出结果如下:(x)
declare c1 cursor for select * from staff for read only with UR;
此时我们再运行这个存储过E,q利用DB2PD获取锁的情况Q输出结果如下:(x)
c:\> db2pd -db sample -locks show locks
Locks:
Address TranHdl Lockname Type Mode Sts Owner Dur HldCnt Att ReleaseFlg
0x408E07E0 2 00020003000000000000000054 Table .IN G 2 1 0 0x0000 0x00000001
TbspaceID 2 TableID 3
-注:(x)可以看到STAFF表上出现的锁是IN锁?/p>
从上面的例子中我们可以看刎ͼ(x)“未提交读(UR)”隔离U别允许应用E序讉K其他事务的未提交的更攏V除非其他应用程序尝试删除或改变该表Q否则该应用E序也不?x)锁定正d的行而其他应用E序不能讉K该行。对于只d可更新的游标Q?#8220;未提交的?#8221;的工作方式有所不同?/p>
如果使用q种隔离U别Q那么对于只L作不加行锁。典型的只读操作包括Q?nbsp; SELECT语句的结果集只读(比如语句中包括ORDER BY子句)Q定义游标时指明起ؓ(f)FOR FETCH ONLY或FOR READ ONLY?/p>
该隔ȝ别可以改善应用程序的性能Q同时可以达到最大程度的q发性。但是,应用E序的数据完整性将受到威胁。如果需要读取未提交的数据,该隔ȝ是唯一选择?/p>
使用“未提交的?#8221;Q可能出C可重复读行ؓ(f)和像读现象?#8220;未提交读”隔离U别最常用于只读表上的查询Q或者在仅执行选择语句且不兛_(j)是否可从其他应用E序中看到未提交的数据时也最常用?/p>
以上我们所讲的隔离U别的加锁范围和持箋(hu)旉都是针对L作而言的。对于更Ҏ(gu)作,被修改的行上?x)被加上X锁,无论使用何种隔离U别QX锁都直到提交或回滚之后才?x)被释放?/p>
假设有一张表EMP1Q表中有42条记录,我们使用FOR READ ONLY分别在UR、CS、RS和RR隔离U别下加锁?/p>
EMP1表在本章后箋(hu)的内容中也会(x)使用刎ͼ其创E如下:(x)
C:\> db2 "create table emp1 like employee"
C:\> db2 "insert into emp1 select * from employee"
我们使用EMP1表中JOB字段内容?CLERK'的数据,输出l果如下Q?/p>
C:\>db2 +c select empno,job,salary from emp1 where job='CLERK' for read only
EMPNO JOB SALARY
------ -------- -----------
000120 CLERK 49250.00
000230 CLERK 42180.00
000240 CLERK 48760.00
000250 CLERK 49180.00
000260 CLERK 47250.00
000270 CLERK 37380.00
200120 CLERK 39250.00
200240 CLERK 37760.00
8 条记录已选择?/p>
在上面的SQL语句中,我们从表?2条记录中q回8条记录。下面我们分别看看这条语句在不同的隔ȝ别下加锁的情况:(x)
?nbsp; UR隔离U别Q输出结果如下:(x)
C:\>db2 +c select empno,job,salary from emp1 where job='CLERK' for read only with ur
EMPNO JOB SALARY
------ -------- -----------
000120 CLERK 49250.00
000230 CLERK 42180.00
000240 CLERK 48760.00
000250 CLERK 49180.00
000260 CLERK 47250.00
000270 CLERK 37380.00
200120 CLERK 39250.00
200240 CLERK 37760.00
8 条记录已选择?/p>
在另外一个窗口中使用“db2 get snapshot for locks on sample”命o(h)监控Q发现在UR隔离U别下,在表上有一个IN锁,没有加Q何行锁?/p>
?nbsp; CS隔离U别Q输出结果如下:(x)
C:\>db2 +c declare c1 cursor for select empno,job,salary from emp1 where job='CLERK' for read only with CS
C: \>db2 +c open c1
C: \>db2 +c fetch c1
EMPNO JOB SALARY
------ -------- -----------
000120 CLERK 49250.00
1 条记录已选择?/p>
在另外一个窗口中使用“db2 get snapshot for locks on sample”命o(h)监控Q发现在CS隔离U别下,共有两个锁:(x)在表上有一个IS锁,在行上有一个NS锁?/p>
?nbsp; RS隔离U别Q输出结果如下:(x)
C:\>db2 +c select empno,job,salary from emp1 where job='CLERK' for read only with RS
EMPNO JOB SALARY
------ -------- -----------
000120 CLERK 49250.00
000230 CLERK 42180.00
000240 CLERK 48760.00
000250 CLERK 49180.00
000260 CLERK 47250.00
000270 CLERK 37380.00
200120 CLERK 39250.00
200240 CLERK 37760.00
8 条记录已选择?/p>
在另外一个窗口中使用“db2 get snapshot for locks on sample”命o(h)监控Q发现在RS隔离U别下,共有9个锁Q在表上有一个IS锁,在读取的8行上分别?个NS锁?/p>
?nbsp; RR隔离U别Q输出结果如下:(x)
C:\>db2 +c select empno,job,salary from emp1 where job='CLERK' for read only with RR
EMPNO JOB SALARY
------ -------- -----------
000120 CLERK 49250.00
000230 CLERK 42180.00
000240 CLERK 48760.00
000250 CLERK 49180.00
000260 CLERK 47250.00
000270 CLERK 37380.00
200120 CLERK 39250.00
200240 CLERK 37760.00
8 条记录已选择?/p>
在另外一个窗口中使用“db2 get snapshot for locks on sample”命o(h)监控Q发现在RR隔离U别下,分ؓ(f)两种情况Q?/p>
如果该SQL语句使用全表扫描Q那么即使只d?行,也会(x)在整个表上加一个S锁,输出l果如下Q?/p>
C:\>dynexpln -d sample -q "select empno,job,salary from emp1 where job='CLERK'
for read only with rr" –t
Access Table Name = DB2ADMIN.EMP1 ID = 3,12
| #Columns = 2
| Relation Scan --注:(x)全表扫描
| | Prefetch: Eligible
| Isolation Level: Repeatable Read --注:(x)RR隔离U别
| Lock Intents
| | Table: Share --注:(x)整个表上加S?/p>
| | Row : None
| Sargable Predicate(s)
| | #Predicates = 1
| | Return Data to Application
| | | #Columns = 3
Return Data Completion
End of section
如果创徏索引Qƈq行索引扫描Q那么表上加I(yng)S锁,d的每行上加S锁。所以对于RR隔离U别来说Qؓ(f)?jin)保证ƈ发,可能创建合理的索引以减加锁的范围Q输出结果如下:(x)
C:\>db2 create index job on DB2ADMIN.emp1(job)
DB20000I SQL命o(h)成功完成?/p>
C:\>db2 runstats on table DB2ADMIN.emp1 and indexes all
DB20000I RUNSTATS命o(h)成功完成?/p>
C:\>dynexpln -d sample -q "select empno,job,salary from emp1 where job='CLERK'
for read only with rr" -t
Access Table Name = DB2ADMIN.EMP1 ID = 3,12
| Index Scan: Name = DB2ADMIN.JOB ID = 1 --注:(x)索引扫描
| | Regular Index (Not Clustered)
| | Index Columns:
| | | 1: JOB (Ascending)
| #Columns = 2
| #Key Columns = 1
| | Start Key: Inclusive Value
| | | | 1: 'CLERK '
| | Stop Key: Inclusive Value
| | | | 1: 'CLERK '
| Data Prefetch: Eligible 0
| Index Prefetch: None
| Isolation Level: Repeatable Read --注:(x)RR隔离U别
| Lock Intents
| | Table: Intent Share --注:(x)表上加I(yng)S?/p>
| | Row : Share --注:(x)行上加S?/p>
| Sargable Predicate(s)
| | Return Data to Application
| | | #Columns = 3
Return Data Completion
End of section
?-1按不期望的结果概qC(jin)几个不同的隔ȝ别?/p>
?-1 隔离U别摘要 |
|||
隔离U别 |
讉K未提交的数据 |
不可重复?/p> |
qdȝ?/p> |
可重复读(RR) |
不可?/p> |
不可?/p> |
不可?/p> |
ȝ定?RS) |
不可?/p> |
不可?/p> |
可能 |
游标E_?CS) |
不可?/p> |
可能 |
可能 |
未提交读(UR) |
可能 |
可能 |
可能 |
?-2提供?jin)简单的试探Ҏ(gu)Q以帮助(zhn)ؓ(f)应用E序选择初始隔离U别。首先考虑表中列示的方法,q参阅先前对影响各隔ȝ别因素的讨论Q可能会(x)扑ֈ另一个更适合的隔ȝ别?
?-2 选择隔离U别的准?/p> |
||
应用E序cd |
需要高数据E_?/p> |
?/strong>需要高数据E_? |
d事务 |
RS |
CS |
只读事务 |
RR ?RS |
UR |
为避免应用程序出现用h法容忍的现象Q必Mؓ(f)光择适当的隔ȝ别。在不同隔离U别下,应用E序锁定或释放资源需要不同的CPU和内存资源,所以隔ȝ别不但媄(jing)响应用程序之间的隔离E度Q还可能影响应用E序的个别性能特征。潜在的锁等待情况也?x)随隔离U别的不同而不同?/p>
因ؓ(f)隔离U别定讉K数据时如何锁定数据ƈ使数据不受其他进E媄(jing)响,所以?zhn)在选择隔离U别时应该^衡ƈ行性和数据完整性需求。?zhn)指定的隔ȝ别在工作单元q行期间生效?
选择正确的隔ȝ?/p>
使用的隔ȝ别不仅媄(jing)响数据库的ƈ发性,而且影响q发应用E序的性能。通常Q用的隔离U别严|q发性就小Q某些应用程序的性能可能?x)随之越低,因?f)它们要等待资源上的锁被释放。那么,如何军_要用哪U隔ȝ别呢Q最好的Ҏ(gu)是先定哪些现象是不可接受的Q然后选择能够防止q些现象发生的隔ȝ别。以下列举了(jin)各种隔离U别的适用情况Q?/p>
?nbsp; 如果正在执行大型查询Q而且不希望ƈ发事务所做的修改D查询的多ơ运行返回不同的l果Q则使用可重复读隔离U别?
?nbsp; 如果希望在应用程序之间获得一定的q发性,q希望限定的行在事务执行期间保持E_Q则使用ȝ定性隔ȝ别?
?nbsp; 如果希望获得最大的q发性,同时不希望查询看到未提交的数据,则用游标稳定性隔ȝ别?
?nbsp; 如果正在只读的表/视图/数据库上执行查询Q或者ƈ不介意查询是否返回未提交的数据,则用未提交读隔ȝ别?
讄隔离U别
管隔离U别控制事务U上的行为,但实际上它们是在应用E序U被指定的:(x)
?nbsp; 对于嵌入式SQL应用E序Q在预编译时或在应用程序绑定到数据?如果使用延迟l定)时指定隔ȝ别。在q种情况下,使用PRECOMPILE或BIND命o(h)的ISOLATION选项来设|隔ȝ别?
?nbsp; 对于开放数据库q接(ODBC)和调用接口(Call Level InterfaceQCLI)应用E序Q隔ȝ别是在应用程序运行时通过调用指定?jin)SQL_ATTR_TXN_ISOLATIONq接属性的SQLSetConnectAttr()函数q行讄的。另外,也可以通过指定DB2CLI.INI配置文g中的TXNISOLATION关键字的值来讄ODBC/CLI应用E序的隔ȝ别;但是Q这U方法不够灵z,不能像第一U方法那样ؓ(f)一个应用程序中的不同事务修攚wȝ别?/p>
?nbsp; 对于Java数据库连?JDBC)和SQLJ应用E序Q隔ȝ别是在应用程序运行时通过调用DB2的JAVA.SQLq接接口中的“setTransactionIsolation()”Ҏ(gu)讄的?
当没有用这些方法显式指定应用程序的隔离U别Ӟ默认使用游标E_?CS)隔离U别。这个默认设|被应用于从命o(h)行处理程?CLP)执行的DB2 命o(h)、SQL语句和脚本,以及(qing)嵌入式SQL、ODBC/CLI、JDBC和SQLJ应用E序。因此,也可以ؓ(f)从CLP执行的操?以及(qing)传递给DB2 CLPq行处理的脚?指定隔离U别。在q种情况下,隔离U别是通过在徏立数据库q接之前在CLP中执行CHANGE ISOLATION命o(h)讄的,输出l果如下Q?/p>
C:\pp>db2 change isolation to ur
DB21027E 当连接至数据库时未能更改隔离U别?/p>
C:\pp>db2 connect reset
DB20000I SQL命o(h)成功完成?/p>
C:\pp>db2 change isolation to ur
DB21053W 当连接至不支?UR 的数据库Ӟ?x)发生自动升U?/p>
DB20000I CHANGE ISOLATION命o(h)成功完成?/p>
在DB2 V7.1?qing)更高版本中Q能够指定特定查询所用的隔离U别Q方法是在SELECT SQL语句中加上WITH [RR | RS | CS | UR]子句。大家可以看刎ͼ本章前面的示例均使用q种Ҏ(gu)举例?/p>
e.g.事务A和事务B同时修改某行的|
1.事务A数值改?q提?/p>
2.事务B数值改?q提交?/p>
q时数据的gؓ(f)2Q事务A所做的更新会(x)丢失?/p>
解决办法Q对行加锁,只允许ƈ发一个更C务?/p>
?未确认的相关性(脏读Q?br> 当第二个事务选择其它事务正在更新的行Ӟ?x)发生未认的相x(chng)问题。第二个事务正在d的数据还没有认q且可能由更新此行的事务所更改?/p>
e.g.
1.Mary的原工资?000, 财务人员Mary的工资改Z(jin)8000(但未提交事务) 2.Maryd自己的工?,发现自己的工资变?sh)Z(jin)8000Q欢天喜圎ͼ
3.而胦(ch)务发现操作有误,回滚?jin)事?Mary的工资又变(sh)ؓ(f)?000
像这?Mary记取的工资数8000是一个脏数据?/p>
解决办法Q如果在W一个事务提交前QQ何其他事务不可读取其修改q的|则可 以避免该问题?/p>
?不一致的分析Q非重复读)(j)
当第二个事务多次讉K同一行而且每次d不同的数据时Q会(x)发生不一致的分析问题。不一致的分析与未认的相x(chng)类|因ؓ(f)其它事务也是正在更改W二个事务正在读取的数据。然而,在不一致的分析中,W二个事务读取的数据是由已进行了(jin)更改的事务提交的。而且Q不一致的分析涉及(qing)多次Q两ơ或更多Q读取同一行,而且每次信息都由其它事务更改Q因而该行被非重复读取?/p>
在一个事务中前后两次d的结果ƈ不致Q导致了(jin)不可重复诅R?/p>
e.g.
1.在事?中,Mary d?jin)自q工资?000,操作q没有完?
2.在事?中,q时财务人员?sh)改了(jin)Mary的工资ؓ(f)2000,q提交了(jin)事务.
3.在事?中,Mary 再次d自己的工资时Q工资变?sh)Z(jin)2000
解决办法Q如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题?/p>
?qd?
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围Ӟ?x)发生像读问题。事务第一ơ读的行范围昄出其中一行已不复存在于第二次L后箋(hu)MQ因行已被其它事务删除。同P׃其它事务的插入操作,事务的第二次或后l读昄有一行已不存在于原始M?
e.g. 目前工资?000的员工有10人?
1.事务1,d所有工资ؓ(f)1000的员工?
2.q时事务2向employee表插入了(jin)一条员工记录,工资也ؓ(f)1000
3.事务1再次d所有工资ؓ(f)1000的员?p取到?1条记录,
解决办法Q如果在操作事务完成数据处理之前QQ何其他事务都不可以添加新数据Q则可避免该问题
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/d8111/archive/2008/06/29/2595635.aspx
注意要加括号Q在更改多个列的时?/p>
ALTER proc usp_clearActiveScoreCalcCommentScore
as
begin
update tbForum set UltimoScore=
(case
when AllScore-RemainScore<0 then 0
else AllScore-RemainScore
end),AllScore=
(case
when ActivityDegree>=0 and ActivityDegree<=300 then 250
when ActivityDegree>=301 and ActivityDegree<=800 then 500
when ActivityDegree>=801 and ActivityDegree<=2000 then 1000
when ActivityDegree>=2001 and ActivityDegree<=4000 then 2000
when ActivityDegree>=4001 and ActivityDegree<=8000 then 4500
when ActivityDegree>8000 then 9000
end),UltimoDegree=ActivityDegree,ActivityDegree = 0
update tbForum set RemainScore=AllScore
end
嵌入式SQL解决下列几个问题:(x)
(1)如何嵌有SQL的宿主语aE序~译成可执行码(q是首要问题Q?br> (2)宿主语言和DBMS之间如何传递数据和信息?br> (3)如何查询结果赋值给宿主语言E序中的变量Q通过游标语句Q?br> (4)宿主语言与SQL之间数据cd的{换问题(按系l约定{换)(j)?/p>
以SQL嵌入CZQ说明实现的一般方法?/p>
如何在C中嵌入SQLQ?strong>通常是以“EXEC SQL”开始,?#8220;Q?#8221;l尾?/strong>
SQL与C之间数据的传送通过宿主变量。(即SQL中可引用的C语言变量Q?br> 在SQL语句中引用宿d量时Qؓ(f)?jin)区别数据库中变量,宿主变量前须?#8220;Q?#8221;Q它可与数据库中变量同名。在宿主语言语句中,宿主变量可与其它变量一样用,不须加冒受当宿主变量的数据类型与数据库中不一致时Q由pȝ按约定{换?/p>
在宿d量中Q有一个系l定义的Ҏ(gu)变量Q叫SQLCAQSQL通信区)(j)?strong>它是全局变量。供应用E序与DBMS之间通信用?/strong>
EXEC SQL INCLUDE SQLCA
SQLCA中有一个分量叫SQLCODEQ可表示为:(x)SQLCA.SQLCODE. 它是一个整敎ͼ供DBMS向应用程序报告SQL语句执行情况用?/p>
SQLCODE > 0 QSQL已执行,但有异常Q?br> SQLCODE < 0 QSQL没执行,有错误;
SQLCODE = 0 Q执行成功, 无异常?
注:(x)SQLCODE的g具体含义Q不同系l有所区别?nbsp;
允许在嵌入的SQL语句中引用宿主语a的程序变量,但有两条规定Q?br>Q?Q引用时Q这些变量前必须?#8220;Q?#8221;作ؓ(f)前缀Q?br>以示与数据库中变量区别?br>Q?Q这?#8220;׃n变量”有宿主语a的持l定义,q用SQL的DECLARE语句说明?/p>
例如Q在C语言中说明共享变量:(x)
EXEC SQL BEGIN DECLARE SECTION;/说明语句开?br> CHAR SNO [7];
CHAR GIVENSNO[7];
CHAR CNO[6];
CHAR GIVENCNO[6];
FLOAT GRADE;
SHORT GRADEI;/*GRADEI是GRADE的指C变量,两者必连?
EXEC SQL END DECLARE SECTION;/*说明语句l束
SQL的集合处理方式与宿主语言单记录处理方式的协调
׃SQL语句可以处理一l记录,而宿主语a语句一ơ只能处理一个记录,因此需要游标机Ӟ把集合操作{换成单记录方式?/p>
嵌入式SQL的可执行语句内容包括Q嵌入式DDL、QL、DML、及(qing)DCL语句Q进入数据库的CONNECT语句以及(qing)控制事务l束的语句?br> 对于SQL DDL语句Q?strong>只要加上前缀标识“EXEC SQL”和结束标?#8220;Q?#8221;Q对C语言Q,p嵌入在宿主语aE序中用。而SQL DML语句在嵌入用时Q要注意是否使用?jin)游标机制?br> 可执行语句格式:(x)
EXEC SQL CONNECT :uid IDENTIFIED BY :pwdQ?br> q里uid、pwdZ个宿d量;uid为用h识符Qpwd为用L(fng)口o(h)。执行CONNECT前由宿主语言E序赋倹{只有当CONNECT语句执行成功后才能执行事务处理中的其它可执行语句?/p>
例:(x)
EXEC SQL INSERT INTO SC (SNO, CNO, GRADE )
VALUES (:SNO, :CNO, :GRADE);
功能Q将一个元l插入到表SC中?br> 插入的元l由三个宿主变量构成Q由宿主语言E序赋倹{?nbsp;
例:(x)
EXEC SQL SELECT GRADE
INTO :GRADE,:GRADEI
FROM SC
WHERE SNO=:GIVENSNO AND CNO=:GIVENCNO;
功能Q查询学生成l?br> 如查询结果只有一个元l,可将l果直接用INTO子句Ҏ(gu)关的宿主变量直接赋倹{?br> 如查询结果超q一个元l,需在程序中开辟一个区域,存放查询的结果。该区域?qing)其相应的数据结构称为游标。然后逐个地取出每个元l给宿主变量赋倹{?nbsp;
嵌入式SQL的实玎ͼ有两U处理方式:(x)
(1)扩充宿主语言的编译程序,使之能处理SQL语句Q?br> (2)采用预处理方式?br>
目前多数pȝ采用后一U方式。预处理方式是先用预处理E序Ҏ(gu)E序q行扫描Q识别出SQL语句Qƈ处理成宿主语a的过E调用语句;然后再用宿主语言的编译程序把源程序编译成目标E序?/p>
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/prayforever/archive/2008/08/06/2778495.aspx
@@12W03501.GIF;? ODBC体系l构@@
下面我们详细介绍各层的功能?br>1. 应用E序?Application)
使用ODBC接口的应用程序可执行以下dQ?br>①请求与数据源的q接和会(x)?SQLConnect)Q?br>②向数据源发送SQLh(SQLExecDirct或SQLExecute)Q?br>③对SQLh的结果定义存储区和数据格式;
④请求结果;
⑤处理错误;
⑥如果需要,把结果返回给用户Q?br>⑦对事务q行控制Q请求执行或回退操作(SQLTransact)Q?br>⑧终止对数据源的q接(SQLDisconnect)?br>2. 驱动E序理?Driver Manager)
由微软提供的驱动E序理器是带有输入库的动态连接库ODBC.DLLQ其主要目的是装入驱动程序,此外q执行以下工?
①处理几个ODBC初始化调用;
②ؓ(f)每一个驱动程序提供ODBC函数入口点;
③ؓ(f)ODBC调用提供参数和次序验证?br>3. 驱动E序(Driver)
驱动E序是实现ODBC函数和数据源交互的DLLQ当应用E序调用SQL Connect或者SQLDriver Connect函数Ӟ驱动E序理器装入相应的驱动E序Q它Ҏ(gu)自应用程序的ODBC函数调用q行应答Q按照其要求执行以下d:
①徏立与数据源的q接Q?br>②向数据源提交请求;
③在应用E序需求时Q{换数据格式;
④返回结果给应用E序Q?br>⑤将q行错误格式化ؓ(f)标准代码q回Q?br>⑥在需要时说明和处理光标?br>以上q些功能都是对应用程序层功能的具体实现。驱动程序的配置方式可以划分Z下两U?br>(1)单层?single-tier) q种方式下,驱动E序要处理ODBC调用SQL语句Qƈ直接操纵数据库,因此h数据存取功能。这U配|最常见的是同一台微Z上异U数据库通过ODBC存取Q如在Powerbuilder中存取XBase、Excel、Paradox{数据文?如图3所C。@@12W03502.GIF;? 一层配|示意图@@
(2)多层?multiple-tier) q种配置中驱动程序仅仅处理ODBC调用Q而将SQL语句交给服务器执行,然后q回l果。这U情况往往是应用程序、驱动程序管理器、驱动程序驻留在客户机端Q而数据源和数据存取功能放在服务器端。譬如用Foxpro或Excel存取SQL Server或Oracle上的数据,如图4所C?br>@@12W03503.GIF;? 二层配置C意图@@
有时在以上两者之间加上网关以解决[本文q?a >www.gwdq.com公文大全www.gwdq.cn攉整理]通信协议的{换等问题Q这旉动程序要请求先传送给|关Q如讉KDEC RDB和IBM AS/400时的配置,如图5所C?br>@@12W03504.GIF;? 三层配置C意图@@
4. 数据?br>数据源由用户惌存取的数据和它相关的操作pȝ、DBMS?qing)网l环境组成?br>四、一致性?br>从应用程序观Ҏ(gu)看,最理想的情冉|每个数据源和驱动E序都支持同一套ODBC函数调用和SQL语句。但是由于Ş形色色的DBMS在实C有很大的差异Q它们所依赖的系l和环境也各不相同,在对ODBC支持的程度上׃一致。一致性?Conformance Levels)建立?jin)对众多功能的标准划分,为应用程序和驱动E序提供帮助和选择的依据。它划定?jin)驱动程序所支持的ODBC函数和SQL语句的范_(d)我们可以用SQLGetInfo、SQLGetFunctions、SQLTypeInfo三个函数L(fng)驱动E序所支持的功能集。ODBC从API和SQL语法两方面划分别?br>1. API的一致?br>ODBC函数调用划分ؓ(f)三?br>(1)核心(j)API 它包括了(jin)与SAG的CLI相匹配的基本功能Q包括:(x)分配与释攄境、连接及(qing)语句句柄Q连接到数据源;准备q执行SQL语句或立x(chng)行SQL语句Qؓ(f)SQL语句和结果列中的参数分配存储器;从结果中(g)索数据,(g)索结果的信息Q提交和撤消事务处理Q检索错误信息?br>(2)一UAPI 它包括了(jin)核心(j)API的全部功能,比如用特定驱动程序的对话框连接到数据源;讄和查询语句值和q接选项Q送部分或全部参数|(g)索部分和全部l果Q检索目录信息;(g)索关于驱动程序和数据源的信息?br>(3)二API 其功能包括核?j)和一UAPI的全部功能;览可获得的q接和可获得的数据源列表Q发送参数值数l,(g)索结果数l;(g)索参C数及(qing)参数描述Q应用可卷动的光标;(g)索SQL语句和本|(g)索各U目录信息;调用转换DLL?br>2. SQL语法的一致性?br>从SQL斚w可划分ؓ(f)最的SQL语法、核?j)SQL语法和扩展SQL语法三个{?br>五、ODBC的应用与前景
ODBC的出现给用户描绘?sh)(jin)一个诱人的前景Q即|络中的Windows用户可以方便地访问各U数据库。现在,在微软推出的许多产品中都提供?jin)ODBC支持Q如Visal Basic 3.0、Visal C1.5、Excel 5.0、Word 6.0、FoxPro、Access{。同时其他一些应用Y件和开发工具也提供?jin)对ODBC的支持。因此用户只要安装不同的ODBC驱动E序Q就可存取相应的数据库品,而不用户用何U前台应用YӞ也不后台是何种数据库,q个存取?br>本文来自: 公文大全(www.gwdq.com) 详细出处参考:(x)http://www.gwdq.com/lwzx/jsj/jsjll/146960_2.html
q程是一致的?br>但是׃ODBC产生的时间还?sh)长Q其应用也同时存在着一些问题。首先,它的层次比较多,表现在性能上比专有的API要慢Q这是其标准化和开发性所带来的必要的代h(hun)Q其ơ,׃ODBC规定?jin)三个层ơ的一致性别,应用E序与驱动程序之间的匚w׃(x)出现一些问题和矛盾Q比如某些驱动程序支持的U别比较低,而应用程序要求的比较高;再者,׃不同的驱动程序ؓ(f)不同的开发商所开发,试工作不能l一Q而现有的开发和试工具q不很完善;同时Q在非SQL的数据库pȝ上的应用也存在一些问题?br>微Y公司ODBC作ؓ(f)一很重要的技术,它已承诺q一步改qODBC技术,为驱动程序开发者提供更先进的开发和试工具Q还交付系l管理和监控工具Q它q将与DBMS厂商和第三方厂商建立更密切的合作Q以期驱动E序支持更高U别的一致性,q在规范化方面有所完善。目前,ODBC已ؓ(f)数据库供应商l织内部所认可Q同时ؓ(f)众多应用软g厂商和第三方开发商所使用Q相信随着SQL的推q和规范Q用户和开发商?x)更加依赖于q一技?br>本文来自: 公文大全(www.gwdq.com) 详细出处参考:(x)http://www.gwdq.com/lwzx/jsj/jsjll/146960_3.html
问题 在一台机器上q行DB2 CLI或者ODBC应用E序Q必要安装DB2q行客户端,DB2是否提供?jin)单独的ODBC驱动E序Q?/p>
解答 DB2在版?.1以前Q没有提供单独的ODBC/CLI驱动E序Q如果要q行ODBC/CLIE序Q?zhn)必须安装DB2的运行客L(fng)Q在DB2版本8.1补丁9以后QDB2q提供了(jin)一个轻量的DB2q行客户端。但是没有提供单独的ODBC/CLI驱动E序?/p>
从版?.1开始,DB2提供?jin)一个单独的ODBC/CLI驱动E序Q现在,(zhn)只需安装ODBC/CLI驱动E序Q就可以方便地运行?zhn)的ODBC/CLI应用E序?jin)。通过使用单独的ODBC/CLI驱动E序Q?zhn)可以驱动程序包含在?zhn)的应用E序安装包中Q用该驱动E序Q应用程序的大小Q安装大和内存需求都有所减少?/p>
你可以单独安装ODBC/CLI驱动E序Q驱动程序可以安装在已经包含DB2客户端的机器上,也可以在一台机器上安装多个ODBC/CLI驱动E序?/p>
DB2 ODBC/CLI驱动E序需要通过ODBC驱动E序理器加载,目前它符合ODBC 3.51标准。DB2 ODBC/CLI驱动E序提供如下功能Q?/p>
* DB2 CLI API q行环境
* ODBC API q行环境
* XA API q行环境
* 数据库连接功?br>* 支持 LDAP 数据库目?br>* 支持跟踪、日志和诊断功能
本文来自: IXPUB技术社?www.ixpub.net) 详细出处参考:(x)http://www.ixpub.net/thread-855959-1-1.html
创徏序列需要CREATE SEQUENCEpȝ权限。序列的创徏语法如下Q?/p>
CREATE SEQUENCE 序列?/p>
[INCREMENT BY n]
[START WITH n]
[{MAXVALUE/ MINVALUE n|NOMAXVALUE}]
[{CYCLE|NOCYCLE}]
[{CACHE n|NOCACHE}];
INCREMENT BY 用于定义序列的步长,如果省略Q则默认?Q如果出现负|则代表序列的值是按照此步镉K减的?/p>
START WITH 定义序列的初始?即生的W一个?Q默认ؓ(f)1?/p>
MAXVALUE 定义序列生成器能产生的最大倹{选项NOMAXVALUE是默认选项Q代表没有最大值定义,q时对于递增序列Q系l能够生的最大值是10?7ơ方;对于递减序列Q最大值是-1?/p>
MINVALUE定义序列生成器能产生的最倹{选项NOMAXVALUE是默认选项Q代表没有最值定义,q时对于递减序列Q系l能够生的最值是?10?6ơ方;对于递增序列Q最值是1?/p>
CYCLE和NOCYCLE 表示当序列生成器的D到限制值后是否循环。CYCLE代表循环QNOCYCLE代表不@环。如果@环,则当递增序列辑ֈ最大值时Q@环到最?对于递减序列辑ֈ最值时Q@环到最大倹{如果不循环Q达到限制值后Ql生新值就?x)发生错误?/p>
CACHE(~冲)定义存放序列的内存块的大,默认?0。NOCACHE表示不对序列q行内存~冲。对序列q行内存~冲Q可以改善序列的性能?/p>
删除序列的语法是Q?/p>
DROP SEQUENCE 序列?
其中Q?/p>
删除序列的h应该是序列的创徏者或拥有DROP ANY SEQUENCEpȝ权限的用戗序列一旦删除就不能被引用了(jin)?/p>
序列的某些部分也可以在用中q行修改Q但不能修改SATRT WITH选项。对序列的修改只影响随后产生的序P已经产生的序号不变。修改序列的语法如下Q?/p>
创徏和删除序?/p>
?Q创建序列:(x)
CREATE SEQUENCE ABC INCREMENT BY 1 START WITH 10 MAXVALUE 9999999 NOCYCLE NOCACHE;
执行l果
序列已创建?/p>