Mostrando postagens com marcador SQL Server. Mostrar todas as postagens
Mostrando postagens com marcador SQL Server. Mostrar todas as postagens

21 de jul. de 2011

Fonética + SQL Server

1

fonética
(francês phonétique)

s. f.

1. [Linguística]  Parte da linguística que trata dos sons articulados, considerados do ponto de vista físico, acústico e articulatório, como elementos dos vocábulos.

Essa é a definição do dicionário, mas basicamente a fonética é um "ramo" que estuda a pronuncia de uma palavra, visto que há diferenças entre a escrita e a pronuncia. Por exemplo, quantas maneiras podemos escrever o nome Wilham?

Wilian, Willian, Uyliam… Ainda mais no Brasil, e por falar nisso aqui há uma "limitação", a fonética é fortemente vinculada a língua. No brasil o som da letra "i" é um, nos EUA é outro… Ai!

Voltando aos nomes, no exemplo citado o som pode ser "fielmente" definido como "uiliam", então, na teoria, teríamos que bolar algum algoritmo para gerar o fonema da palavra, e nesse caso, independente da maneira como o nome for escrito, o resultado fonético seria o mesmo.

Complicado não!? Mas a boa notícia é que existem inúmeros estudos para gerar essa solução. Um deles é o Soundex. Criado em 1918, por Robert C. Russell e Margaret K. Odell. Esse algoritmo gera uma chave baseada na primeira letra e três números, "calculados" pelas letras na sequencia. Nesse algoritmo, o nosso Willian, viraria W450, e suas variações também.

O SQL Server já implementa nativamente o Soundex. Veja os exemplos a seguir:

2

Mas como "alegria de pobre dura pouco"… Há alguns poréns, primeiramente o Soundex é um algoritmo que funciona muito bem com a língua inglesa. Como disse anteriormente a fonética é extremamente ligada a sua língua. Palavras compostas e alguns casos da língua portuguesa não se dão muito bem com essa implementação do Soundex. Veja:

3

Vamos superar esse #mimimi!? Primeiramente vamos implementar o Soundex em C# e depois implementar adaptações necessárias para a nossa língua.

A base para isso foi tirada da revista Mundo .NET número 26, Casos de sucesso – Pesquisa Fonética em português; Tribunal de Justiça de Mato Grosso do Sul. Nesse caso o tribunal tinha problemas em localizar pessoas no sistema pelo nome. Antes da solução era preciso de informar o nome exato para o sistema buscar as informações.

Vamos definir alguns métodos para a implementação básica do Soundex:

    // -> Obtem o soudex de uma string
private static string GetSoundex(string value)
{
value = value.ToUpper(); // -> Normaliza letras em Maiuscula
var result = new StringBuilder();

foreach (char item in value)
if (char.IsLetter(item)) // -> Limpa String
AddCharacter(result, item); // -> Adiciona um char Soudex

// -> Limpa as exceções geradas
result.Replace(".", string.Empty);
// -> Arruma o tamanho no padrão soudex
// 4 caracteres.
FixLength(result);

return result.ToString();
}

// -> Preenche com 0 nos casos menor q quatro,
// ou pega os 4 primeiros caracteres.
private static void FixLength(StringBuilder result)
{
var length = result.Length;

if (length < 4)
result.Append(new string('0', 4 - length));
else
result.Length = 4;
}

// -> Adiciona o caractere soudex, cuidando para não repetir.
private static void AddCharacter(StringBuilder result, char item)
{
if (result.Length == 0)
{
result.Append(item);
}
else
{
var code = GetSoundexDigit(item);

if (code != result[result.Length - 1].ToString())
result.Append(code);
}
}

// -> Algoritmo de substituição padrão Soudex.
private static string GetSoundexDigit(char item)
{
var charString = item.ToString();

if ("BFPV".Contains(charString))
return "1";
else if ("CGJKQSXZ".Contains(charString))
return "2";
else if ("DT".Contains(charString))
return "3";
else if ("L".Contains(charString))
return "4";
else if ("MN".Contains(charString))
return "5";
else if ("R".Contains(charString))
return "6";
else
return ".";
}




Como a língua portuguesa dispões de muita sujeira e quinquilharia acentos e símbolos, temos de tratá-las com as funções a seguir:




    // -> Recebe várias letras, separadas por virgula, para serem substituídas por uma letra específica.
private static string ReplaceMultiplo(string value, string from, string to)
{
var fromPattern = string.Format("({0})", string.Join(")|(", from.Split(','))).Replace(".", @"\.");
return Regex.Replace(value, fromPattern, to);
}

private static string GetSoundexBR(string value)
{
value = value.ToUpper();
value = ReplaceMultiplo(value, "Á,À,Ã,Â,Ä", "A");
value = ReplaceMultiplo(value, "É,È,Ê,Ë", "E");
value = ReplaceMultiplo(value, "Í,Ì,Î,Ï", "I");
value = ReplaceMultiplo(value, "Ó,Ò,Ö,Õ,Ô", "O");
value = ReplaceMultiplo(value, "Ú,Ù,Û,Ü", "U");
value = ReplaceMultiplo(value, ".,-,", string.Empty);
value = ReplaceMultiplo(value, "0,1,2,3,4,5,6,7,8,9,0", string.Empty);
value = ReplaceMultiplo(value, "Y", "I");
value = ReplaceMultiplo(value, "PH", "F");
value = ReplaceMultiplo(value, "GE", "JE");
value = ReplaceMultiplo(value, "GI", "JI");
value = ReplaceMultiplo(value, "CA", "KA");
value = ReplaceMultiplo(value, "CE", "SE");
value = ReplaceMultiplo(value, "CI", "SI");
value = ReplaceMultiplo(value, "CO", "KO");
value = ReplaceMultiplo(value, "CU", "KU");
value = ReplaceMultiplo(value, "Ç", "S");
value = ReplaceMultiplo(value, "WAS", "WS");
value = ReplaceMultiplo(value, "WA", "VA");
value = ReplaceMultiplo(value, "WO", "VO");
value = ReplaceMultiplo(value, "WU", "VU");
value = ReplaceMultiplo(value, "WI", "UI");

// -> Depois de tratar a lingua portuguesa
// Geramos o soudex padrão.
value = GetSoundex(value);
return value;
}




Agora vem uma parte legal, vamos implementar isso diretamente no SQL Server, usando a CLR do SQL Server, ou seja, a vantagem do SQL Server utilizar o .NET Framework.



Para tal, vamos habilitar a execução da CLR executando os comando a seguir no SQL Server:




sp_configure 'clr', 1
go
RECONFIGURE
go




Em seguida crie no Visual Studio um projeto para o SQL Server:



4



Após isso o Visual Studio pede para se conectar a base onde a CLR será implantada:



SNAGHTML98a862



O projeto já vem estruturado para o SQL Server e com exemplos de teste:



image



Nesse projeto existem várias opções prontas para implementar muitas das funcionalidades do banco de dados. Aqui usaremos uma Function:



image



Cada método que deverá ser função tem que ser decorado com o atributo "[Microsoft.SqlServer.Server.SqlFunction]". Outro ponto importante é que é possível trabalhar com os tipos do SQL Server. Eles são fundamentais para receber entradas e devolver as saídas.



Resta fazer os métodos que serão reconhecidas pelo SQL Server, ou seja, decoradas com o atributo citado acima. A classe final fica assim:




using System.Data.SqlTypes;
using System.Text.RegularExpressions;
using System.Text;
using System.Linq;

public partial class UserDefinedFunctions
{
/*
para ligar o clr no sql server:
sp_configure 'clr', 1
go
RECONFIGURE
go
*/

[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString SoundexBR(SqlString value)
{
StringBuilder palavras = new StringBuilder();
value = NormalizarEspacos(value);

var valorNormalizado = value.ToString();

// -> Gera o Soundex de cada palavra da string
valorNormalizado.Split(' ').ToList().ForEach(palavra => palavras.Append(string.Format("{0} ", GetSoundexBR(palavra))));

// -> Retorna o tipo string do SQL Server
return new SqlString(palavras.ToString().Trim());
}

// -> Retira espaços excedentes.
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString NormalizarEspacos(SqlString value)
{
var result = value.ToString().Trim();

while (result.Contains(" "))
result = result.Replace(" ", " ");

return new SqlString(result);
}

// -> Recebe várias letras, separadas por virgula, para serem substituídas por uma letra específica.
private static string ReplaceMultiplo(string value, string from, string to)
{
var fromPattern = string.Format("({0})", string.Join(")|(", from.Split(','))).Replace(".", @"\.");
return Regex.Replace(value, fromPattern, to);
}

private static string GetSoundexBR(string value)
{
value = value.ToUpper();
value = ReplaceMultiplo(value, "Á,À,Ã,Â,Ä", "A");
value = ReplaceMultiplo(value, "É,È,Ê,Ë", "E");
value = ReplaceMultiplo(value, "Í,Ì,Î,Ï", "I");
value = ReplaceMultiplo(value, "Ó,Ò,Ö,Õ,Ô", "O");
value = ReplaceMultiplo(value, "Ú,Ù,Û,Ü", "U");
value = ReplaceMultiplo(value, ".,-,", string.Empty);
value = ReplaceMultiplo(value, "0,1,2,3,4,5,6,7,8,9,0", string.Empty);
value = ReplaceMultiplo(value, "Y", "I");
value = ReplaceMultiplo(value, "PH", "F");
value = ReplaceMultiplo(value, "GE", "JE");
value = ReplaceMultiplo(value, "GI", "JI");
value = ReplaceMultiplo(value, "CA", "KA");
value = ReplaceMultiplo(value, "CE", "SE");
value = ReplaceMultiplo(value, "CI", "SI");
value = ReplaceMultiplo(value, "CO", "KO");
value = ReplaceMultiplo(value, "CU", "KU");
value = ReplaceMultiplo(value, "Ç", "S");
value = ReplaceMultiplo(value, "WAS", "WS");
value = ReplaceMultiplo(value, "WA", "VA");
value = ReplaceMultiplo(value, "WO", "VO");
value = ReplaceMultiplo(value, "WU", "VU");
value = ReplaceMultiplo(value, "WI", "UI");

// -> Depois de tratar a lingua portuguesa
// Geramos o soudex padrão.
value = GetSoundex(value);
return value;
}

// -> Obtem o soudex de uma string
private static string GetSoundex(string value)
{
value = value.ToUpper(); // -> Normaliza letras em Maiuscula
var result = new StringBuilder();

foreach (char item in value)
if (char.IsLetter(item)) // -> Limpa String
AddCharacter(result, item); // -> Adiciona um char Soudex

// -> Limpa as exceções geradas
result.Replace(".", string.Empty);
// -> Arruma o tamanho no padrão soudex
// 4 caracteres.
FixLength(result);

return result.ToString();
}

// -> Preenche com 0 nos casos menor q quatro,
// ou pega os 4 primeiros caracteres.
private static void FixLength(StringBuilder result)
{
var length = result.Length;

if (length < 4)
result.Append(new string('0', 4 - length));
else
result.Length = 4;
}

// -> Adiciona o caractere soudex, cuidando para não repetir.
private static void AddCharacter(StringBuilder result, char item)
{
if (result.Length == 0)
{
result.Append(item);
}
else
{
var code = GetSoundexDigit(item);

if (code != result[result.Length - 1].ToString())
result.Append(code);
}
}

// -> Algoritmo de substituição padrão Soudex.
private static string GetSoundexDigit(char item)
{
var charString = item.ToString();

if ("BFPV".Contains(charString))
return "1";
else if ("CGJKQSXZ".Contains(charString))
return "2";
else if ("DT".Contains(charString))
return "3";
else if ("L".Contains(charString))
return "4";
else if ("MN".Contains(charString))
return "5";
else if ("R".Contains(charString))
return "6";
else
return ".";
}
};




Pronto. Para testar coloque a chamada SQL no arquivo "Test.sql", veja:



image



"Dá o play macaco" #Cruj… E começa o deploy no banco de dados, veja o resultado:



image



Como podemos observar na imagem acima, o fonema é apresentado na janela de output, e como a dll já está instalada no SQL Server podemos testar diretamente nele:



image



Podemos aplicá-la em tabelas  e views normalmente! O desempenho é muito superior comparada a uma implementação onde os dados são recuperados e processados por uma aplicação externa. Códigos .NET rodando diretamente na CLR do SQL Server são muito eficazes.



O Soundex é uma dos estudos disponíveis. Existe também o algoritmo BuscaBR, mas esse fica para uma outra oportunidade Smiley de boca aberta



Obrigado, abraços.

28 de set. de 2010

Um pouco sobre ADO.NET

Como se conectar a um banco de dados com o C# ou outra linguagem da plataforma .NET?

Bem, a maioria das aplicações comerciais desenvolvidas precisam de interação com uma base de dados, para persistir informações, processá-las conforme a necessidade e disponibilizá-las posteriormente.

Dentro do .NET Framework (Plataforma com bibliotecas por trás do C#), temos um subconjunto de bibliotecas, ou um outro framework conhecido como ADO.NET (ActiveX Data Objects). Ele é responsável pela comunicação com alguma base de dados, seja em nível mais primitivo ou robusto.

Como ele faz isso? Através de classes simples e intuitivas, de fácil utilização. Também é possível plugar drivers de conexão com banco de dados nele. Isso o torna bem extensível, ou seja, é possível eu conectar com qualquer base de dados que tenha um driver escrito para o ADO.NET. Na maioria das vezes o fabricante da base de dados acaba fornecendo esse driver.

O driver é o conjunto de bibliotecas necessárias para se comunicar com a base de dados. Apesar dos bancos de dados serem os mais variados possíveis, o ADO.NET impõe um padrão, então apenas alguns detalhes irão mudar nos acessos. No geral o padrão é o mesmo. Mas o ADO.NET expande bastante esse conceito de drivers, e pela imposição do padrão, dentro do .NET eles acabam se tornando nossos Provedores (Providers) de dados.

Os provedores de dados ficam responsáveis por fornecer meio de conexão, leitura e “escrita” em um banco de dados.

Há duas formas básicas (primitivas) de se obter dados de uma consulta a uma base de dados. Uma delas é com DataSet. A outra é com DataReader.

O DataSet é um mapeamento em memória das tabelas, relacionamentos e linhas solicitada na consulta. Ele mantém um controle sobre o estado dos objetos na memória, logo ele tem a capacidade de persistir as mudanças no banco de dados.

O DataReader é um leitor de item a item (linha a linha) retornada da consulta. Ele é mais rápido por não mantém todos os metadados que o DataSet mantém. Porém é somente leitura.

No .NET temos alguns provedores nativos. São eles:

  • SQL Server (System.Data.SqlClient),
  • OLE DB (System.Data.OleDb),
  • ODBC (System.Data.Odbc),
  • Oracle (System.Data.OracleClient – Apenas até o VS 2008/.NET 3.5).

Como já comentado antes, esse provedores são expansíveis, uma prova disso é que a própria Oracle tem um provedor para o ADO.NET (e como eles conhecem melhor o caminho das pedras da base de dados deles, acaba sendo mais eficiente o provedor nativo).

Na figura abaixo é exposto a estrutura básica de um provedor:

Os objetos principais de um provedor são:

  • Connection: Gerencia a conexão com a fonte de dados.
  • Command: Executa comados na fonte de dados, podendo ser utilizado para recuperar um DataSet ou um DataReader.
  • DataReader: Lê as informações (item a item) de uma consulta na fonte de dados.
  • DataAdapter: Utilizado para preencher um DataSet após uma consulta. Como já dito anteriormente, ele também tem a capacidade de replicar a atualização dos dados (após as manipulações necessárias) na fonte de dados.

Observe que o DataSet não está citado acima, pois ele é o mesmo objeto para qualquer provedor. Como? Ele só mantem em memória os dados fornecidos pelo DataAdapter, desconhecendo assim o banco de dados, e deixando essa responsabilidade a cargo do DataAdapter.

Vejamos alguns exemplos de conexão com banco de dados:

image

Importante observar três coisas na figura acima:

A primeira são os namespaces que foram incluídos. Um para cada provedor.

A segunda é a string de conexão. Esta é responsável por localizar o banco de dados e passar as credenciais de conexão. Para compreendermos melhor o conceito de string de conexão, imagine o seguinte: para você se conectar a um site, você tem de informar a URL do mesmo, talvez passar alguns parâmetros pela URL, e em algum momento se autenticar no site. A string de conexão faz isso! para saber mais sobre strings de conexão do ADO.NET acesse: http://www.connectionstrings.com/

A terceira é o fato do padrão de nomenclatura.

Vamos trabalhar com um exemplo simples, porém mais concreto. Após instalar o Visual Studio e SQL server em uma máquina, abra o Visual Studio e localize a window “Server Explorer”:

image

Esta window do Visual Studio gerencia as conexões as bases de dados que você informar. Vamos criar uma nova base de dados no SQL Server, clicando com o Botão direito em “Data Connections” > “Create new SQL Server Database”:

image

image

Configure a janela que aparecer com o nome da sua instância de SQL Server, e o nome da base que será criada.

Após criar a base vamos adicionar uma Tabela “Pessoa”. Clique com o botão direito na pasta “Table” > “Add New Table”.

image

Crie as colunas com os tipos da imagem abaixo. Na coluna “Codigo”, clique com o botão direito em Set Primary Key, para definir esta coluna como chave primária.

image

Para tornar a coluna código Auto-Incremento, selecione-a e na window de “Column Properties”, defina “Is Identity = Yes”, como na imagem abaixo:

image

Quando for salvar defina o nome “Pessoa”:

image

Vamos inserir algumas linhas nessa tabela, para isso, clique com o botão direito sobre a tabela e selecione “New Query”:

image

Em seguida digite alguns comandos de “insert” e clique no ponto de exclamação em vermelho, como indicado na figura:

image

Após inserir alguns dados, vamos criar uma aplicação de console que irá se conectar na base de dados. Neste primeiro exemplo, iremos listar os dados usando o objeto DataReader, observe:

image

Explicando:

Na linha 16 é definida a variável que representa a string de conexão com o SQL Server, ou seja, qual o caminho para eu conectar na base de dados, com suas devidas configurações e parâmetros de autenticação. Basicamente ela é composta de servidor (podendo ser um IP, assim, poderíamos ter o SQL server em outra máquina que não a de desenvolvimento) com instância do SQL Server, a base de dados inicial e o tipo de autenticação.

Na linha 14 é criado o objeto de conexão com SQL Server passando a string de conexão no construtor. Perceba o uso da palavra reservada “using”. Ela faz o descarte automático do objeto de conexão quando o bloco que ela define for totalmente executado. Isso significa que ela desconecta da base de dados e retira todas as informações desnecessárias da memória, pois abrir e manter uma conexão com uma base de dados é muito custoso. E fica a dica: É possível utilizar o “using” em qualquer objeto que implementa a interface IDisposable, ou seja, todo objeto que pode ser descartado da memória.

Chegou a hora de eu passar o comando SQL criado, para isso utilizamos a classe SqlCommand, passando a string com a instrução SQL, e o objeto de conexão, na linha 18.

Agora que esta tudo pronto para executar o comando, vamos abrir a conexão com o método “Open()”, na linha 20, e resgatar o DataReader (linha 22).

E, enquanto for possível ler linhas que a instrução retornou (linha 24), imprimimos isto na tela, obtendo os dados pelo tipo e índice da coluna (linha 26). Fica registrado que há várias formas de obter a coluna de um DataReader, fique à vontade para explorá-los.

Sendo assim, eis nosso resultado:

image

Agora um exemplo utilizando DataSet:

image

Antes de mais nada a classe DataSet fica no namespace “System.Data”, como na linha 3 indicada na figura acima.

Agora, na linha 19, aparece o DataAdapter recebendo a instrução SQL e a conexão. Ele é que será responsável em recuperar as informações e preencher o DataSet.

Na linha 21 é criado o DataSet, abaixo é aberta a conexão e o DataAdapter preenche o DataSet (linha 24).

Para listar os dados no console, foi feito um “foreach”, obtendo um DataRow (objeto do DataSet que representa uma linha). Percebam que o DataSet tem a capacidade de gerenciar várias tabelas em memória, então, como só temos uma tabela mapeada, pegamos as linhas (Rows) da tabela de índice “0”.

Recuperada a linha, para selecionar a coluna, da linha, é só passar o nome, por string entre colchetes, para o objeto que representa a linha (“item”).

O resultado é o mesmo.

Podemos disponibilizar estes dados facilmente na web. Para tal vamos adicionar uma ASP.NET Web Application na solução:

image

image

Agora, na pagina Default.aspx vamos adicionar um controle que esta apto para receber uma coleção de registros, proveniente da base de dados. Para tal, escolhi a GridView.

image

Basicamente, uma vez que fornecermos uma fonte de dados (coleção de registros) para a GridView, ela irá renderizar uma tabela HTML com as informações. Para forneceremos as informações, vamos para o code behind da página Default.aspx, e no evento Page_Load podemos conectar no banco de dados, resgatar os registros com um select, e de alguma forma fornecer esta coleção para a GridView.

Com o DataSet é mais fácil, apenas atribuímos ele na propriedade DataSouce da GridView, e realizar um DataBind(), método responsável por renderizar a informação vinculada.

Alguns detalhes importantes, para acessar o code behind, abra o arquivo Default.aspx.cs:

image

Temos de tornar esta aplicação a principal, pois o console não nos interessa mais, para isso clique com o botão direito no projeto web > “Set as StartUp Project”:

image

Após estes detalhes, resta a codificação. Vejamos o exemplo da codificação e seu resultado:

image

image

Podemos trabalhar também com o DataReader, porém temos de criar uma lista de objetos. O papel da lista será armazenar os registros em memória e atribuí-la no DataSource da GridView.

Vamos adicionar uma classe “Pessoa” que modelará os objetos da lista,

image

image

image

Agora entramos em um conceito interessante: A interação de um sistema, baseado em linguagem Orientada a Objetos, com uma base de dados relacional.

Já temos nossa classe, resta criar uma lista e os objetos para cada linha recuperada do banco de dados, e adicioná-los em uma Lista tipada (List<>). Vejamos:

image

Visualmente, o resultado é o mesmo, mas lembrando que performaticamente o DataReader é mais ágil.

Não foi muito diferente do exemplo no console, a diferença é que não utilizamos o Console.WriteLine().

Para concluir, vamos voltar na aplicação console, pois agora é hora de explicar como efetuar um comando na base de dados, ganhando assim o poder de inserir, atualizar e apagar registros da base.

image

Para qualquer que seja o comando que deverá ser executado na base de dados (insert, delete, update), devemos utilizar um objeto SqlCommand e o seu método “ExecuteNonQuery()”, que retornará o número de linhas afetadas pelo comando.

Acompanhe o exemplo abaixo:

image

image

Uma instrução de insert esta definida na linha 17. Perceba que ela não recebe diretamente os valores que serão inseridos no banco de dados, pois ela esta recebendo parâmetros. Estes são importantes para evitarmos problema de SQL Injection (injeção de comandos indesejados na string do comando). Então nas linhas 21 e 22 são adicionados parâmetros ao comando, provenientes da classe SqlParameter, passando, no construtor, o nome do parâmetro (com “@”, uma característica do SQL Server, podendo variar a maneira de passar parâmetro, dependendo do Provedor de Dados), e seu valor. O valor é tratado pelo parâmetro, assim evitando dados truncados (no caso de uma Data e Hora) e injeção indevida de SQL (SQL Injection).

Finalmente, na linha 25 executamos o “ExecuteNonQuery()”, inserindo assim mais um registro no SQL Server.

Lembrando que o “ExecuteNonQuery()” da suporte para os comandos de delete e update também.

Para comprovar, podemos voltar no exemplo web, que está com o select, e executar a aplicação.

image

Percebam que o registro inserido, no exemplo acima, esta na linha de Codigo 4.

Espero que tenham gostado, pois o objetivo aqui, foi dar um overview do ADO.NET, focando na conectividade nativa e primitiva do mesmo.

Para quem quiser se aprofundar no assunto, o ADO.NET suporta uma série de frameworks que ajudam a abstrair a camada de dados, e facilitar a interação com o mundo das linguagens Orientadas a Objeto, como o Entity Framework, LINQ to SQL, NHibernate etc… Inclusive DataSets Tipados.

E fica a dica: pense como disponibilizar registros e conectividade com o banco de dados após explorar este artigo de arquitetura, seja de forma primitiva, ou explorando uma solução/framework mais robusto. Se achar que de primeira está difícil, tente criar funções ou classes com métodos que generalizam e o ajudariam com a base de dado.

E este foi um grande overview sobre a base do ADO.NET… Abraços, até mais Smiley mostrando a língua

29 de dez. de 2009

Descobrindo os Relacionamentos das Colunas de um Banco de Dados

image

Perguntei-me, algum tempo atrás, como descobrir o relacionamento entre colunas de um banco de dados no SQL Server. Eis o SQL resultante:

Select
    KeyColumnUsage.Table_Name As Tabela1,
    KeyColumnUsage.Column_Name As Coluna1,
    ConstraintColumnUsage.Table_Name As Tabela2,
    ConstraintColumnUsage.Column_Name As Coluna2,
    KeyColumnUsage.Constraint_Name As NomeFK
From
    Information_Schema.Key_Column_Usage As KeyColumnUsage
    Inner Join Information_Schema.Table_Constraints As TableConstraints On
        KeyColumnUsage.Table_Name = TableConstraints.Table_Name
        And KeyColumnUsage.Constraint_Name = TableConstraints.Constraint_Name
    Inner Join Information_Schema.Referential_Constraints As ReferentialConstraints On
        TableConstraints.Constraint_Name = ReferentialConstraints.Constraint_Name
    Inner Join Information_Schema.Constraint_Column_Usage As ConstraintColumnUsage On
        ReferentialConstraints.Unique_Constraint_Name = ConstraintColumnUsage.Constraint_Name
Where
    TableConstraints.Constraint_Type = 'FOREIGN KEY'

...agora estou trabalhando para mostrar como a relação é feita (1..1; 1..n; n..n). Aceito Sugestões ;)

"Rankeando" as tabelas de um banco SQL Server por quantidade de linhas

image

Eis o SQL "Mágico":

Select Object_Name(ID) AS Tabela, Rows As Linhas From SysIndexes Where IndID < 2 AndObject_Name(ID) Not Like 'sys%' Order By Rows Desc

Espero que tenham gostado :)

Senha Padrão do SQL Server

image

Sumário

Quando se instala o Visual Studio ou o SQL Server, por padrão ele não há interveção na configuração do banco de dados, o que implica também na definição de uma senha padrão parao Super Usuário, ou usuário mestre do banco de dados.

Este artigo descreve detalhadamente as etapas que podem ser usadas para alterar a senhasa (administrador do sistema) no SQL Server.

É possível configurar o Microsoft SQL Server 2005 Express para execução no modo de Autenticação mista. A conta sa é criada durante o processo de instalação e a conta sa tem plenos direitos no ambiente SQL Server. Por padrão, a senha do sa é em branco (NULL), exceto se você alterá-la ao executar o programa Configuração do SQL Server.

Para se ajustar às práticas recomendadas de segurança, é necessário alterar a senha do sapara uma senha mais segura assim que possível.

Como verificar se a senha do SA está em branco

No computador que está hospedando o SQL Server, abra uma janela do prompt de comando.

No prompt de comando, digite o seguinte comando e pressione ENTER:

osql -U sa

Isso o conecta com o SQL Server usando a conta sa. Para estabelecer uma conexão com uma instância nomeada instalada no tipo de computador:

osql -U sa -S servername\instancename

Você estará agora no seguinte prompt:

Senha:

Pressione ENTER novamente. Isso passará uma senha NULL (em branco) para o sa.
Se estiver no seguinte prompt, após pressionar ENTER, isso significa que você não tem a senha para a conta sa:

1>

É aconselhável que você crie uma senha segura e que não esteja em branco e ajusta-se às práticas recomendadas de segurança.

No entanto, se a seguinte mensagem de erro for exibida, isso significa que a senha inserida está incorreta. Essa mensagem de erro indica que uma senha foi criada para conta do sa:

"Falha de logon do usuário 'sa'."

A seguinte mensagem de erro indica que o computador que está executando o SQL Server está definido somente para a Autenticação do Windows:

"Falha de logon do usuário 'sa'. Motivo: O usuário não está associado a uma conexão confiável com o SQL Server."

Não é possível verificar a sua senha do sa no modo de Autenticação do Windows. Contudo, é possível criar uma senha do sa para que a conta do sa esteja segura no caso do modo de autenticação ser alterado para Modo misto no futuro.

Se a seguinte mensagem de erro for exibida, o SQL Server talvez não esteja respondendo ou você tenha fornecido nome incorreto para a instância nomeada do SQL Server instalada:

[Memória compartilhada]O SQL Server não existe ou o acesso foi negado.

[Memória compartilhada]ConnectionOpen (Connect()).

Como alterar a senha do SA

No computador que está hospedando o SQL Server, abra uma janela de prompt de comando.

Digite o seguinte comando e pressione ENTER.

osql -U sa

No prompt Senha: pressione ENTER se a seja for em branco ou digite a senha atual. Isso o conecta com a instância local padrão do MSDE usando a conta sa. Para conectar usando a autenticação do Windows, digite este comando:

use osql –E

Observação: Se estive usando o SQL Server 2005 Express, evite usar o utilitário Osql e faça planos para alterar aplicativos que usam o recurso Osql no momento. Ao contrário, use o utilitário Sqlcmd.
Para obter mais informações sobre o utilitário Sqlcmd, visite o seguinte site do Microsoft Developer Network (MSDN) (em inglês):

http://msdn2.microsoft.com/en-us/library/ms165702.aspx

Digite os seguintes comandos em linhas separadas e pressione ENTER:

sp_password @old = null, @new = 'complexpwd', @loginame ='sa' go

Observação: Verifique se você substituiu o "complexpwd" com a nova senha segura. Uma senha segura inclui caracteres alfanuméricos e especiais e uma combinação de caracteres em maiúsculas e minúsculas.

A seguinte mensagem informativa que será exibida, indica que a senha foi alterada com êxito:

Senha alterada.

Como determinar ou alterar o modo de autenticação

Importante: Este artigo contém informações sobre como modificar o Registro. Antes de modificá-lo, faça um backup e certifique-se de que saiba como restaurá-lo caso ocorra algum problema. Para obter mais informações sobre como fazer backup, restaurar e modificar o Registro, clique no número abaixo para ler o artigo na Base de Dados de Conhecimento Microsoft (a página pode estar em inglês): 256986 Descrição do Registro do Microsoft Windows

Aviso: O uso incorreto do Editor do Registro, ou outro método, pode causar sérios problemas, que talvez exijam a reinstalação do sistema operacional. A Microsoft não garante que os problemas resultantes do uso incorreto do Editor do Registro possam ser solucionados. A modificação do Registro é de sua responsabilidade.

Se não estiver certo de como verificar o modo de autenticação da instalação do MSDE, é possível verificar a entrada do Registro correspondente. Por padrão, o valor da subchave LoginMode do Registro do Windows é 1 para a Autenticação do Windows. Ao ativar o Modo misto de autenticação, esse valor é definido como 2.

  • O local da subchave LoginMode depende da instalação do MSDE como instância padrão do MSDE ou como instância nomeada. Se o MSDE foi instalado como instância padrão, a subchave LoginMode está localizada na seguinte subchave do Registro:

HKLM\Software\Microsoft\MSSqlserver\MSSqlServer\LoginMode

  • Observação: Se estiver usando o SQL Server 2005, o que foi instalado como instância padrão ou instância nomeada, localiza a seguinte subchave do Registro. MSSQL.xrepresenta um espaço reservado para o valor correspondente do sistema:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.x\MSSQLServer

  • Se instalou o MSDE como instância nomeada, a subchave LoginMode estará localizada na seguinte subchave do Registro:

HKLM\Software\Microsoft\Microsoft SQL Server\%InstanceName%\MSSQLServer\LoginMode

Observação: Antes de optar pelos modos de autenticação, é necessário definir uma senha do sa para evitar a exposição a uma brecha na segurança em potencial.

  • Para optar do Modo misto para o Modo integrado (Windows) de autenticação, execute as seguintes etapas:
  • Para interromper o MSSQLSERVER e todos os demais serviços relacionados (como SQLSERVERAgent), abra o applet Serviços no Painel de Controle.
  • Abra o Editor do Registro. Para abrir o Editor do Registro, clique em Iniciar, em Executare digite:
    • "regedt32" (sem as aspas)
  • Clique em OK.
  • Localize uma das seguintes subchaves (dependendo de se você instalou MSDE como instância padrão do MSDE ou como instância nomeada):

HKEY_LOCAL_MACHINE\Software\Microsoft\MSSqlserver\MSSqlServerouHKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\<Instance Name>\MSSQLServer\

  • No painel direito, clique duas vezes na subchave LoginMode.
  • Na caixa de diálogo Editor do DWORD, defina o valor da subchave como 1. Verifique se a opção Hex está selecionada e clique em OK.
  • Reinicie os serviços MSSQLSERVER e SQLSERVERAgent para que a alteração tenha efeito.

Práticas recomendadas de segurança para uma instalação do SQL Server

Cada um dos itens a seguir tornarão o sistema mais seguro e fazem parte das práticas recomendadas de segurança padrão para qualquer instalação do SQL Server.

  • Torne a conta do sa mais segura com uma senha que não seja em branco. Existem worms que só funcionam se não houver segurança na conta de logon do sa. Portanto, para verificar se a conta interna do sa tem uma senha segura, é necessário seguir a recomendação apresentada no tópico "Logon do administrador do sistema (SA)" nos Manuais online do SQL Server, ainda que você não use a conta do sa diretamente.
  • Bloqueie a porta 1433 nos gateways de Internet e reatribua o SQL Server para que receba dados em uma porta alternativa.
  • Se for necessário que a porta 1433 fique disponível nos gateways de Internet, habilite o filtro de entrada e saída para impedir o uso incorreto da porta.
  • Execute o serviço SQLServer e o SQL Server Agent em uma conta do Microsoft Windows NT, não em uma conta local do sistema.
  • Habilite a Autenticação do Microsoft Windows NT e habilite a auditoria para logons com e sem êxito. Depois, interrompa e reinicie o serviço MSSQLServer. Configure os clientes para o uso da Autenticação do Windows NT.

Referências

http://support.microsoft.com/kb/322336/pt-br

Abraços

21 de out. de 2009

Lidando com acentos no SQL

Pessoal, ontem estava fazendo uma importação de um arquivo CSV, na verdade hoje ainda estou nele e está de rosca, mas enfim, um dos problemas que tive foram na parte das cidades, onde umas estavam com acentos e outras não, ex: São Paulo –> Sao Paulo.

Isto pode ser corrigido com o collation (configuração e maneira como o banco de dados trabalha com os caracteres) de várias maneiras.

No SQL Server ele herda o collation do banco ao criar uma tabela. e isto pode ser personalizado a nível de coluna, até mesmo de SQL.

image

O collation default, no meu caso, estava como o do Windows – “Latin1_General”.

image

No meu caso alterei a coluna da minha tabela para o “Latin1_General_CI_AI”, que armazena os caracteres, mas fica indiferente na hora da consulta.

image

Sendo assim, eu posso fazer um where com “São Paulo”, ou “Sao Paulo” e o resultado é o mesmo.

Não é muito bom generalizar, então apliquei somente na coluna de nome da cidade neste caso para poder usar com o LINQ. Ainda não achei uma forma de fazer o LINQ executar o collation no sql, o que seria fantástico, pois em uma instrução de SQL normal conseguimos fazer algo assim:

select * from cidade where Nome like '%São%'
collate Latin1_General_CI_AI

image

Para alterar uma coluna da tabela, você pode usar o SQL Management, clicando com o Botão direito na tabela > Design:

image

Depois selecione a coluna e na janela de column properties localize o item collation:

image

Ou então criar alterar a coluna da tabela passando o collation:

CREATE TABLE dbo.Tmp_Cidade
    (
    Id int NOT NULL IDENTITY (1, 1),
    Uf varchar(2) NOT NULL,
    Nome varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
    )  ON [PRIMARY]

Obs: Não funciona para “Ç”

Obs: Com a coluna alterada o LINQ funciona normalmente.