Enjoy Your SQL bad practice - Francesco Quaratino

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

Comments

No Comments