Março 10, 2010

Índices por Datas

Posted in SQL Server tagged às 22:31 por Henrry Pires

As datas são e serão sempre especiais, temos que ter atenção a elas quando se pesquisa, quando se insere / altera, e neste caso quando se cria um índice.

O que vou falar advém da minha experiência pessoal. Quando crio um índice por um campo data, normalmente ponho o mesmo como sendo descendente, porque e em que situações?

A razão que me leva a fazer isto é simples, normalmente os utilizadores querem / precisam ver os registos mais recentes, pelo que se estes estiverem no princípio do índice a pesquisa será mais rápida.

Agora, em que situações, vou dar um exemplo para me explicar melhor.

Imaginemos uma tabela de documentos, onde guardamos por exemplo facturas, desta tabela extraímos por exemplo extrair um balancete (ou parte da informação necessária para tal), conversão de facturas em outro tipo de documentos (guias de remessa, recibos, notas de crédito, etc.), este tipo de operações normalmente é efectuada com os documentos mais recentes.

Seguindo o raciocínio do exemplo anterior temos então que se os documentos mais recentes (os mais prováveis de serem pesquisados) estiverem no princípio do índice, a pesquisa será mais rápida.

Outubro 30, 2009

Comparando Strings

Posted in .NET Framework tagged às 22:50 por Henrry Pires

O que há de especial em comparar duas strings? Uma rápida vista de olhos na classe string pode-nos ajudar a perceber.

A classe string ao contrário da classe Int32 (por exemplo) é uma reference type. Mas em que é que isto afecta a comparação? Vejamos um exemplo de outra classe reference type. No código a seguir vou usar a classe DataTable, para demonstrar o problema existente na avaliação da igualdade dos reference type.

VB.Net

Dim dataTable1 = New DataTable()
Dim values(1) As Object

values(0) = "value1"
dataTable1.Columns.Add("Column1")
dataTable1.Rows.Add(values)

Dim dataTable2 As DataTable = dataTable1.Copy()

If dataTable1 = dataTable2 Then

C#

DataTable dataTable1 = new DataTable();

dataTable1.Columns.Add("Column1");
dataTable1.Rows.Add(new object[1] { "value1" });

DataTable dataTable2 = dataTable1.Copy();

if (dataTable1 == dataTable2)

Em VB.Net da erro de compilação.

“Operator ‘=’ is not defined for types ‘System.Data.DataTable’ and ‘System.Data.DataTable’.”

Em C# funciona, mas na realidade o que o compilador está a fazer é comparar as referências para o endereço de memória, ou seja estaríamos a fazer qualquer coisa como:

C#

if (object.ReferenceEquals(dataTable1, dataTable2))

Mas devido ao facto de a classe string fazer override do operador “=”,

a comparação entre duas variáveis do tipo string funciona, e funciona bem.

Ok, mas se a comparação funciona bem então, “O que há de especial em comparar duas strings?

Vamos então fazer algumas mudanças no código, desta vez só para os programadores de VB.Net

VB.Net

Option Compare Binary

Imports System.Windows.Forms

Module Module1

    Sub Main()

        Dim stringA, stringB As String

        stringA = “A"
        stringB = “a”

        If stringA = stringB Then
            MessageBox.Show(“As strings são iguais”, “Teste strings”, _
			MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        Else
            MessageBox.Show(“As strings não são iguais”, “Teste strings”, _
			MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End If

    End Sub

End Module

Neste caso, a comparação vai dar sempre falso porque estamos a definir o “Option Compare” como sendo “Binary” (que é o predefinido no C#). Então se não quisermos fazer distinção entre maiúsculas e minúsculas, o que podemos fazer?

A opção mais comum é por ambas as strings em maiúsculas (ou minúsculas) usando os métodos “ToUpper” ou “ToLower” da classe string.

Funciona? A resposta é sim, mas em termos de desempenho não será a mais adequada. Aqui entra um método da string, o “Compare”. Então teríamos o código da seguinte forma:

VB.Net

If String.Compare(stringA, stringB, True) = 0 Then

C#

if(string.Compare(stringA, stringB, true)== 0)

O que significa o parâmetro “True” e porque comparar o resultado com zero? Como neste caso queremos que ambas as strings (“A”, “a”) sejam iguais, vamos definir que deverá ser feita uma comparação Case Insensitive. O retorno com valor zero indica-nos que ambas as strings são iguais. No entanto existe ainda uma maneira mais correcta de isto ser feito.

VB.Net

If String.Compare(stringA, stringB, True, _
			 CultureInfo.GetCultureInfo("PT-pt")) = 0 Then

C#

if (string.Compare(stringA, stringB, true,
			 CultureInfo.GetCultureInfo("PT-pt")) == 0)

Conclusão

De modo a evitarmos problemas, ao comparar duas strings, convêm sempre usar o método “Compare” assim serão evitados os tais erros, “que só dão as vezes”, os tais muito difíceis de apanhar.