Ieri in "[NHibernate] e l'importanza dei parametri precisi!" avevo sollevato il problema della difficoltà nel definire correttamente i parametri stringa in NHibernate... leggendo meglio la documentazione ho scoperto l'esistenza di tipi built-in già pronti - beh avrei dovuto sospettarlo che non potevano aver trascurato un problema simile.
Tornando quindi all'esempio di ieri la corretta definizione del nostro campo CHAR(5) è la seguente:
<ID column="CODICE" name="Codice" type="AnsiString(5)"><GENERATOR class=assigned /></ID>
Quindi riassumendo: 
- Se si ha una colonna CHAR(n) o VARCHAR(n)  dove n > 1 occorre definire esplicitamente il type AnsiString(n). Se abbiamo un CHAR(1) possiamo usare AnsiChar; 
- Se si ha una colonna NCHAR(n) o NVARCHAR(n) dove n > 1 occorre definire il type String(n). Se abbiamo un NCHAR(1) possiamo usare Char. Se la proprietà è stringa "String" è il valore di default quindi è da usare esplicatemente se vogliamo specificarne la lunghezza.
Vediamo di fare un esempio. 
CREATE TABLE [dbo].[Sheet1$]
(
 [Codice] [char](5) NOT NULL,
 [Descrizione] [nvarchar](255) NOT NULL,
 CONSTRAINT [PK_Sheet1$] PRIMARY KEY CLUSTERED ([Codice] ASC)
)
Riempiamo le tabella con qualche migliaio di elementi e facciamo qualche query controllando l'execution plan.
exec sp_executesql N'SELECT Codice, Descrizione FROM Sheet1$ WHERE codice = @p0', 
N'@p0 nvarchar(5)', 
@p0 = N'90001'
exec sp_executesql N'SELECT Codice, Descrizione FROM Sheet1$ WHERE codice = @p0', 
N'@p0 varchar(5)', 
@p0 = '90001'
exec sp_executesql N'SELECT Codice, Descrizione FROM Sheet1$ WHERE codice = @p0', 
N'@p0 char(5)', 
@p0 = '90001'
Che sono verosimilmente quelle eseguite da NHIbernate usando il paramentro @P definito prima String - Unicode - e poi AnsiString - ANSI.

 Come si vede in un caso viene eseguito uno SCAN sull'indice... nel secondo caso viene fatto una più performante SEEK, rimando a "scan VS seek" la spiegazione dei due predicati di ricerca. La cosa interssante è che il PLANNING NON VARIA se definiamo la lunghezza del parametro non precisa - esempio "@p VARCHAR(4000)" - ... l'importante quindi è definire correttamente il tipo. Beh tutto bene quel che finisce bene!
 Come si vede in un caso viene eseguito uno SCAN sull'indice... nel secondo caso viene fatto una più performante SEEK, rimando a "scan VS seek" la spiegazione dei due predicati di ricerca. La cosa interssante è che il PLANNING NON VARIA se definiamo la lunghezza del parametro non precisa - esempio "@p VARCHAR(4000)" - ... l'importante quindi è definire correttamente il tipo. Beh tutto bene quel che finisce bene!
		
			posted @ sabato 20 gennaio 2007 00:14