今天同仁系統發生錯誤訊息,該段語法是透過Linked Server去另一台Server抓取一張Table的資料。結果發生了
訊息 7347,層級 16,狀態 1,行 20
連結伺服器 '127.0.0.1' 的 OLE DB 提供者 'MSOLEDBSQL' 傳回與資料行 '[127.0.0.1].[dbtemp].[dbo].[vwtb1].cname' 應有資料長度不符的資料。(最大) 資料長度應該為 10,而傳回的資料長度為 13。
的錯誤。
測試的Demo Code如下
--建立一資料表tb1
Create Table tb1(id int,cname varchar(10));
GO
--建立名為vwtb1的View,很單純Select tb1
Create View vwtb1
AS
Select * From tb1;
GO
--加長cname欄位到20
Alter Table tb1 Alter Column cname Varchar(20);
GO
--寫入一筆cname長度13的資料進入tb1
Insert Into tb1(id,cname) Values(1,'0123456789ABC');
GO
--透過linked Server 來Select vwtb1
Select * from [127.0.0.1].[dbtemp].[dbo].[vwtb1];
GO
發生錯誤如下圖

發生原因為建立View的當下MSSQL以將該View的Schema資訊記錄起來,一旦我們後續修改Base Table的Schema後沒有ReFresh跟該Table相關物件,在某些情境下就會發生因為實際Schema跟系統紀錄的不一致而產生的錯誤訊息。
解法就是一旦有Table的Schema被異動了,就同時用sp_refreshsqlmodule一併更新相依的物件,這樣MSSQL就會更新相關資訊了。
--用sp_refreshsqlmodule更新相依的物件
sp_refreshsqlmodule 'vwtb1';
GO
--透過linked Server 來Select vwtb1
Select * from [127.0.0.1].[dbtemp].[dbo].[vwtb1];
GO
如下圖,完成sp_refreshsqlmodule後再Select一次就能成功存取。

我是ROCK
rockchang@mails.fju.edu.tw