SQL Server ed ALM su database


Il blog di Alessandro Alpi
Archivio Posts
Anno 2018

Anno 2017

Anno 2016

Anno 2015

Anno 2014

Anno 2013

Anno 2012

Anno 2011

Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

Non Equi Join. Ricavare il primo "buco" di un campo contatore

Quante volte è capitato di voler "riempire i buchi" lasciati da un campo contatore? In effetti, una volta definito un identity, non dovremmo preoccuparci di una problematica di questo tipo, però può accadere di avere un campo numerico che non deve assolutamente lasciare "buchi".. Potrebbero esistere campi gestiti come progressivi i quali, dopo varie cancellazioni fisiche, lasciano spazi nel conteggio.

Ecco, in quei casi è utile ricavare il primo spazio in cui inserire il nostro contatore/progressivo applicativo..

Scenario:

Ho una tabella di anagrafica della mia azienda (alcuni dipendenti ) e ho la necessità di inserire i nuovi dipendenti nel primo "buco" lasciato libero dai licenziamenti di dipendenti precedenti. Quindi, devo fornire qualcosa che mi dica quale spazio posso riempire:

IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('TabellaContatori'))
 DROP TABLE TabellaContatori

-- creo la tabella con un campo intero che sarà il nostro contatore applicativo
---------------------------------------------------------------------------------
CREATE TABLE TabellaContatori
(
 Id int NOT NULL,
 Nome varchar(30) NOT NULL,
 Cognome varchar(30) NOT NULL,
 Eta tinyint NOT NULL,
 CONSTRAINT PK_TabellaContatori PRIMARY KEY CLUSTERED
 (
  Id
 )
)

-- inserisco nella tabella alcuni record con contatori non seguenti
---------------------------------------------------------------------------------
INSERT INTO TabellaContatori
SELECT 1,'Alessandro','Alpi', 25

INSERT INTO TabellaContatori
SELECT 2,'Alex','Rabboni', 23

INSERT INTO TabellaContatori
SELECT 5,'Marco','Rossi', 25

INSERT INTO TabellaContatori
SELECT 6,'Michael','Denny', 23

INSERT INTO TabellaContatori
SELECT 8,'Matteo','Celaschi', 28

INSERT INTO TabellaContatori
SELECT 9,'Davide','Manuto', 24
---------------------------------------------------------------------------------

-- Ricavo il primo contatore seguente e lo inserisco (ovviamente il tutto si può
-- strutturare con variabili e transazioni)
---------------------------------------------------------------------------------
SELECT
 TOP 1 IdDaInserire = TC1.Id + 1
FROM
 TabellaContatori TC1
LEFT JOIN
 TabellaContatori TC2
ON TC2.id = TC1.Id + 1
WHERE
 TC2.id IS NULL

INSERT INTO TabellaContatori
SELECT 3,'Daniele','Zanella', 32
---------------------------------------------------------------------------------

---------------------------------------------------------------------------------
SELECT
 TOP 1 IdDaInserire = TC1.Id + 1
FROM
 TabellaContatori TC1
LEFT JOIN
 TabellaContatori TC2
ON TC2.id = TC1.Id + 1
WHERE
 TC2.id IS NULL

INSERT INTO TabellaContatori
SELECT 4,'Massimo','Preitano', 44
---------------------------------------------------------------------------------

---------------------------------------------------------------------------------
SELECT
 TOP 1 IdDaInserire = TC1.Id + 1
FROM
 TabellaContatori TC1
LEFT JOIN
 TabellaContatori TC2
ON TC2.id = TC1.Id + 1
WHERE
 TC2.id IS NULL

INSERT INTO TabellaContatori
SELECT 7,'Luca','Ferrari', 26

Come già indico in un commento interno è possibile ottimizzare l'utilizzo di questo codice tramite l'utilizzo di transazioni e di variabili, in modo da crearsi una stored procedure che in automatico inserisce i dati nella prima "locazione" disponibile, con la possibilità di gestione delle contention e dei vari errori.

Oppure è possibile farsi una User Function, che ritorna solo il primo spazio libero..

Insomma, tutto questo lo lascio a voi

Stay tuned!

Categoria: SQL Server 2005
venerdì, 09 mar 2007 Ore. 10.10
Statistiche
  • Views Home Page: 599.573
  • Views Posts: 1.065.671
  • Views Gallerie: 637.597
  • n° Posts: 484
  • n° Commenti: 273



















Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003