bad practice
Oltre alle "best practice" bisognerebbe ricordarsi delle "bad practice"... naturalmente per starvi alla larga.
Eccono una che può provocare non poco danni, la quale coinvolge la sp_executesql e @@identity, comunemente usata per recuperare l'ultimo valore identity inserito in una tabelle..dimenticandosi dell'esistenza della funzione scope_identity():
use
tempdb
go
if
object_id('t1') is not null
drop table t1;
create table t1 ( id int identity, col1 int not null );
go
declare
@t as table ( id int identity (1,1), col1 char(1) );
insert
@t (col1) values ('A');
declare
@id bigint, @sql_string nvarchar(max), @params_def nvarchar(max);
set
@sql_string = N'INSERT INTO t1 (col1) VALUES (@col1); SELECT @Id=@@IDENTITY;';
set
@params_def = N'@col1 int, @Id int OUTPUT';
exec sp_executesql @sql_string, @params_def, NULL, @id OUTPUT
if @@ERROR <> 0
select 'Error!';
-- @@ERROR è uguale a zero (0) poichè l'ultima istruzione eseguita
-- è la "SELECT @id=@@IDENTITY" e non la "INSERT ...."
select last_identity_inserted = @id;
-- @@IDENTITY restituisce l'ultimo identity, ovvero quello della "@t"
-- anche se la insert t1 si conclusa con un errore
go
/* Questa invece è una versione corretta */
declare
@t as table ( id int identity (1,1), col1 char(1) );
insert
@t (col1) values ('A');
declare
@id bigint, @sql_string nvarchar(max), @params_def nvarchar(max);
set @sql_string = N'INSERT INTO t1 (col1) VALUES (@col1); SELECT @Id=SCOPE_IDENTITY();';
set
@params_def = N'@col1 int, @Id int OUTPUT';
-- TRY..CATCH is better !!!
begin
try
exec sp_executesql @sql_string, @params_def, NULL, @id OUTPUT
end
try
begin
catch
select 'Error!';
end
catch
-- SCOPE_IDENTITY is better !!!
select
last_identity_inserted = @id;
go