??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲成人激情小说,在线观看亚洲一区二区,亚洲精品无码午夜福利中文字幕http://www.tkk7.com/xixidabao/category/15383.htmlGROW WITH JAVAzh-cnFri, 21 Dec 2007 19:48:22 GMTFri, 21 Dec 2007 19:48:22 GMT60SQL语句处理的过E?/title><link>http://www.tkk7.com/xixidabao/archive/2007/12/20/169007.html</link><dc:creator>JAVA之\</dc:creator><author>JAVA之\</author><pubDate>Thu, 20 Dec 2007 05:30:00 GMT</pubDate><guid>http://www.tkk7.com/xixidabao/archive/2007/12/20/169007.html</guid><description><![CDATA[在调整之前我们需要了解一些背景知识,只有知道q些背景知识Q我们才能更好的去调整sql语句?br /> 本节介绍了SQL语句处理的基本过E,主要包括Q?br />   ·        查询语句处理 <br />   ·        DML语句处理(insert, update, delete) <br />   ·        DDL 语句处理(create .. , drop .. , alter .. , ) <br />   ·        事务控制(commit, rollback) <br /> <br /> <strong>  SQL 语句的执行过E?SQL Statement Execution)</strong><br />             <br />    ?-1 概要的列Z处理和运行一个sql语句的需要各个重要阶Dc在某些情况下,Oracleq行sql的过E可能与下面列出的各个阶D늚序有所不同。如DEFINE阶段可能在FETCH阶段之前Q这主要依赖你如何书写代码?br /> <br />   对许多oracle的工h_其中某些阶段会自动执行。绝大多数用户不需要关心各个阶D늚l节问题Q然而,知道执行的各个阶D还是有必要的,q会帮助你写出更高效的SQL语句来,而且q可以让你猜出性能差的SQL语句主要是由于哪一个阶D造成的,然后我们针对q个具体的阶D,扑և解决的办法?br /> <br />   ?3-1  SQL语句处理的各个阶D?br /> <br /> <strong>  DML语句的处?/strong><br />       <br />   本节l出一个例子来说明在DML语句处理的各个阶D到底发生了什么事情。假设你使用Pro*CE序来ؓ指定部门的所有职员增加工资。程序已l连到正的用户Q你可以在你的程序中嵌入如下的SQL语句Q?br /> EXEC SQL UPDATE employees <br /> SET salary = 1.10 * salary WHERE department_id = :var_department_id; var_department_id是程序变量,里面包含部门P我们要修改该部门的职员的工资。当q个SQL语句执行Ӟ使用该变量的倹{?br /> <br />   每种cd的语句都需要如下阶D:<br />   ·        W?? Create a Cursor     创徏游标<br />   ·        W?? Parse the Statement  分析语句<br />   ·        W?? Bind Any Variables    l定变量<br />   ·        W?? Run the Statement    q行语句<br />   ·        W?? Close the Cursor     关闭游标<br /> <br />   如果使用了ƈ行功能,q会包含下面q个阶段Q?br />   ·        W?? Parallelize the Statement   q行执行语句<br /> <br />   如果是查询语句,则需要以下几个额外的步骤Q如?3所C:<br />   ·        W?? Describe Results of a Query   描述查询的结果集<br />   ·        W?? Define Output of a Query      定义查询的输出数?br />   ·        W?? Fetch Rows of a Query        取查询出来的?br /> <br />   下面具体说一下每一步中都发生了什么事情:.<br /> <strong><br />   W?? 创徏游标(Create a Cursor)</strong><br /> <br />         q序接口调用创Z个游标(cursorQ。Q何SQL语句都会创徏它,特别在运行DML语句Ӟ都是自动创徏游标的,不需要开发h员干预。多数应用中Q游标的创徏是自动的。然而,在预~译E序(pro*c)中游标的创徏Q可能是隐含的,也可能显式的创徏。在存储q程中也是这L?br /> <br /> <strong>  W??分析语句(Parse the Statement)</strong><br />  <br />   在语法分析期_SQL语句从用戯E传送到OracleQSQL语句l语法分析后QSQL语句本n与分析的信息都被装入到共享SQL区。在该阶D中Q可以解册多类型的错误?br /> <br />   语法分析分别执行下列操作Q?br /> l        译SQL语句Q验证它是合法的语句Q即书写正确<br /> l        实现数据字典的查找,以验证是否符合表和列的定?br /> l        在所要求的对象上获取语法分析锁,使得在语句的语法分析q程中不改变q些对象的定?br /> l        验证为存取所涉及的模式对象所需的权限是否满?br /> l        军_此语句最佳的执行计划<br /> l        它装入׃nSQL?br /> l        对分布的语句来说Q把语句的全部或部分路由到包含所涉及数据的远E节?br />       <br />   以上M一步出现错误,都将D语句报错Q中止执行?br /> <br />   只有在共享池中不存在{h(hun)SQL语句的情况下Q才对SQL语句作语法分析。在q种情况下,数据库内栔RCؓ该语句分配新的共享SQL区,q对语句q行语法分析。进行语法分析需要耗费较多的资源,所以要量避免q行语法分析Q这是优化的技巧之一?br /> <br />   语法分析阶段包含了不此语句执行多次Q而只需分析一ơ的处理要求。Oracle只对每个SQL语句译一ơ,在以后再ơ执行该语句Ӟ只要该语句还在共享SQLZQ就可以避免对该语句重新q行语法分析Q也是此时可以直接使用其对应的执行计划Ҏ(gu)据进行存取。这主要是通过l定变量(bind variable)实现的,也就是我们常说的׃nSQLQ后面会l出׃nSQL的概c?br /> <br />   虽然语法分析验证了SQL语句的正性,但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误、权限不等)。因此,有些错误通过语法分析是抓不到的。例如,在数据{换中的错误或在数据中的错Q如企图在主键中插入重复的|以及死锁{均是只有在语句执行阶段期间才能遇到和报告的错误或情c?br /> <br /> <strong>  查询语句的处?/strong><br />       <br />   查询与其它类型的SQL语句不同Q因为在成功执行后作为结果将q回数据。其它语句只是简单地q回成功或失败,而查询则能返回一行或许多行数据。查询的l果均采用表格Ş式,l果行被一ơ一行或者批量地被检索出来。从q里我们可以得知扚w的fetch数据可以降低|络开销Q所以批量的fetch也是优化的技巧之一?br /> <br />        有些问题只与查询处理相关Q查询不仅仅指SELECT语句Q同样也包括在其它SQL语句中的隐含查询。例如,下面的每个语句都需要把查询作ؓ它执行的一部分Q?br /> INSERT INTO table SELECT... <br /> UPDATE table SET x = y WHERE... <br /> DELETE FROM table WHERE... <br /> CREATE table AS SELECT... <br /> <br />   具体来说Q查?br /> ·        要求M致?br /> ·        可能使用回滚D作中间处理<br /> ·        可能要求SQL语句处理描述、定义和取数据阶D?br /> <br /> <strong>  W?? 描述查询l果(Describe Results of a Query)</strong><br />  <br />   描述阶段只有在查询结果的各个列是未知时才需要;例如Q当查询q户交互地输入需要输出的列名。在q种情况要用描述阶段来决定查询结果的特征Q数据类型,长度和名字)?br /> <br /> <strong>  W?? 定义查询的输出数?Define Output of a Query)  </strong><br />        <br />   在查询的定义阶段Q你指定与查询出的列值对应的接收变量的位|、大和数据cdQ这h们通过接收变量可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列cd相比较决定的?br /> <br /> <strong>  W?? l定变量(Bind Any Variables)</strong><br />       <br />   此时QOracle知道了SQL语句的意思,但仍没有_的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的倹{在该例中,Oracle需要得到对department_id列进行限定的倹{得到这个值的q程叫l定变量(binding variables)<br /> <br />   此过E称之ؓ变量值捆l进来。程序必L出可以找到该数值的变量名(该变量被UCؓ捆绑变量Q变量名实质上是一个内存地址Q相当于指针Q。应用的最l用户可能ƈ没有发觉他们正在指定捆绑变量Q因为Oracle 的程序可能只是简单地指示他们输入新的|其实q一切都在程序中自动做了。因Z指定了变量名Q在你再ơ执行之前无重新捆l变量。你可以改变l定变量的|而Oracle在每ơ执行时Q仅仅用内存地址来查找此倹{如果Oracle 需要实现自动数据类型{换的话(除非它们是隐含的或缺省的Q,你还必须Ҏ(gu)个值指定数据类型和长度。关于这些信息可以参考oracle的相x档,如Oracle Call Interface Programmer's Guide<br /> <br /> <strong>  W?? q行执行语句(Parallelize the Statement )</strong><br />      <br />   ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应ƈ行查询操作,对于某些DDL操作Q如创徏索引、用子查询创、在分区表上的操作,也可以执行ƈ行操作。ƈ行化可以D多个服务器进E?oracle server processes)为同一个SQL语句工作Q该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用q行查询?br /> <br /> <strong>  W?? 执行语句(Run the Statement)</strong><br />       <br />   C现在q个时候,Oracle拥有所有需要的信息与资源,因此可以真正q行SQL语句了。如果该语句为SELECT查询或INSERT语句Q则不需要锁定Q何行Q因为没有数据需要被改变。然而,如果语句为UPDATE或DELETE语句Q则该语句媄响的所有行都被锁定Q防止该用户提交或回滚之前,别的用户对这些数据进行修攏V这保证了数据的一致性。对于某些语句,你可以指定执行的ơ数Q这UCؓ批处?array processing)。指定执行Nơ,则绑定变量与定义变量被定义ؓ大小为N的数l的开始位|,q种Ҏ(gu)可以减少|络开销Q也是优化的技巧之一?br /> <br /> <strong>  W?? 取出查询的行(Fetch Rows of a Query)</strong><br />       <br />   在fetch阶段Q行数据被取出来Q每个后l的存取操作索结果集中的下一行数据,直到最后一行被取出来。上面提到过Q批量的fetch是优化的技巧之一?br /> <br /> <strong>  W?? 关闭游标(Close the Cursor)</strong><br />       <br />   SQL语句处理的最后一个阶D就是关闭游?br /> <br /> <strong>  DDL语句的处?DDL Statement Processing)</strong><br />      <br />   DDL语句的执行不同与DML语句和查询语句的执行Q这是因为DDL语句执行成功后需要对数据字典数据q行修改。对于DDL语句Q语句的分析阶段实际上包括分析、查找数据字怿息和执行。事务管理语句、会话管理语句、系l管理语句只有分析与执行阶段Qؓ了重新执行该语句Q会重新分析与执行该语句?br /> <br /> <strong>  事务控制(Control of Transactions)</strong><br />       <br />   一般来_只有使用ORACLE~程接口的应用设计h员才兛_操作的类型,q把相关的操作组l在一P形成一个事务。一般来_我门必须定义事务Q这样在一个逻辑单元中的所有工作可以同时被提交或回滚,保证了数据的一致性。一个事务应该由逻辑单元中的所有必部分组成,不应该多一个,也不应该一个?br />   ·        在事务开始和l束的这D|间内Q所有被引用表中的数据都应该在一致的状?或可以被回溯C致的状?<br />   ·        事务应该只包含可以对数据q行一致更?one consistent change to the data)的SQL语句<br /> <br />   例如Q在两个帐号之间的{?q是一个事务或逻辑工作单元)Q应该包含从一个帐号中借钱(׃个SQL完成)Q然后将借的钱存入另一个帐?由另一个SQL完成)。这2个操作作Z个逻辑单元Q应该同时成功或同时p|。其它不相关的操作,如向一个帐户中存钱Q不应该包含在这个{帐事务中?br /> <br />   在设计应用时Q除了需要决定哪U类型的操作l成一个事务外Q还需要决定用BEGIN_DISCRETE_TRANSACTIO存储q程是否Ҏ(gu)高小的、非分布式的事务的性能有作用? <img src ="http://www.tkk7.com/xixidabao/aggbug/169007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xixidabao/" target="_blank">JAVA之\</a> 2007-12-20 13:30 <a href="http://www.tkk7.com/xixidabao/archive/2007/12/20/169007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL触发器语法参?http://www.tkk7.com/xixidabao/archive/2007/12/07/165947.htmlJAVA之\JAVA之\Fri, 07 Dec 2007 01:13:00 GMThttp://www.tkk7.com/xixidabao/archive/2007/12/07/165947.htmlSQL触发器语法参?/a>


[ WITH ENCRYPTION ]
{

    { { [ INSERT ] [ , ] [ UPDATE ] }
        [ NOT FOR REPLICATION ]
        [ { IF UPDATE ( column )
            [ ...n ]
         bitwise_operator } comparison_operator
} ]
        sql_statement [ ...n ]
    }
}

参数

trigger_name

是触发器的名U。触发器名称必须W合标识W规则,q且在数据库中必d一。可以选择是否指定触发器所有者名U?/p>

Table | view

是在其上执行触发器的表或视图Q有时称发器表或触发器视图。可以选择是否指定表或视图的所有者名U?/p>

WITH ENCRYPTION

加密 syscomments 表中包含 CREATE TRIGGER 语句文本的条目。?WITH ENCRYPTION 可防止将触发器作?SQL Server 复制的一部分发布?/p>

AFTER

指定触发器只有在触发 SQL 语句中指定的所有操作都已成功执行后才激发。所有的引用U联操作和约束检查也必须成功完成后,才能执行此触发器?/p>

如果仅指?FOR 关键字,?AFTER 是默认设|?/p>

不能在视图上定义 AFTER 触发器?/p>

INSTEAD OF

指定执行触发器而不是执行触?SQL 语句Q从而替代触发语句的操作?/p>

在表或视图上Q每?INSERT、UPDATE ?DELETE 语句最多可以定义一?INSTEAD OF 触发器。然而,可以在每个具?INSTEAD OF 触发器的视图上定义视图?/p>

INSTEAD OF 触发器不能在 WITH CHECK OPTION 的可更新视图上定义。如果向指定?WITH CHECK OPTION 选项的可更新视图d INSTEAD OF 触发器,SQL Server 生一个错误。用户必ȝ ALTER VIEW 删除该选项后才能定?INSTEAD OF 触发器?/p>

{ [DELETE] [,] [INSERT] [,] [UPDATE] }

是指定在表或视图上执行哪些数据修改语句时激z触发器的关键字。必至指定一个选项。在触发器定义中允许使用以Q意顺序组合的q些关键字。如果指定的选项多于一个,需用逗号分隔q些选项?/p>

对于 INSTEAD OF 触发器,不允许在h ON DELETE U联操作引用关系的表上?DELETE 选项。同P也不允许在具?ON UPDATE U联操作引用关系的表上?UPDATE 选项?/p>

WITH APPEND

指定应该d现有cd的其它触发器。只有当兼容U别?65 或更低时Q才需要用该可选子句。如果兼容别是 70 或更高,则不必?WITH APPEND 子句d现有cd的其它触发器Q这是兼容别设|ؓ 70 或更高的 CREATE TRIGGER 的默认行为)。有x多信息,请参?strong> sp_dbcmptlevel?/p>

WITH APPEND 不能?INSTEAD OF 触发器一起用,或者,如果昑ּ声明 AFTER 触发器,也不能用该子句。只有当Z向后兼容而指?FOR Ӟ没有 INSTEAD OF ?AFTERQ,才能使用 WITH APPEND。以后的版本不支持 WITH APPEND ?FORQ将被解释ؓ AFTERQ?/p>

NOT FOR REPLICATION

表示当复制进E更改触发器所涉及的表Ӟ不应执行该触发器?/p>

AS

是触发器要执行的操作?/p>

sql_statement

是触发器的条件和操作。触发器条g指定其它准则Q以定 DELETE、INSERT ?UPDATE 语句是否D执行触发器操作?/p>

当尝?DELETE、INSERT ?UPDATE 操作ӞTransact-SQL语句中指定的触发器操作将生效?/p>

触发器可以包含Q意数量和U类?Transact-SQL 语句。触发器旨在Ҏ(gu)数据修改语句查或更改数据Q它不应数据返回给用户。触发器中的 Transact-SQL 语句常常包含控制语a。CREATE TRIGGER 语句中用几个特D的表:

  • deleted ?inserted 是逻辑Q概念)表。这些表在结构上cM于定义触发器的表Q也是在其中尝试用h作的表)Q这些表用于保存用户操作可能更改的行的旧值或新倹{例如,若要?deleted 表中的所有|请用:
    SELECT *
        FROM deleted
        
  • 如果兼容U别{于 70Q那么在 DELETE、INSERT ?UPDATE 触发器中QSQL Server 不允许引用 inserted ?deleted 表中?text?strong>ntext ?image 列。不能访?inserted ?deleted 表中?text?strong>ntext ?image 倹{若要在 INSERT ?UPDATE 触发器中索新|请将 inserted 表与原始更新表联接。当兼容U别?65 或更低时Q对 inserted ?deleted 表中允许I值的text?strong>ntext ?image 列,返回空|如果q些列不可ؓI,则返回零长度字符丌Ӏ?

    当兼容别是 80 或更高时QSQL Server 允许在表或视图上通过 INSTEAD OF 触发器更?text?strong>ntext ?image 列?/p>

n

是表C发器中可以包含多?Transact-SQL 语句的占位符。对?IF UPDATE (column) 语句Q可以通过重复 UPDATE (column) 子句包含多列?/p>

IF UPDATE (column)

试在指定的列上q行?INSERT ?UPDATE 操作Q不能用?DELETE 操作。可以指定多列。因为在 ON 子句中指定了表名Q所以在 IF UPDATE 子句中的列名前不要包含表名。若要测试在多个列上q行?INSERT ?UPDATE 操作Q请在第一个操作后指定单独?UPDATE(column) 子句。在 INSERT 操作?IF UPDATE 返?TRUE |因ؓq些列插入了昑ּ值或隐?(NULL) 倹{?/p>

说明  IF UPDATE (column) 子句的功能等同于 IF、IF...ELSE ?WHILE 语句Qƈ且可以?BEGIN...END 语句块。有x多信息,请参?a >控制语a?

 

可以在触发器M中的L位置使用 UPDATE (column)?/p>

column

是要试 INSERT ?UPDATE 操作的列名。该列可以是 SQL Server 支持的Q何数据类型。但是,计算列不能用于该环境中。有x多信息,请参?a >数据cd?

IF (COLUMNS_UPDATED())

试是否插入或更C提及的列Q仅用于 INSERT ?UPDATE 触发器中。COLUMNS_UPDATED q回 varbinary 位模式,表示插入或更C表中的哪些列?/p>

COLUMNS_UPDATED 函数以从左到右的序q回位,最左边的ؓ最不重要的位。最左边的位表示表中的第一列;向右的下一位表C第二列Q依此类推。如果在表上创徏的触发器包含 8 列以上,?COLUMNS_UPDATED q回多个字节Q最左边的ؓ最不重要的字节。在 INSERT 操作?COLUMNS_UPDATED 对所有列q回 TRUE |因ؓq些列插入了昑ּ值或隐?(NULL) 倹{?/p>

可以在触发器M中的L位置使用 COLUMNS_UPDATED?/p>

bitwise_operator

是用于比较运的位运符?/p>

updated_bitmask

是整型位掩码Q表C实际更新或插入的列。例如,?t1 包含?C1?strong>C2?strong>C3?strong>C4 ?C5。假定表 t1 上有 UPDATE 触发器,若要查列 C2、C3 ?C4 是否都有更新Q指定?14Q若要检查是否只有列 C2 有更斎ͼ指定?2?/p>

comparison_operator

是比较运符。用等?(=) ?updated_bitmask 中指定的所有列是否都实际进行了更新。用大于号 (>) ?updated_bitmask 中指定的M列或某些列是否已更新?/p>

column_bitmask

是要查的列的整型位掩码,用来查是否已更新或插入了q些列?

注释

触发器常常用于强制业务规则和数据完整性。SQL Server 通过表创句(ALTER TABLE ?CREATE TABLEQ提供声明引用完整?(DRI)Q但?DRI 不提供数据库间的引用完整性。若要强制引用完整性(有关表的主键和外键之间关pȝ规则Q,请用主键和外键U束QALTER TABLE ?CREATE TABLE ?PRIMARY KEY ?FOREIGN KEY 关键字)。如果触发器表存在约束,则在 INSTEAD OF 触发器执行之后和 AFTER 触发器执行之前检查这些约束。如果违反了U束Q则回滚 INSTEAD OF 触发器操作且不执行(Ȁ发)AFTER 触发器?/p>

可用 sp_settriggerorder 指定表上W一个和最后一个执行的 AFTER 触发器。在表上只能为每?INSERT、UPDATE ?DELETE 操作指定一个第一个执行和一个最后一个执行的 AFTER 触发器。如果同一表上q有其它 AFTER 触发器,则这些触发器以随机序执行?/p>

如果 ALTER TRIGGER 语句更改了第一个或最后一个触发器Q则除d修改触发器上讄的第一个或最后一个特性,而且必须?sp_settriggerorder 重置排序倹{?/p>

只有当触?SQL 语句Q包括所有与更新或删除的对象兌的引用联操作和U束查)成功执行后,AFTER 触发器才会执行。AFTER 触发器检查触发语句的q行效果Q以及所有由触发语句引v?UPDATE ?DELETE 引用U联操作的效果?/p>

触发器限?/h6>

CREATE TRIGGER 必须是批处理中的W一条语句,q且只能应用C个表中?

触发器只能在当前的数据库中创建,不过触发器可以引用当前数据库的外部对象?

如果指定触发器所有者名UC限定触发器,请以相同的方式限定表名?

在同一?CREATE TRIGGER 语句中,可以为多U用h作(?INSERT ?UPDATEQ定义相同的触发器操作?

如果一个表的外键在 DELETE/UPDATE 操作上定义了U联Q则不能在该表上定义 INSTEAD OF DELETE/UPDATE 触发器?/p>

在触发器内可以指定Q意的 SET 语句。所选择?SET 选项在触发器执行期间有效Qƈ在触发器执行完后恢复C前的讄?/p>

与用存储过E一P当触发器Ȁ发时Q将向调用应用程序返回结果。若要避免由于触发器Ȁ发而向应用E序q回l果Q请不要包含q回l果?SELECT 语句Q也不要包含在触发器中进行变量赋值的语句。包含向用户q回l果?SELECT 语句或进行变量赋值的语句的触发器需要特D处理;q些q回的结果必d入允怿改触发器表的每个应用E序中。如果必d触发器中q行变量赋|则应该在触发器的开头?SET NOCOUNT 语句以避免返回Q何结果集?

DELETE 触发器不能捕?TRUNCATE TABLE 语句。尽?TRUNCATE TABLE 语句实际上是没有 WHERE 子句?DELETEQ它删除所有行Q,但它是无日志记录的,因而不能执行触发器。因?TRUNCATE TABLE 语句的权限默认授予表所有者且不可转让Q所以只有表所有者才需要考虑无意中用 TRUNCATE TABLE 语句规避 DELETE 触发器的问题?/p>

无论有日志记录还是无日志记录QWRITETEXT 语句都不Ȁz触发器?/p>

触发器中不允总?Transact-SQL 语句Q?/p>
ALTER DATABASE CREATE DATABASE DISK INIT
DISK RESIZE DROP DATABASE LOAD DATABASE
LOAD LOG RECONFIGURE RESTORE DATABASE
RESTORE LOG    

说明  ׃ SQL Server 不支持系l表中的用户定义触发器,因此不要在系l表中创建用户定义触发器?/p>

 

多个触发?/h6>

SQL Server 允许为每个数据修改事ӞDELETE、INSERT ?UPDATEQ创建多个触发器。例如,如果对已?UPDATE 触发器的表执?CREATE TRIGGER FOR UPDATEQ则创建另一个更新触发器。在早期版本中,在每个表上,每个数据修改事gQINSERT、UPDATE ?DELETEQ只允许有一个触发器?

说明  如果触发器名UC同,?CREATE TRIGGERQ兼容别ؓ 70Q的默认行ؓ是在现有的触发器中添加其它触发器。如果触发器名称相同Q则 SQL Server q回一条错误信息。但是,如果兼容U别{于或小?65Q则使用 CREATE TRIGGER 语句创徏的新触发器将替换同一cd的Q何现有触发器Q即使触发器名称不同。有x多信息,请参?strong> sp_dbcmptlevel?

 

递归触发?/h6>

当在 sp_dboption 中启?recursive triggers 讄ӞSQL Server q允许触发器的递归调用?/p>

递归触发器允许发生两U类型的递归Q?

  • 间接递归

  • 直接递归

使用间接递归Ӟ应用E序更新?T1Q从而激发触发器 TR1Q该触发器更新表 T2。在q种情况下,触发?T2 激发ƈ更新 T1?/p>

使用直接递归Ӟ应用E序更新?T1Q从而激发触发器 TR1Q该触发器更新表 T1。由于表 T1 被更斎ͼ触发?TR1 再次Ȁ发,依此cL?/p>

下例既用了间接触发器递归Q又使用了直接触发器递归。假定在?T1 中定义了两个更新触发?TR1 ?TR2。触发器 TR1 递归地更新表 T1。UPDATE 语句?TR1 ?TR2 各执行一ơ。?TR1 的执行将触发 TR1Q递归Q和 TR2 的执行。给定触发器?inserted ?deleted 表只包含与唤醒调用触发器?UPDATE 语句相对应的行?/p>

说明  只有启用 sp_dboption ?recursive triggers 讄Q才会发生上q行为。对于ؓl定事g定义的多个触发器Qƈ没有定的执行顺序。每个触发器都应是自包含的?/p>

 

recursive triggers 讄只能止直接递归。若要也用间接递归Q请使用 sp_configure ?nested triggers 服务器选项讄?0?/p>

如果M触发器执行了 ROLLBACK TRANSACTION 语句Q则无论嵌套U是多少Q都不会q一步执行其它触发器?/p>

嵌套触发?/h6>

触发器最多可以嵌?32 层。如果一个触发器更改了包含另一个触发器的表Q则W二个触发器激z,然后该触发器可以再调用第三个触发器,依此cL。如果链中Q意一个触发器引发了无限@环,则会出嵌套U限Ӟ从而导致取消触发器。若要禁用嵌套触发器Q请?sp_configure ?nested triggers 选项讄?0Q关闭)。默认配|允许嵌套触发器。如果嵌套触发器是关闭的Q则也将用递归触发器,?sp_dboption ?recursive triggers 讄无关?/p>

延迟名称解析

SQL Server 允许 Transact-SQL 存储q程、触发器和批处理引用~译时不存在的表。这U能力称为gq名U解析。但是,如果 Transact-SQL 存储q程、触发器或批处理引用在存储过E或触发器中定义的表Q则只有当兼容别设|(通过执行 sp_dbcmptlevel 讄Q等?65 Ӟ才会在创建时发出警告。如果用批处理Q则在编译时发出警告。如果引用的表不存在Q将在运行时q回错误信息。有x多信息,请参?a ="javascript:hhobj_1.Click()">延迟名称解析和编?/a>?

权限

CREATE TRIGGER 权限默认授予定义触发器的表所有者?strong>sysadmin 固定服务器角色成员以?db_owner ?db_ddladmin 固定数据库角色成员,q且不可转让?/p>

若要索表或视图中的数据,用户必须在表或视图中拥有 SELECT 语句权限。若要更新表或视囄内容Q用户必d表或视图中拥?INSERT、DELETE ?UPDATE 语句权限?/p>

如果视图中存?INSTEAD OF 触发器,用户必须在该视图中有 INSERT、DELETE ?UPDATE Ҏ(gu)Q以对该视图发出 INSERT、DELETE ?UPDATE 语句Q而不实际上是否在视图上执行了这L操作?/p>

CZ
A. 使用带有提醒消息的触发器

当有囑֜ titles 表中d或更Ҏ(gu)据时Q下例将向客L昄一条消息?/p>

说明  消息 50009 ?sysmessages 中的用户定义消息。有兛_建用户定义消息的更多信息Q请参见 sp_addmessage?

 

USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE
AS RAISERROR (50009, 16, 10)
GO
B. 使用带有提醒?sh)子邮g的触发器

?titles 表更Ҏ(gu)Q下例将?sh)子邮g发送给指定的h?(MaryM)?/p>

USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'reminder' AND type = 'TR')
DROP TRIGGER reminder
GO
CREATE TRIGGER reminder
ON titles
FOR INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail 'MaryM',
'Don''t forget to print a report for the distributors.'
GO
C. ?employee ?jobs 表之间用触发器业务规则

׃ CHECK U束只能引用定义了列U或表U束的列Q表间的MU束Q在下例中是指业务规则)都必d义ؓ触发器?/p>

下例创徏一个触发器Q当插入或更新雇员工作?(job_lvls) Ӟ该触发器查指定雇员的工作U别Q由此决定薪_是否处于工作定义的范围内。若要获得适当的范_必须引用 jobs 表?/p>

USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'employee_insupd' AND type = 'TR')
DROP TRIGGER employee_insupd
GO
CREATE TRIGGER employee_insupd
ON employee
FOR INSERT, UPDATE
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @min_lvl tinyint,
@max_lvl tinyint,
@emp_lvl tinyint,
@job_id smallint
SELECT @min_lvl = min_lvl,
@max_lvl = max_lvl,
@emp_lvl = i.job_lvl,
@job_id = i.job_id
FROM employee e INNER JOIN inserted i ON e.emp_id = i.emp_id
JOIN jobs j ON j.job_id = i.job_id
IF (@job_id = 1) and (@emp_lvl   10)
BEGIN
RAISERROR ('Job id 1 expects the default level of 10.', 16, 1)
ROLLBACK TRANSACTION
END
ELSE
IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)
BEGIN
RAISERROR ('The level for job_id:%d should be between %d and %d.',
16, 1, @job_id, @min_lvl, @max_lvl)
ROLLBACK TRANSACTION
END
D. 使用延迟名称解析

下例创徏两个触发器以说明延迟名称解析?

USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'trig1' AND type = 'TR')
DROP TRIGGER trig1
GO
-- Creating a trigger on a nonexistent table.
CREATE TRIGGER trig1
on authors
FOR INSERT, UPDATE, DELETE
AS
SELECT a.au_lname, a.au_fname, x.info
FROM authors a INNER JOIN does_not_exist x
ON a.au_id = x.au_id
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig1'
-- Creating a trigger on an existing table, but with a nonexistent
-- column.
USE pubs
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'trig2' AND type = 'TR')
DROP TRIGGER trig2
GO
CREATE TRIGGER trig2
ON authors
FOR INSERT, UPDATE
AS
DECLARE @fax varchar(12)
SELECT @fax = phone
FROM authors
GO
-- Here is the statement to actually see the text of the trigger.
SELECT o.id, c.text
FROM sysobjects o INNER JOIN syscomments c
ON o.id = c.id
WHERE o.type = 'TR' and o.name = 'trig2'
E. 使用 COLUMNS_UPDATED

下例创徏两个表:一?employeeData 表和一?auditEmployeeData 表。h力资源部的成员可以修?employeeData 表,该表包含敏感的雇员薪水信息。如果更改了雇员的社会保险号?(SSN)、年薪或银行帐户Q则生成审核记录q插入到 auditEmployeeData 审核表?/p>

通过使用 COLUMNS_UPDATED() 功能Q可以快速测试对q些包含敏感雇员信息的列所做的更改。只有在试图对表中的前 8 列所做的更改ӞCOLUMNS_UPDATED() 才v作用?/p>

USE pubs
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'employeeData')
DROP TABLE employeeData
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'auditEmployeeData')
DROP TABLE auditEmployeeData
GO
CREATE TABLE employeeData (
emp_id int NOT NULL,
emp_bankAccountNumber char (10) NOT NULL,
emp_salary int NOT NULL,
emp_SSN char (11) NOT NULL,
emp_lname nchar (32) NOT NULL,
emp_fname nchar (32) NOT NULL,
emp_manager int NOT NULL
)
GO
CREATE TABLE auditEmployeeData (
audit_log_id uniqueidentifier DEFAULT NEWID(),
audit_log_type char (3) NOT NULL,
audit_emp_id int NOT NULL,
audit_emp_bankAccountNumber char (10) NULL,
audit_emp_salary int NULL,
audit_emp_SSN char (11) NULL,
audit_user sysname DEFAULT SUSER_SNAME(),
audit_changed datetime DEFAULT GETDATE()
)
GO
CREATE TRIGGER updEmployeeData
ON employeeData
FOR update AS
/*Check whether columns 2, 3 or 4 has been updated. If any or all of columns 2, 3 or 4 have been changed, create an audit record. The bitmask is: power(2,(2-1))+power(2,(3-1))+power(2,(4-1)) = 14. To check if all columns 2, 3, and 4 are updated, use = 14 in place of >0 (below).*/
IF (COLUMNS_UPDATED() & 14) > 0
/*Use IF (COLUMNS_UPDATED() & 14) = 14 to see if all of columns 2, 3, and 4 are updated.*/
BEGIN
-- Audit OLD record.
INSERT INTO auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'OLD',
del.emp_id,
del.emp_bankAccountNumber,
del.emp_salary,
del.emp_SSN
FROM deleted del
-- Audit NEW record.
INSERT INTO auditEmployeeData
(audit_log_type,
audit_emp_id,
audit_emp_bankAccountNumber,
audit_emp_salary,
audit_emp_SSN)
SELECT 'NEW',
ins.emp_id,
ins.emp_bankAccountNumber,
ins.emp_salary,
ins.emp_SSN
FROM inserted ins
END
GO
/*Inserting a new employee does not cause the UPDATE trigger to fire.*/
INSERT INTO employeeData
VALUES ( 101, 'USA-987-01', 23000, 'R-M53550M', N'Mendel', N'Roland', 32)
GO
/*Updating the employee record for employee number 101 to change the salary to 51000 causes the UPDATE trigger to fire and an audit trail to be produced.*/
UPDATE employeeData
SET emp_salary = 51000
WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO
/*Updating the employee record for employee number 101 to change both the bank account number and social security number (SSN) causes the UPDATE trigger to fire and an audit trail to be produced.*/
UPDATE employeeData
SET emp_bankAccountNumber = '133146A0', emp_SSN = 'R-M53550M'
   WHERE emp_id = 101
GO
SELECT * FROM auditEmployeeData
GO
F. 使用 COLUMNS_UPDATED 试 8 列以?/h6>

如果必须试影响到表中前 8 列以外的列的更新Ӟ必须使用 UBSTRING 函数试?COLUMNS_UPDATED q回的适当的位。下例测试媄?Northwind.dbo.Customers 表中的第 3、第 5 或第 9 列的更新?/p>

USE Northwind
DROP TRIGGER  tr1
GO
CREATE TRIGGER tr1 ON Customers
FOR UPDATE AS
IF ( (SUBSTRING(COLUMNS_UPDATED(),1,1)=power(2,(3-1))
+ power(2,(5-1)))
AND (SUBSTRING(COLUMNS_UPDATED(),2,1)=power(2,(1-1)))
)
PRINT 'Columns 3, 5 and 9 updated'
GO
UPDATE Customers
SET ContactName=ContactName,
Address=Address,
Country=Country
GO


JAVA之\ 2007-12-07 09:13 发表评论
]]>
标准SQL参?/title><link>http://www.tkk7.com/xixidabao/archive/2007/07/23/131875.html</link><dc:creator>JAVA之\</dc:creator><author>JAVA之\</author><pubDate>Mon, 23 Jul 2007 06:41:00 GMT</pubDate><guid>http://www.tkk7.com/xixidabao/archive/2007/07/23/131875.html</guid><description><![CDATA[<p>一?单查?<br>  单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所查询列、查询的表或视图、以及搜索条件等?br>  例如Q下面的语句查询testtable表中姓名?张三"的nickname字段和email字段? <p>   SELECT nickname,email<br>  FROM testtable<br>  WHERE name='张三' <p>  (一) 选择列表 <p>  选择列表(select_list)指出所查询列,它可以是一l列名列表、星受表辑ּ、变?包括局部变量和全局变量){构成? <p>  1、选择所有列 <p>  例如Q下面语句显Ctesttable表中所有列的数据: <p>   SELECT *<br>  FROM testtable <p>  2、选择部分列ƈ指定它们的显C次? <p>  查询l果集合中数据的排列序与选择列表中所指定的列名排列顺序相同?br>  例如Q? <p>   SELECT nickname,email<br>  FROM testtable <p>  3、更改列标题 <p>  在选择列表中,可重新指定列标题。定义格式ؓQ?br>  列标?列名<br>  列名 列标?br>  如果指定的列标题不是标准的标识符格式Ӟ应用引号定界符Q例如,下列语句使用汉字昄列标题: <p>   SELECT 늧=nickname,?sh)子邮g=email<br>  FROM testtable <p>  4、删除重复行 <p>  SELECT语句中用ALL或DISTINCT选项来显C中符合条件的所有行或删除其中重复的数据行,默认为ALL。用DISTINCT选项Ӟ对于所有重复的数据行在SELECTq回的结果集合中只保留一行? <p>  5、限制返回的行数 <p>  使用TOP n [PERCENT]选项限制q回的数据行敎ͼTOP n说明q回n行,而TOP n PERCENTӞ说明n是表CZ癑ֈ敎ͼ指定q回的行数等于总行数的癑ֈ之几?br>  例如Q? <p>   SELECT TOP 2 *<br>  FROM testtable<br>  SELECT TOP 20 PERCENT *<br>  FROM testtable <p>  (?FROM子句 <p>  FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,它们之间用逗号分隔?br>  在FROM子句同时指定多个表或视图Ӟ如果选择列表中存在同名列Q这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应使用下面语句格式加以限定Q? <p>    SELECT username,citytable.cityid<br>  FROM usertable,citytable<br>  WHERE usertable.cityid=citytable.cityid <p>  在FROM子句中可用以下两U格式ؓ表或视图指定别名Q?br>  表名 as 别名<br>  表名 别名 <p>  (? FROM子句 <p>  FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,它们之间用逗号分隔?br>  在FROM子句同时指定多个表或视图Ӟ如果选择列表中存在同名列Q这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应使用下面语句格式加以限定Q? <p>   SELECT username,citytable.cityid<br>  FROM usertable,citytable<br>  WHERE usertable.cityid=citytable.cityid <p>  在FROM子句中可用以下两U格式ؓ表或视图指定别名Q?br>  表名 as 别名<br>  表名 别名<br>  例如上面语句可用表的别名格式表示为: <p>   SELECT username,b.cityid<br>  FROM usertable a,citytable b<br>  WHERE a.cityid=b.cityid <p>  SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所q回的结果集合中查询数据? <p>  例如Q? <p>    SELECT a.au_fname+a.au_lname<br>  FROM authors a,titleauthor ta<br>  (SELECT title_id,title<br>  FROM titles<br>  WHERE ytd_sales>10000<br>  ) AS t<br>  WHERE a.au_id=ta.au_id<br>  AND ta.title_id=t.title_id <p>  此例中,SELECTq回的结果集合给予一别名tQ然后再从中索数据? <p>(? 使用WHERE子句讄查询条g <p>  WHERE子句讄查询条gQ过滤掉不需要的数据行。例如下面语句查询年龄大?0的数据: <p>   SELECT *<br>  FROM usertable<br>  WHERE age>20 <p>  WHERE子句可包括各U条件运符Q?br>  比较q算W?大小比较)Q?gt;?gt;=??lt;?lt;=?lt;>?>?<<br>  范围q算W?表达式值是否在指定的范?QBETWEEN...AND...<br>  NOT BETWEEN...AND...<br>  列表q算W?判断表达式是否ؓ列表中的指定?QIN (?,?......)<br>  NOT IN (?,?......)<br>  模式匚wW?判断值是否与指定的字W通配格式相符):LIKE、NOT LIKE<br>  I值判断符(判断表达式是否ؓI?QIS NULL、NOT IS NULL<br>  逻辑q算W?用于多条件的逻辑q接)QNOT、AND、OR <p>  1、范围运符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30<br>  2、列表运符例:country IN ('Germany','China')<br>  3、模式匹配符例:常用于模p查找,它判断列值是否与指定的字W串格式相匹配。可用于char、varchar、text、ntext、datetime和smalldatetime{类型查询?br>  可用以下通配字符Q?br>  癑ֈ?Q可匚wLcd和长度的字符Q如果是中文Q请使用两个癑ֈ号即%%?br>  下划U_Q匹配单个Q意字W,它常用来限制表达式的字符长度?br>  Ҏ(gu)号[]Q指定一个字W、字W串或范_要求所匚w对象为它们中的Q一个。[^]Q其取g[] 相同Q但它要求所匚w对象为指定字W以外的M个字W?br>  例如Q?br>  限制以Publishingl尾Q用LIKE '%Publishing'<br>  限制以A开_LIKE '[A]%'<br>  限制以A开头外QLIKE '[^A]%' <p>  4、空值判断符例WHERE age IS NULL <p>  5、逻辑q算W:优先UؓNOT、AND、OR <p>  (?查询l果排序 <p>  使用ORDER BY子句Ҏ(gu)询返回的l果按一列或多列排序。ORDER BY子句的语法格式ؓQ?br>  ORDER BY {column_name [ASC|DESC]} [,...n]<br>  其中ASC表示升序Qؓ默认|DESC为降序。ORDER BY不能按ntext、text和image数据cdq行?br>  序?br>  例如Q? <p>    SELECT *<br>  FROM usertable<br>  ORDER BY age desc,userid ASC <p>  另外Q可以根据表辑ּq行排序? <p>  二?联合查询 <p>  UNIONq算W可以将两个或两个以上上SELECT语句的查询结果集合合q成一个结果集合显C,x行联合查询。UNION的语法格式ؓQ? <p>    select_statement<br>  UNION [ALL] selectstatement<br>  [UNION [ALL] selectstatement][...n] <p>  其中selectstatement为待联合的SELECT查询语句? <p>  ALL选项表示所有行合ƈ到结果集合中。不指定该项Ӟ被联合查询结果集合中的重复行只保留一行? <p>  联合查询Ӟ查询l果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语句中定义。要对联合查询结果排序时Q也必须使用W一查询语句中的列名、列标题或者列序号? <p>  在用UNION q算W时Q应保证每个联合查询语句的选择列表中有相同数量的表辑ּQƈ且每个查询选择表达式应h相同的数据类型,或是可以自动它们{换ؓ相同的数据类型。在自动转换Ӟ对于数值类型,pȝ低_ֺ的数据类型{换ؓ高精度的数据cd? <p>  在包括多个查询的UNION语句中,其执行顺序是自左臛_Q用括号可以改变这一执行序。例如: <p>  查询1 UNION (查询2 UNION 查询3) <p>  三、连接查? <p>  通过q接q算W可以实现多个表查询。连接是关系数据库模型的主要特点Q也是它区别于其它类型数据库理pȝ的一个标志? <p>  在关pL据库理pȝ中,表徏立时各数据之间的关系不必定Q常把一个实体的所有信息存攑֜一个表中。当索数据时Q通过q接操作查询出存攑֜多个表中的不同实体的信息。连接操作给用户带来很大的灵zL,他们可以在Q何时候增加新的数据类型。ؓ不同实体创徏新的表,后通过q接q行查询? <p>  q接可以在SELECT 语句的FROM子句或WHERE子句中徏立,似是而非在FROM子句中指接时有助于将q接操作与WHERE子句中的搜烦条g区分开来。所以,在Transact-SQL中推荐用这U方法? <p>  SQL-92标准所定义的FROM子句的连接语法格式ؓQ? <p>   FROM join_table join_type join_table<br>  [ON (join_condition)] <p>  其中join_table指出参与q接操作的表名,q接可以对同一个表操作Q也可以对多表操作,对同一个表操作的连接又U做自连接? <p>  join_type 指出q接cdQ可分ؓ三种Q内q接、外q接和交叉连接。内q接(INNER JOIN)使用比较q算W进行表间某(?列数据的比较操作Qƈ列出q些表中与连接条件相匚w的数据行。根据所使用的比较方式不同,内连接又分ؓ{D接、自然连接和不等q接三种。外q接分ؓ左外q接(LEFT OUTER JOIN或LEFT JOIN)、右外连?RIGHT OUTER JOIN或RIGHT JOIN)和全外连?FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列Zq接条g相匹配的行,而是列出左表(左外q接?、右?叛_q接?或两个表(全外q接?中所有符合搜索条件的数据行? <p>  交叉q接(CROSS JOIN)没有WHERE 子句Q它q回q接表中所有数据行的笛卡尔U,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以W二个表中符合查询条件的数据行数? <p>  q接操作中的ON (join_condition) 子句指出q接条gQ它pq接表中的列和比较运符、逻辑q算W等构成? <p>  无论哪种q接都不能对text、ntext和image数据cd列进行直接连接,但可以对q三U列q行间接q接。例如: <p>   SELECT p1.pub_id,p2.pub_id,p1.pr_info<br>  FROM pub_info AS p1 INNER JOIN pub_info AS p2<br>  ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info) <p>  (一)内连?br>  内连接查询操作列Zq接条g匚w的数据行Q它使用比较q算W比较被q接列的列倹{内q接分三U:<br>  1、等D接:在连接条件中使用{于?=)q算W比较被q接列的列|其查询结果中列出被连接表中的所有列Q包括其中的重复列?br>  2、不{连接: 在连接条件用除{于q算W以外的其它比较q算W比较被q接的列的列倹{这些运符包括>?gt;=?lt;=?lt;?>?<?lt;>?br>  3、自然连接:在连接条件中使用{于(=)q算W比较被q接列的列|但它使用选择列表指出查询l果集合中所包括的列Qƈ删除q接表中的重复列?br>  例,下面使用{D接列出authors和publishers表中位于同一城市的作者和出版C: <p>   SELECT *<br>  FROM authors AS a INNER JOIN publishers AS p<br>  ON a.city=p.city<br>  又如使用自然q接Q在选择列表中删除authors 和publishers 表中重复?city和state)Q?br>  SELECT a.*,p.pub_id,p.pub_name,p.country<br>  FROM authors AS a INNER JOIN publishers AS p<br>  ON a.city=p.city <p>  (?外连?br>  内连接时Q返回查询结果集合中的仅是符合查询条? WHERE 搜烦条g?HAVING 条g)和连接条件的行。而采用外q接Ӟ它返回到查询l果集合中的不仅包含W合q接条g的行Q而且q包括左?左外q接?、右?叛_q接?或两个边接表(全外q接)中的所有数据行。如下面使用左外q接论坛内容和作者信息连接v来: <p>   SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b<br>  ON a.username=b.username <p>  下面使用全外q接city表中的所有作者以及user表中的所有作者,以及他们所在的城市Q? <p>    SELECT a.*,b.*<br>  FROM city as a FULL OUTER JOIN user as b<br>  ON a.username=b.username <p>  (?交叉q接<br>  交叉q接不带WHERE 子句Q它q回被连接的两个表所有数据行的笛卡尔U,q回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以W二个表中符合查询条件的数据行数。例Qtitles表中?cd书,而publishers表中?家出版社Q则下列交叉q接索到的记录数等?*8=48行?br>   SELECT type,pub_name<br>  FROM titles CROSS JOIN publishers<br>  ORDER BY type </p> <img src ="http://www.tkk7.com/xixidabao/aggbug/131875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xixidabao/" target="_blank">JAVA之\</a> 2007-07-23 14:41 <a href="http://www.tkk7.com/xixidabao/archive/2007/07/23/131875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://zhongxueping888.com" target="_blank">ŮڵƵ</a>| <a href="http://nzzys.com" target="_blank">ëƬ߹ۿ</a>| <a href="http://lshwork.com" target="_blank">Ƶ߹ۿѲ</a>| <a href="http://xzdlgp.com" target="_blank">ƷСƵ</a>| <a href="http://qzllw.com" target="_blank">ҳƷ˿</a>| <a href="http://laxdz.com" target="_blank">ձvѷƵ</a>| <a href="http://by11gun.com" target="_blank">ҹƷ</a>| <a href="http://dagongxing.com" target="_blank">ŷ</a>| <a href="http://catalna.com" target="_blank">˳վ߹ۿ</a>| <a href="http://lanoss.com" target="_blank">ŷŮƵ</a>| <a href="http://22nee.com" target="_blank">AVһ </a>| <a href="http://tqdrhj.com" target="_blank">˳ɫ7777߹ۿ</a>| <a href="http://zhiwajic.com" target="_blank">ѴƬavֻƬ</a>| <a href="http://taoh2507.com" target="_blank">ĻӰѹۿ</a>| <a href="http://600c63.com" target="_blank">պƬѹۿƵ</a>| <a href="http://sdtuoliuta.com" target="_blank">޸Ʒһ</a>| <a href="http://918989b.com" target="_blank">jizzһ</a>| <a href="http://dasheng178.com" target="_blank">޾ƷAv߹ۿ</a>| <a href="http://doubaye.com" target="_blank">ձAëһƬ</a>| <a href="http://adcacs.com" target="_blank">޻ɫѹۿ</a>| <a href="http://jiggybaby.com" target="_blank">þۺAVѹۿ</a>| <a href="http://128313.com" target="_blank">Ʒۺ</a>| <a href="http://51jingpai.com" target="_blank">þþƷһ</a>| <a href="http://sijep.com" target="_blank">Ѿþˬˬav</a>| <a href="http://mogo321.com" target="_blank">Ƶվ</a>| <a href="http://cndianxian.com" target="_blank">91ƷӾʢ</a>| <a href="http://slotvip24.com" target="_blank">Ůվ</a>| <a href="http://as5566.com" target="_blank">޹Ʒ</a>| <a href="http://cebeke.com" target="_blank">2021ƷƵ</a>| <a href="http://takiku.com" target="_blank">avպר߹ۿ</a>| <a href="http://lai228.com" target="_blank">߹ۿ޾ƷƬ</a>| <a href="http://ttvv55.com" target="_blank">99߹ۿƵ</a>| <a href="http://zhiwajic.com" target="_blank">ۺһ뾫Ʒ</a>| <a href="http://shunfk.com" target="_blank">ݺɫúݺݺۺ</a>| <a href="http://www97544.com" target="_blank">þѾƷһ</a>| <a href="http://6464k.com" target="_blank">ass**ëpics</a>| <a href="http://by33321.com" target="_blank">߻ɫַ</a>| <a href="http://440878.com" target="_blank">۲Ƶwwwѿ</a>| <a href="http://5666my.com" target="_blank">һƷƵ</a>| <a href="http://youweidianqi.com" target="_blank">ֻùۿ</a>| <a href="http://xwy2.com" target="_blank">97þƵ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>