发现一个SQLSERVER数据库的编绎解析问题

今天捧读SQLSERVER圣经联机帮助,设计SQL SERVER 2000复制时出现下面的问题,最后得出结论是SQL 数据库引擎不能正确的解析或者说不是时候的解析。
 
1. 创建复制表:
-- 在发布服务器上创建表sales:
CREATE   TABLE  sales 
(sale_id 
INT   IDENTITY ( 1 , 1
    
NOT   FOR   REPLICATION,
sales_region  VARCHAR ( 20 ),
CONSTRAINT  id_pk  PRIMARY   KEY  (sale_id)
)

-- 在订阅服务器上创建表sales:
CREATE   TABLE  sales 
(sale_id 
INT   IDENTITY ( 100001 , 1
    
NOT   FOR   REPLICATION
sales_region 
VARCHAR ( 2 ),
CONSTRAINT  id_pk  PRIMARY   KEY  (sale_id)
)
 
2. 建立事务复制,不可更新的订阅,其它都采用默认设置,只改发布属性“名称冲突”为“删除现有表中与行筛选语句相匹配的数据”,以防删除手工建立的表及标识列规则。在服务器插入新数据或删除旧数据时都正确,但修改数据时出错:
A.错误消息:{CALL sp_MSupd_sales (NULL,'afg2342342',2, 0x02)}
上一次执行批处理的事务序列号和命令 ID 分别是 0x0000006100000082000500000000 和 1。
B.上一条命:无法更新标识列 'sale_id'。
C.错误详细信息:无法更新标识列 'sale_id'。
(源: DEV1 (数据源); 错误代码: 8102)

3. 复制自动创建的订阅服务器的存储过程如下,我对错误处做了注释:
create   procedure  "sp_MSupd_sales" 
 
@c1   int , @c2   varchar ( 20 ), @pkc1   int
,
@bitmap   binary ( 1 )
as
if   substring ( @bitmap , 1 , 1 &   1   =   1      -- 条件为否时,应执行ELSE语句块
begin
update  "sales"  set
"sale_id" 
=   case   substring ( @bitmap , 1 , 1 &   1   when   1   then   @c1   else  "sale_id"  end     -- 其语法完全没有问题,存储过程已创建好,标识列是不能更新的,由于@bitmap=0x02,不应该执行该语句块,但是该语句既然分析正确而且不会执行,仍然还在在执行时进行解析,???
,"sales_region"  =   case   substring ( @bitmap , 1 , 1 &   2   when   2   then   @c2   else  "sales_region"  end
where  "sale_id"  =   @pkc1
if   @@rowcount   =   0
 
if   @@microsoftversion > 0x07320000
  
exec  sp_MSreplraiserror  20598
end
else
begin
update  "sales"  set
"sales_region" 
=   case   substring ( @bitmap , 1 , 1 &   2   when   2   then   @c2   else  "sales_region"  end
where  "sale_id"  =   @pkc1
if   @@rowcount   =   0
 
if   @@microsoftversion > 0x07320000
  
exec  sp_MSreplraiserror  20598
end
GO
 
最后得出一个结论:不是复制组件的问题,问题出在 数据库引擎不能正确的解析或者说不是时候的解析,简单的试试下面的代码(先分析后执行):
CREATE   TABLE  Test 
(
    ID 
INT   IDENTITY ( 1 , 1 NOT   FOR   REPLICATION
    Content 
VARCHAR ( 20 ),
    
CONSTRAINT  id_pk  PRIMARY   KEY  (ID)
)
GO
if   1 = 0
begin
    
print   ' It can not be. '
    
update  Test  set  ID = ID, Content = Content     --where 1=0
end
else
begin
    
print   ' Right. '
    
update  Test  set  Content = Content
end

你可能感兴趣的:(sqlserver)