当前位置: 首页 > 图文教程 > 数据库 > MSSQL > SQL Server使用Merge语句当源表数据集为空时,无法进行查询的问题

MSSQL
MS SQL SERVER2005 XML 最佳实践
SQL Server对文件进行全文检索的查询
教你构建SQL Server可管理安全机制
维护SQL Server的交易日志经验总结
SQL SERVER 2005 EXPRESS不能远程连接的问题
SQL Server与Oracle并行访问本质区别
SQL Server数据库优化其索引的小技巧
分析及解决SQLServer死锁问题
用SQL Server为Web浏览器提供图像
SQL Server SQL Agent服务使用小结
SQL Server 存储过程的分页方案比拼
SQL Server数据库中存储引擎深入探讨
四招解决SQL Server对上亿表的排序和join的问题
SQL Server数据库管理员必须掌握的DBCC命令
如何将sql数据库的文件备份到本地?
如何解决Sybase数据库乱码问题详解
SQL Server:SQLServer中最小函数依赖集
小编谈Transact-SQL中的一些命名规范
谈SQL编写规范
浅谈SQL命名与注释规范

MSSQL 中的 SQL Server使用Merge语句当源表数据集为空时,无法进行查询的问题


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 66 ::
收藏到网摘: n/a

今天使用Merge语句时遇到了一个问题,当源表数据集为空时,merge就不工作了。

面举一个例子来具体说明一下:
有两个表SourceTable为登陆表,TargetTable为授权表,如果访问用户在登陆表中,更新授权表的授权级别,否则授权0表示游客。sql语句如下:
--SourceTable为登陆表,TargetTable为授权表
--如果访问用户在登陆表中,更新授权表的授权级别,否则授权0表示游客。
create table SourceTable(UserName nvarchar(10),Pwd int,[Level] int)
create table TargetTable(UserName nvarchar(10),[Level] int)
go
--下面是SQL Server2008新增的赋值功能,更多新功能请参见
insert into SourceTable values('user1','111',1),('user2','222',2),('user3','333',3)
insert into TargetTable values('user1',1),('user2',2)
一般情况,我们会写如下的语句:

复制代码 代码如下:

declare @UserName varchar(10) = 'user2'--表示某个登陆的用户名
merge into TargetTable as tg
using (select UserName,[Level] from SourceTable where UserName=@UserName)
as sr(UserName,[Level]) on tg.UserName=sr.UserName
when matched then
update set [Level]=sr.[Level]--更新授权级别
when not matched by target then
insert (UserName,[Level]) values(@UserName,0)--表示游客
output $action;

执行结果为UPDATE,表示执行了更新操作,也正是我们想要的。
但是如果我们把@UserName赋值为'user6',希望能在TargetTable中插入一条记录,但是实际执行结果为空,显示什么都没执行。原因就是using (select UserName,[Level] from SourceTable where UserName=@UserName) as sr(UserName,[Level]) on tg.UserName=sr.UserName这个语句中,sr结果集为空,所以merge语句就不向后执行了,不知道这是不是SQL Server的bug。
下面的SQL可以解决上面的问题:
复制代码 代码如下:

declare @UserName varchar(10) = 'user7'--表示某个登陆的用户名
merge into TargetTable as tg
using (select @UserName)
as sr(UserName) on tg.UserName=sr.UserName
when matched then
update set [Level]= (select top 1 [Level] from SourceTable where UserName=@UserName)
--更新授权级别
when not matched by target then
insert (UserName,[Level]) values(@UserName,0)--表示游客
output $action;