Newsgroup: it.comp.lang.visual-basic
Titolo: Prossimo codice

In SQL server 2000 ho una query:
SELECT CODICE FROM CLIENTI
ORDER BY CODICE
il set di risultati è il seguente:
000001
000002
000004
000005
000008
000009
000010
Che funzione posso utilizzare per propormi il prossimo codice libero?
Ad esempio una query che mi dia per risultato
000003
Poi una volta inserito il codice 000003 rieseguendo la query mi deve
proporre: 000006 e così via.
Grazie

 000003
Premesso che operare in questo modo è a rischio in ambienti multiutenza, se
non gestisci i lock, diciamo che una query che funziona potrebbe essere (se
codice è numerico, altrimenti devi fare qualche Cast as Numeric):
Select top 1 a.codice+1
from Clienti as a
left outer join Clienti as b
on a.codice=b.codice-1
where b.codice is null
order by a.codice asc
Scritta a braccio e non verificata, ma dovrebbe andare.
Ciao
Alberto

 Scritta a braccio e non verificata, ma dovrebbe andare.
mmmm, il record NON esiste, quindi non è "neppure" null, penso...


No, la query di Albe è corretta :-)
USE tempdb
GO
/* Definisco la tabella dbo.Clienti */
CREATE TABLE dbo.Clienti(
Codice char(6) NOT NULL
)
GO
/* La popolo */
SET NOCOUNT ON
INSERT dbo.Clienti VALUES('000001')
INSERT dbo.Clienti VALUES('000002')
INSERT dbo.Clienti VALUES('000004')
INSERT dbo.Clienti VALUES('000005')
INSERT dbo.Clienti VALUES('000008')
INSERT dbo.Clienti VALUES('000009')
INSERT dbo.Clienti VALUES('000010')
SET NOCOUNT OFF
GO
/* Query */
SELECT TOP 1 a.codice + 1 Gap
FROM dbo.Clienti AS a
LEFT OUTER JOIN Clienti AS b
ON a.codice = b.codice - 1
WHERE b.codice IS NULL
ORDER BY a.codice ASC
GO
/* Output:
Gap
----------- 
3
(1 row(s) affected)
*/
/* Inserisco il codice 000003 */
INSERT dbo.Clienti VALUES('000003')
GO
/* Query */
SELECT TOP 1 a.codice + 1 Gap
FROM dbo.Clienti AS a
LEFT OUTER JOIN Clienti AS b
ON a.codice = b.codice - 1
WHERE b.codice IS NULL
ORDER BY a.codice ASC
GO
/* Output:
Gap
----------- 
6
(1 row(s) affected)
*/
/* Inserisco il codice 000006 */
INSERT dbo.Clienti VALUES('000006')
GO
/* Query */
SELECT TOP 1 a.codice + 1 Gap
FROM dbo.Clienti AS a
LEFT OUTER JOIN Clienti AS b
ON a.codice = b.codice - 1
WHERE b.codice IS NULL
ORDER BY a.codice ASC
GO
/* Output:
Gap
----------- 
7
(1 row(s) affected)
*/
/* Inserisco il codice 000007 */
INSERT dbo.Clienti VALUES('000007')
GO
/* Query */
SELECT TOP 1 a.codice + 1 Gap
FROM dbo.Clienti AS a
LEFT OUTER JOIN Clienti AS b
ON a.codice = b.codice - 1
WHERE b.codice IS NULL
ORDER BY a.codice ASC
GO
/* Output:
Gap
----------- 
11
(1 row(s) affected)
*/
/* Pulizia */
DROP TABLE dbo.Clienti
Una query alternativa potrebbe essere:
SELECT TOP 1 C1.Codice + 1 Gap
FROM dbo.Clienti C1
WHERE NOT EXISTS(
    SELECT *
    FROM dbo.Clienti C2
    WHERE C2.Codice = C1.Codice + 1
)
ORDER BY C1.Codice
GO
Ma la soluzione di Albe è + elegante e dando uno sguardo al query plan +
efficiente :-)
-- 
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://mvp.support.microsoft.com
http://italy.mvps.org


E' un Left Outer Join.
Se il record non esiste viene 'simulato' con tutti Null.
Ciao
Alberto
-- 
"Tina, ta te tòta tinta un tac!"
"Te cat tac i tac, m'tac't un tac?"
"Me ca tac un tac a tè?
Tac'tel te l tò tac, tò!"

 Se il record non esiste viene 'simulato' con tutti Null.
Però!  :-))