Mi è capitato tempo fa di imbattermi in uno strano comportamento di SQL Server 2008: improvvisamente una view, che nel corso degli anni aveva subito diverse modifiche, è regredita a una versione molto vecchia.
Mi sono arrovellato il cervello nel tentativo, inutile, di cercare una spiegazione al fenomeno, finché esso non si è recentemente manifestato di nuovo e in circostanze fortunate: stavo eseguendo delle operazioni di manutenzione su un database, ed avevo quindi buone possibilità di riprodurre il problema in modo controllato.
Ho ripristinato il database da un backup, e ho rieseguito i pochi comandi impartiti, finché si è manifestato il problema.
Sono così giunto a scoprire che SQL Server 2008 espone un pericoloso bug legato all’uso delle stored procedure di sistema sp_rename e sp_refreshview.
Il problema è già stato isolato e descritto da Davide Mauri.
Riporto qui i dettagli del test che consente di riprodurlo.
Creiamo una view:
create view dbo.a as select c = 1 go
Adesso rinominiamola usando sp_rename:
exec sp_rename 'a', 'b' go
Ricreiamola:
create view dbo.a as select c = 2 go
Testiamo, per adesso tutto perfetto:
select * from dbo.a select * from dbo.b go c ----------- 2 (Righe interessate: 1) c ----------- 1 (Righe interessate: 1)
Ed ora diamo fuoco alle polveri. Eseguiamo sp_refreshview su b:
sp_refreshview 'dbo.b' go
Testiamo di nuovo:
select * from dbo.a select * from dbo.b go c ----------- 1 (Righe interessate: 1) c ----------- 1 (Righe interessate: 1)
Facendo il refresh di ‘b’, la definizione di ‘a’ è regredita! Verifichiamo:
sp_helptext 'dbo.a' go Text ----------------------------------------------------------------------------------- create view dbo.a as select c = 1
Mauri afferma di aver testato e rilevato il bug in SQL Server 2005, 2008 e 2008 R2. Io personalmente ho potuto verificarlo su SQL Server 2008 SP4.
Come workaround si suggerisce quanto segue:
- Dopo aver eseguito sp_rename, eseguire una ALTER VIEW manuale sulla view ridenominata:
alter view dbo.b as select c = 1 go
- Evitare di usare sp_rename sulle view. Attenzione: SSMS invoca sp_rename dietro le quinte quando si rinomina una view dalla GUI.
Buon lavoro a tutti e… occhi aperti!