09/09/11

La paginazione in SQL Server 2008 e con la CTP3 di denali

Avete mai dovuto paginare i dati con SQL Server 2008 ?
bhè, è un'operazione abbastanza semplice grazie alle funzioni di ranking che il sistema ci mette a disposizione.... Tali funzioni consentono una numerazione arbitraria delle righe reperite dalla selezione e nel nostro caso uso la funzione row_number() over(order by campi da ordinare)

use  TempDb
Go

--Creao una tabella contenente le righe su cui effettuare la paginazione
Create table dbo.Paginata
(
 id int identity(0,1),
 Nome varchar(15) not null,
 Cognome varchar(20) not null
)

ALTER TABLE dbo.Paginata ADD CONSTRAINT
 PK_Paginata PRIMARY KEY NONCLUSTERED 
 (
 Nome,
 Cognome
 ) 

set nocount on
declare @i int = 0

--inserisco le righe
While @i < 100000
begin

 insert into Paginata (Nome,Cognome) 
  values('Nome ' + cast(@i as varchar(8)), 'Cognome ' + cast(@i as varchar(8)));
 set @i = @i + 1

end


--Ricerco la centesima pagina
declare @pagenumber int= 100

--Ogni pagina mi restituisce 10 righe
declare @pagesize int = 10

SELECT TOP (@pagesize) * FROM 
(
 SELECT row_number() over(order by Nome,Cognome) as RowNumber,
  *
 FROM  Paginata
)as A
WHERE RowNumber > ((@pagenumber - 1) * @pagesize)

Con la nuova versione SQL Server (ora sto provando la CTP3) il giochino sarà ancora più semplice !!
--Ricerco la centesima pagina
declare @pagenumber int= 100

--Ogni pagina mi restituisce 10 righe
declare @pagesize int = 10

Select * from Paginata
 order by Nome,Cognome
 OFFSET ((@pagenumber - 1) * @pagesize)  ROWS 
    FETCH NEXT @pagesize ROWS ONLY; 

La sintassi dell'order by ora prevede le clausole Offset e Fetch next che consentono di implementare la paginazione senza utilizzare funzioni di ranking !!!!

Cercare una stringa in un database...

Vi è mai capitato di dover cercare una stringa specifica all'interno del database senza conoscerne la struttura ? A me si e per evitare di farmi migliaia di select a mano ho creato un piccolo script che mi aiuta in modo molto efficace nella ricerca....
Utilizzo le viste information_schema che restituiscono la struttura del Db.
Vediamo come ho fatto :



--non voglio ricevere informazioni sul numero di righe selezionate
Set NoCount On

--Dichiarazione variabile contenente la stringa da ritrovare
Declare @strToFind varchar(max) = 'Luca'

--Dichiarazione variabili d'appoggio
Declare @strSchema sysname = ''
Declare @strTab sysname = ''
Declare @StrFieldsList varchar(Max) = ''
Declare @StrWhereFieldsList varchar(Max) = ''
Declare @strSql varchar(max) = ''

--variabile tabella contenente la le tabelle e i campi testuali
Declare @Tabs table(
TABLE_SCHEMA sysname
,TABLE_NAME sysname
)

Insert into @Tabs
Select Distinct TABLE_SCHEMA,TABLE_NAME from INFORMATION_SCHEMA.COLUMNS
Where DATA_TYPE in ('char','nchar','varchar','nvarchar','text','ntext')
Order by TABLE_SCHEMA,TABLE_NAME

--Fino a che ci sono righe nella variabile tabella
While 1=1
Begin

--operazioni preliminari per formattare la select di ricerca
Set @StrFieldsList = ''
Set @StrWhereFieldsList = ''

Select Top 1 @strSchema = TABLE_SCHEMA, @strTab=TABLE_NAME from @Tabs
Order by TABLE_SCHEMA,TABLE_NAME;

--Se la variabile tabella non mi ha restituito la prima riga esco dal ciclo
--perchè ho esaurito le tabelle su cui implementare la ricerca
IF @@ROWCOUNT=0
Break;

--Formatto la stringa per ricercare il mio dato
With Fields
AS
(
Select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS
Where DATA_TYPE in ('char','nchar','varchar','nvarchar','text','ntext')
And TABLE_SCHEMA = @strSchema
And TABLE_NAME = @strTab
)
Select @StrFieldsList = @StrFieldsList + '' + QUOTENAME(COLUMN_NAME) + ' AS ' + QUOTENAME(COLUMN_NAME) + ',',
@StrWhereFieldsList = @StrWhereFieldsList + QUOTENAME(COLUMN_NAME) + ' Like ''%' + @strToFind + '%'' OR '
From Fields

Set @strSql = 'Select ''' + QUOTENAME(@strSchema) + ''' As Table_Schema,''' + QUOTENAME(@strTab) + ''' As Table_Name, ' + Substring(@StrFieldsList,0,LEN(@StrFieldsList))
+ ' from ' + QUOTENAME(@strSchema) + '.' + QUOTENAME(@strTab)
+ ' Where ' + Substring(@StrWhereFieldsList,0,LEN(@StrWhereFieldsList)-2)

--eseguo il comando di ricerca appena generato
Exec(@strSql)

-- elimino la riga relativa alla tabella appena elaborata
-- dalla tabella temporanea
Delete From @Tabs
Where TABLE_SCHEMA = @strSchema
And TABLE_NAME = @strTab

end

01/09/11

Compare two collections with Linq and method Except

Suppose to have two collections of objects and you want to get the objects of the first collection that are not included in the second collection, you can use Linq with the method "Except".

Let's show a simple example:


            double[] numbers1 = { 2.0, 2.1, 2.2, 2.3, 2.4, 2.5 };
            double[] numbers2 = { 2.2 };

            IEnumerable onlyInFirstSet = numbers1.Except(numbers2);
Now onlyInFirstSet will contains only numbers that are not present in the secondo collection.

You can get the inverse calling the method Expect on the collection numbers2 and passing the parameter numbers1.

Remember that If you want to compare sequences of objects of some custom data type, you need to implement che interface IEquatable<T> where T is your object.

This interface require to implement the methods Equals and GetHashCode.
In the method Equals you define the logic that let the program to know when two object are equals.

In the method GetHashCode you implement the hash code: it is a numerical value that is tied to a fixed input and it is a form of one-way encryption, let you uniquely identifying an object.

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Grants For Single Moms