Ho una query SQL che fa diverse cose contemporaneamente¹: fa più controlli e poi, se i controlli passano, aggiorna alcuni dati. Senza entrare nei dettagli specifici del dominio, ecco un esempio immaginario:
-- The user password should be updated only if the user account is not removed and
-- not locked, and the threshold was not exceeded.
if exists (select * from [People].[User] where [UserId] = @UserId)
begin
if exists (select * from [People].[User] where [UserId] = @UserId and [IsLocked] = 0)
begin
if exists (select * from [People].[User]
where [UserId] = @UserId and [IsRemoved] = 0)
begin
update [People].[User] set [PasswordHash] = @Hash where [UserId] = @UserId
select 0 -- Success.
end
else
begin
select 3 -- The account doesn't exist any longer.
end
end
else
begin
select 2 -- The account is locked.
end
end
else
begin
select 1 -- The user cannot be found.
end
La query viene quindi utilizzata in questo modo:
var errorCode = new SqlDataQuery(query, Program.ConnectionString)
.With(new { UserId = this.Id, Hash = this.ComputeHash() })
.ReadValue<int>();
// Error codes are used only between the database and code, and transformed into exceptions
// as soon as possible.
switch (errorCode)
{
case 1: throw new UserNotFoundException();
case 2: throw new AccountPermissionException();
case 3: throw new AccountRemovedException();
}
Nella programmazione generale, i codici di errore sono considerati negativi e dovrebbero essere sostituiti da procedure convenzionali di gestione degli errori, incluse le eccezioni.
È anche cattivo utilizzarli nelle query SQL? Se sì, come dovrei riscrivere la query per seguire le best practice?
¹ Dati i requisiti non funzionali relativi al carico e alle prestazioni, non c'è modo di fare più query consecutive. Tutti i controlli e l'aggiornamento devono essere eseguiti in una singola query.