今天捧讀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