??xml version="1.0" encoding="utf-8" standalone="yes"?>
以前在Oracle中用=(+)?+)=来进行左外联接和叛_联接Q后来用SQL Server时用*=?*q行外连接左外联接和叛_联接Q?br>现在军_用SQL-92的标准方法:(x)[OUTER] JOINQOUTER是可以省略的?/p>
LEFT OUTER JOIN ?nbsp;LEFT JOIN 表示左外联接
RIGHT OUTER JOIN ?nbsp;RIGHT JOIN 表示左外联接
FULL OUTER JOIN ?nbsp;FULL JOIN 表示左外联接
外联接的意思不用多_(d)我们都懂Q但是JOIN到底怎么用呢Q没有找到很好的资料Q只能从例子中学?fn)?jin)Q?/p>
1、这个例子也许没有实际意义,只是Z(jin)说明问题Q?/p>
CREATE TABLE orders(order_id int, firm_id int, p_id int) CREATE TABLE firms (firm_id int, f_name int) CREATE TABLE products(p_id int, p_name int) select a.order_id, b.f_name, c.p_name from orders a left join firms b on a.firm_id = b.firm_id left join products c on a.p_id = c.p_id
说明Qorders表是主表Q先和从表firmsq行左联接,再和从表productsq行左联接?/p>
判断是外联接中的主表q是从表主要看from从句中各个表在LEFT JOIN或RIGHT JOIN两边的位|:(x)LEFT JOIN左边的表是主表,RIGHT JOIN双的表是主表;
ON表达?jin)两个表q接的条Ӟ一般外联接是等D接,不等D接意义不大;
在多个表的连接中Q一个表既可以做主表又同时可以做从表Qؓ(f)?jin)说明这个问题,我们修改以上SQL为:(x)
select a.order_id, b.f_name, c.p_name from orders a left join firms b on a.firm_id = b.firm_id right join products c on a.order_id = c.p_id
q个SQL没有什么意义,但从中可以看出a表既是b的主表又是c的从表;到底怎么用,q是要根据实际情冉|军_是左联接q是双接;
那天Q看C(jin)q样一个例子:(x)
create table tab1 (c1 int, c2 int, c3 int) create table tab2 (c1 int, c2 int, c3 int) create table tab3 (c1 int, c2 int, c3 int) create table tab4 (c1 int, c2 int, c3 int) SELECT * FROM tab1 LEFT OUTER JOIN tab2 ON tab1.c3 = tab2.c3 left OUTER JOIN tab3 right OUTER JOIN tab4 ON tab3.c1 = tab4.c1 ON tab2.c3 = tab4.c3
q种用法q真见Q具体怎么个意思,q在理解?..我把它改写成Q?/p>
SELECT * FROM tab1 left JOIN tab2 ON tab1.c3 = tab2.c3 LEFT OUTER JOIN tab4 ON tab2.c3 = tab4.c3 RIGHT OUTER JOIN tab3 ON tab3.c1 = tab4.c1
也许它们是一个意思。我发现加个括号Q看的更清楚一些(它是个嵌套)(j)
SELECT * FROM tab1 LEFT OUTER JOIN tab2 ON tab1.c3 = tab2.c3 left OUTER JOIN (tab3 right OUTER JOIN tab4 ON tab3.c1 = tab4.c1) ON tab2.c3 = tab4.c3
?nbsp;外联接中 "ON + AND" ?nbsp;"ON + WHERE" 的区?/strong>
1、on条g是外联接时在生成临时表时使用的联l条Ӟ不论从表是确定D是NULLQ主表所有的值都?x)出玎ͼ?/p>
如果再加上and条gQ?nbsp;如果and条g引用的是主表的列Q则对结果毫无媄(jing)响,主表的所有纪录依然会(x)全部出现Q如果and条g引用的是从表的列Q则不符合条件的从表U录昄NULLQ?/p>
2、where条g是在临时表生成后Q再对(f)时表q行qo(h)的条件。(f)时表中的所有纪录都受媄(jing)响,不符合条件的U录被过滤出l果集;
3、示例:(x)
select a.module_id, a.name, b.module_name from fb_autocoding a left join fb_app_module b on a.module_id = b.module_id and b.module_internal_label <> 'LO'; select a.module_id, a.name, b.module_name from fb_autocoding a left join fb_app_module b on a.module_id = b.module_id where b.module_internal_label <> 'LO';
?nbsp;其他Joinq算
merge joinQ在处理其他联结之前Q先把相关两个表联结在一P
hash joinQ把一个表join到已l被执行qjoin的结果上Q?/p>
用括h变join的顺序:(x)
select catalog.item, catalog.item_color, product.item, color.color_name from catalog full outer join (product cross join color) on catalog.item = product.item and catalog.item_color = color.color_name;
Create Trigger TrackCustomerUpdates
On AppDta.dbo.Customer
For Insert,Update,Delete
As
Declare @InsertedCount Int
Declare @DeletedCount Int
Set @InsertedCount=(Select Count(*)From inserted)
Set @DeletedCount=(Select Count(*)From deleted)
If ( @InsertedCount>0)Begin
Insert Into AppDta.dbo.CustUpdLog
( CustID,
Action,
UpdUser,
UpdDateTime)
Select CustId,
Case
When( @DeletedCount>0)Then
'Update'
Else 'Insert'
End,
Current_User,
Current_TimeStamp
From inserted
End
Else If(@DeletedCount>0)Begin
Insert Into AppDta.dbo.CustUpdLog
( CustId,
Action,
UpdUser,
UpdDateTime)
select CustId,
'Delete',
Current_User,
Current_TimeStamp
From deleted
End
正如本例所C,无论何时Insert 或者Update 语句影响一个或者多行时Qinserted 临时表都有记录行。无Z时Delete 或者Update 语句影响一个或者多行时Qdeleted 临时表都有记录行。对于一个Update 语句Qdeleted 临时表有旧行Qinserted 临时表有新行。这个示例还反映?jin)触发器的另一个重要方面:(x)对于某个表的Update 或者Delete 操作Q即使该语句没有影响到行Q也Ȁz触发器 (也就是说没有满Where 子句的行)?触发器的存储q程应该预测q种可能性?/span>
不仅可以Z个表创徏多个触发器,而且q可以ؓ(f)一个表的同一个SQL 语句(例如Update 语句)创徏多个后触发器Q不能ؓ(f)同一个SQL 语句创徏多个前触发器。每一个新的Create Trigger 语句增加触发器到那些指定表和语句已有的触发器中。对于所创徏的多个触发器Q可以用pȝ存储q程sp_settriggerorder 来指定第一个被Ȁzȝ触发器和最后一个被Ȁzȝ触发器,而对于其他的触发器,则不能指定其Ȁz顺序,只能ql决定。这U触发器的特征不?x)引起Q何特D的问题。因为L可以实现各种动作作ؓ(f)正常的存储过E,q且按照要求的顺序从一个触发器中调用它们?br>
管触发器是一U存储过E,但是不能使用Execute 语句调用?/span>Q如果有希望׃n触发器和正常的存储过E的~码Q那么只需把共享代码放在存储过E中Q从触发器中调用它。如果一个触发器修改一个表Q那么这些修改可能会(x)Ȁzd一个触发器Q或者本w。在默认情况下,SQL Sever 允许q种嵌套的触发器调用深度?2层。虽然我们徏议允许嵌套的和叠代的触发器,但是可以使用pȝ存储q程止q么做。下面的语句在指定的数据库上防止叠代触发器:(x)
sp_dboption AppDta,`recursive triggers',`false'
Z(jin)在所有数据库中防止嵌套触发器调用(包括叠代调用)Q可以用下面的语句Q?br>sp_configure `nested triggers',0
前面以后触发器ؓ(f)例介l了(jin)触发器的基本内容Q下面再介绍一下前触发器的不同之处?span style="COLOR: rgb(255,0,0)">要创Z个前触发器必ȝInstead Of 昑ּ声明Q如下面的例子:(x)
create Trigger TrackCustomerUpdates
On AppDta.dbo.Customer
Instead Of Update
As
Insert Into AppDta.dbo.CustUpdLog
(CustId,
Action,
UpdUser,
UpdDateTime)
Select CustId,
‘Update’,
Current_User,
Current_TimeStamp
From inserted
与后触发器不同的是:(x)前触发器既可以在表又可以在视图上创徏Q但一条语句只能创Z个前触发器,因此Q前触发器不存在Ȁz顺序问?br>
触发器应用D例:(x)从当前数据库服务器的Shop表Insert操作同步到另一台服务器的Shop?br>
CREATE TRIGGER Trigger_SynShopForInsert1
ON dbo.Shop
FOR INSERT
AS
insert into OtherServer.dbo.shop
(
lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
)
select lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
from shop where lngShopID in (select lngshopid from inserted)
或者:(x)
CREATE TRIGGER Trigger_SynShopForInsert2
ON dbo.Shop
FOR INSERT
AS
insert into OtherServer.dbo.shop
(
lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
)
select lngShopID,strShopCode,strName,strShopName,strDescription,lngIndex
from inserted
See (tng)com.borland.dx.dataset.DataSetException (tng)error (tng)code: (tng) (tng)BASE+66 (tng)
(tng)
com.borland.dx.dataset.DataSetException: (tng)[Microsoft][SQLServer (tng)2000 (tng)Driver (tng)for (tng)JDBC]Error (tng)establishing (tng)socket. (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.dx.dataset.DataSetException.a(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.dx.dataset.DataSetException.throwException(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.dx.dataset.DataSetException.SQLException(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.dx.sql.dataset.Database.openConnection(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.jdbcx.metadata.DatabaseInfo.openConnection(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.jdbcx.metadata.e.run(Unknown (tng)Source) (tng)
(tng)
Chained (tng)exception: (tng)
(tng)
java.sql.SQLException: (tng)[Microsoft][SQLServer (tng)2000 (tng)Driver (tng)for (tng)JDBC]Error (tng)establishing (tng)socket. (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.base.BaseExceptions.createException(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.base.BaseExceptions.getException(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.base.BaseExceptions.getException(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.sqlserver.tds.TDSConnection.<init>(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.sqlserver.SQLServerImplConnection.open(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.base.BaseConnection.getNewImplConnection(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.base.BaseConnection.open(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.microsoft.jdbc.base.BaseDriver.connect(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)java.sql.DriverManager.getConnection(DriverManager.java:512) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)java.sql.DriverManager.getConnection(DriverManager.java:171) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.dx.sql.dataset.Database.openConnection(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.jdbcx.metadata.DatabaseInfo.openConnection(Unknown (tng)Source) (tng)
(tng)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)at (tng)com.borland.jdbcx.metadata.e.run(Unknown (tng)Source) (tng)
(tng)
是什么原因啊Q? (tng)
--------------------------------------------------------------- (tng)
(tng)
1、下载Microsoft (tng)SQL (tng)Server (tng)2000 (tng)Service (tng)Pack (tng)3aq安装,SQL请选用混和安装模式Q!Q? (tng)
http://www.microsoft.com/downloads/details.aspx?FamilyId=90DCD52C-0488-4E46-AFBF-ACACE5369FA3&displaylang=zh-cn (tng) (tng)
(tng) (tng) 解压~sp3的升U包?q要点击setup安装.才能成功升到sp3 (tng) (tng)
2、下载SQL (tng)Server (tng)2000 (tng)Driver (tng)for (tng)JDBC (tng)Service (tng)Pack (tng)3 (tng)
http://www.microsoft.com/downloads/details.aspx?FamilyId=07287B11-0502-461A-B138-2AA54BFDC03A&displaylang=en (tng)
(tng)
3、运行时关闭防火?br />