Categorias
dicas ip microterminal rede tcp windows

Comunicando com microterminal em ASP.NET

Quem j?? foi em supermercado e nunca viu aquelas maquininhas que o operador fica digitando? Pois ??… estamos falando dela mesma. Parece ser f??cil seu uso, mas quem come??a a trabalhar com elas ?? de perder os cabelos.

Nesse artigo veremos como comunicar com um microterminal via TCP/IP e trocar informa????es (ida e volta). Para isso vamos utilizar o modelo da Gertec MT 720. Uma breve descri????o do aparelho e seu uso (retirado daqui):

“O MT 720 ?? um excelente microterminal que opera em rede Ethernet com protocolos TCP-IP. Seu teclado com 20 teclas program??veis pode ser utilizado com fun????es espec??ficas de atalhos para agilizar a opera????o.

As teclas re-legend??veis permitem a identifica????o da fun????o de cada tecla. O display com back light (iluminado), com 20 caracteres por 2 linhas, permite facilmente a visualiza????o da informa????o, principalmente em ambientes que possuem pouca ilumina????o, como bares noturnos, por exemplo.

Atrav??s de uma porta de teclado (AT/PS2) e mais 3 portas Seriais (RS-232) ?? poss??vel a conex??o de perif??ricos como: Leitor de C??digo de Barras, Display de Cliente, Balan??a, Impressora, etc.

O MT 720 ?? ideal para aplica????es de Cart??o de Consumo, solu????es para Bares, Lanchonetes, Restaurantes Self-Service, Livrarias, Papelarias, apontamento de produ????o em Ind??strias.”

Na pr??pria p??gina do dispositivo (citada acima) tem alguns downloads de arquivos, dentre eles alguns c??digos-fontes com exemplos de como fazer a comunica????o bem como realizar as opera????es pelas quais foi criado. Um por??m: s?? tem dispon??veis nas linguagens C++, Delphi e VB (n??o ?? VB.NET).

Da?? pensamos: “sem problemas! ?? s?? converter pra VB.NET a partir do VB”… Tamb??m pensei nisso e n??o consegui! Dando uma olhada de perto no c??digo-fonte d?? para saber que as proezas encontradas s??o s?? poss??veis por artif??cios que a linguagem oferece: por exemplo, ponteiros. Quem j?? programou em VB via a grande flexibilidade da linguagem de fazer tudo o que quer e do jeito que era mais conveniente. Maravilha! Pena que tenhamos que seguir certos padr??es. Fica a dica: se n??o quiser perder tempo, pegue logo o c??digo prontinho l?? na p??gina do fabricante (vem tamb??m no CD quando compra o aparelho) e utilize. De prefer??ncia use o Delphi e em seguida em VB. Se quiser aventurar vamos com C#…

Se escolheu C# siga lendo pois, em diante, veremos como fazer… Teremos os seguintes objetivos na implementa????o:

  1. Criar uma ??nica aplica????o que ir?? receber e enviar os dados;
  2. Exibir o que foi digitado tanto no microterminal quanto no monitor.

Instala????o

Leia o manual do usu??rio aqui. Em resumo: ligue o microterminal na rede el??trica e conecte na porta traseira um cabo RJ-45 no dispositivo e a rede. Em seguida configure, no microterminal, o IP do Servidor (no meu caso, considerei minha m??quina local com o IP 192.168.1.100, por exemplo). Demais configura????es a seu gosto…

Implementa????o

Criemos um Windows Form. Coloquei alguns controles para embelezar a aplica????o…

O mais importante ?? adicionar um objeto Timer. Os demais coloquei para gerar a aplica????o final (que ficar?? no tray – perto do rel??gio – e outras coisas fru-frus). Configure seu Timer com Interval de 50. Pegue a DLL pmtg.dll e copie para sua aplica????o. Eu disse copie! Voc?? n??o conseguir?? aplicar Reference sobre ela. Clique com o bot??o direito sobre a DLL e escolha Properties. Em Copy to Output Directory coloque Copy Always.

Agora vamos ao c??digo! Clique sobre o WinForm e escolha View Code. Cole os c??digos abaixo para que possamos us??-las no form:

        // VARI??VEIS
        IntPtr v_Hwnd;
        int statusCard;
        int statusSerial;
        int MsgReceiveData = 1;
        string[] dados = new string[255];


        // INICIALIZA????O DE FUN????ES EXTERNAS
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_startserver(IntPtr mywhnd, int conecmsg, int commumsg);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern void mt_finishserver();
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_getkey(int id, StringBuilder str);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_backspace(int id);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_dispstr(int id, string str);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_dispch(int id, char ch);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_dispclrln(int id, int lin);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]]
        public static extern int mt_gotoxy(int id, int lin, int col);

Em seguida adicionamos as duas fun????es primordiais: in??cio (quando carregar o formul??rio) e t??rmino (quando fechar o formul??rio):

        private void MicroTerminal_Load(object sender, EventArgs e)
        {
            v_Hwnd = this.Handle;
            statusCard = 0;
            statusSerial = 0;
            if (mt_startserver(v_Hwnd, 0, MsgReceiveData) == 1)
            {
                temporizadorLista.Enabled = true;
            }
            else
                MessageBox.Show(“N??o foi poss??vel carregar os m??dulos de conex??o ?? leitora!”);
        }

        private void MicroTerminal_FormClosed(object sender, FormClosedEventArgs e)
        {
            temporizadorLista.Enabled = false;
            mt_finishserver();
        }

Lembrando que esses eventos devem estar configurados (n??o ?? apenas copiar e colar o c??digo, lembra? deve-se indicar l?? em Events do Form). Com isso, ao fazer o primeiro teste, sua aplica????o j?? estar?? recebendo dados do microterminal. Em seguida devemos adicionar um evento Tick ao Timer. Ou seja, a cada 50 milisegundos (lembra que colocamos com esse valor) ir?? ser executado um determinado m??todo.

Antes disso vamos criar um m??todo que ir?? limpar a tela do microterminal e reiniciar os dados de entrada:

                 private void ReiniciaEntrada(int i)
        {
            // Limpa as duas linhas e o que foi armazenado
            dados[i] = “”;
            mt_dispclrln(i, 1);
            mt_dispclrln(i, 2);
            // Coloca o cursor na primeira linha e prepara o display
            mt_gotoxy(i, 1, 0);
            mt_dispstr(i, “Numero: “);
            mt_gotoxy(i, 2, 0);
        }

Enfim adicionamos o c??digo que ir?? ler temporariamente cada leitora conectada ?? rede e coletar/processar os dados de acordo com o que desejar. No meu caso deixei o seguinte:

        private void temporizadorLista_Tick(object sender, EventArgs e)
        {
            StringBuilder rntStr = new StringBuilder();
            int i = 0;
            // Loop em toda faixa de Ips ??teis: cada leitora conectada na rede
            while (i < 255)
            {
                // Captura algo do teclado
                if (mt_getkey(i, rntStr) == 1)
                {
                    string chrAsHex = ((int)rntStr[0]).ToString(“x”);
                    // Entrada do display caso seja um n??mero
                    if ((chrAsHex == “3030”) || (chrAsHex == “30”) || (chrAsHex == “31”) || (chrAsHex == “32”) || (chrAsHex == “33”) || (chrAsHex == “34”) || (chrAsHex == “35”) || (chrAsHex == “36”) || (chrAsHex == “37”) || (chrAsHex == “38”) || (chrAsHex == “39”))
                    {
                        if (dados[i].Length >= 20)
                            dados[i] = dados[i].Substring(0, 19) + rntStr[0];
                        else
                            dados[i] += rntStr[0];
                        mt_dispch(i, rntStr[0]);
                    }
                    // Se for um ENTER, d?? a entrada na tela para mostrar
                    else if (chrAsHex == “d”)
                    {
                        // Captura e trata a entrada
                        if (dados[i] != “”)
                        {
                            // Faz o processamento do que desejar em dados[i]
                        }
                        // Limpa tela
                        ReiniciaEntrada(i);
                    }
                    // Se for um ESC, apaga tudo
                    else if (chrAsHex == “1b”)
                    {
                        // Limpa tela
                        ReiniciaEntrada(i);
                    }
                    // Se for backspace apaga ??ltimo caractere do display
                    else if (chrAsHex == “8”)
                    {
                        if (dados[i].Length > 0)
                            dados[i] = dados[i].Substring(0, dados[i].Length – 1);
                        mt_backspace(i);
                    }
                    // Se apertar * toca o som
                    else if (chrAsHex == “2a”)
                    {
                        // Toca um sonzinho… depois publico o c??digo de tocar som!
                    }
                }
                i++;
            }
        }

Feito! Rode sua aplica????o e digite algo no teclado do microterminal e ver?? que o que est?? sendo digitado est?? indo tanto para a aplica????o quanto para o display (no microterminal). A sa??da seria algo do tipo:

Se precisar de sa??da na tela crie um outro WinForm que ocupe toda tela (sua) e captura o que est?? no display do microterminal. Assim ?? mais f??cil! Ou fa??a do jeito que sua imagina????o mandar! O mais dif??cil j?? passou…

Para quem quiser capturar os IPs de cada microterminal, utilize os m??todos:

[DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern TTABSOCK mt_connectlist();

ou

[DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern StringBuilder mt_ipfromid(int id);

Nessas fun????es tem algumas particularidades muito chatinhas de se trabalhar (veja no manual das fun????es) por isso deixei de lado. Principalmente a classe:

    [StructLayout(LayoutKind.Sequential)]
    public struct TTABSOCK
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
        public UInt32[] TSOCK;
    }

Quem quiser se aventurar nela, fica a?? a dica. Esse artigo merecia at?? uma v??deo-aula, mas a pregui??a ??s vezes ?? muito forte! ?? at?? legalzinho ter esses desafios, mas ??s vezes se torna muito chato quando n??o consegue. Enfim, quanto menos se estressar, melhor! Ent??o tente usar as implementa????es que j?? a Gertec j?? disponibilizou, caso n??o queira aventurar, a menos que precise de algo mais espec??fico.
Falar que nem Marcoratti: “eu sei, ?? apenas ASP.NET, mas eu gosto!”

Categorias
dicas sql server

Melhorando o desempenho de consultas (SELECT) em tabelas grandes no SQL SERVER

“Tenho uma tabela com mais de um milh??o de registros. Fa??o uma consulta… um simples SELECT… mas est?? demorando muito para retornar. O que fazer?”

Essa ?? a pergunta que voc?? se faz nessa situa????o. Todo programador sabe trabalhar com banco, mas nem sempre sabemos utilizar da melhor forma. Um DBA j?? ?? craque na situa????o e sabe a melhor forma de melhorar o desempenho de uma consulta. A dica do dia ??: ??ndices! Se voc?? n??o sabe o que s??o ??ndices, veja essa mat??ria aqui de Thiago Pastorello que explica de forma bem compreensiva. Tamb??m recomendo que leia tamb??m esse artigo da Compute-rs onde explica as vantagens e desvantagens de usar ??ndices.

?? s?? isso? Talvez. Se voc?? entedeu o significado de ??ndices lendo os dois artigos (refer??ncia) e fez o que irei demonstrar abaixo pode ser que resolva. Na net voc?? ir?? encontrar outros artigos semelhantes que ir??o mostrar outros caminhos que podem ajudar melhor. Aqui ser?? de forma simplificada… Vamos?

Abra o Microsoft SQL Server Management Studio, conecte-se a base de dados e clique em New Query. Escreva a consulta que deseja avaliar e corrigir para ficar mais r??pida. No meu caso irei executar uma Stored Procedure que cont??m v??rias sub-consultas com manipula????o de agrupamento tais como COUNT, SUM, etc. Na barra de ferramentas marque a op????o Include Actual Execution Plan (Incluir Plano de Execu????o Atual).

Agora clique em Execute ou pressione F5 para executar a query e avali??-la. Aguarde at?? que finalize completamente. V?? na ??ltima aba abaixo de Plano de Execu????o e veja os resultados.

Passando o mouse por cima de cada item ir?? ser exibidos detalhes acerca do custo de processamento. Depois procurem ai no Google mais explica????es sobre cada item. Mas vamos nos atrelar a essa mensagem verde. Note que o pr??prio SQL Server informa que h?? indices ausentes! Vamos cri??-los?

Clique com o direito sobre a mensagem e escolha Detalhes de ??ndices Ausentes.

Ao clicar, ir?? aparecer outra tela com um query de cria????o do ??ndice, exemplo:

/*
Detalhes de ??ndice Ausentes de SQLQuery1.sql – SERVIDOR.Mailing (thiago (53))
O Processador de Consultas estima que a implementa????o do ??ndice a seguir pode melhorar o custo da consulta em 99.7047%.
*/
/*
USE [Mailing]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[News_Envio] ([id_campanha])
GO
*/
 
A consulta de cria????o est?? praticamente pronta bastanto apenas dar um nome para o ??ndice e remover o coment??rio, deixando da seguinte forma:
 
USE [Mailing]
GO
CREATE NONCLUSTERED INDEX PI_Index_Envio_Campanha
ON [dbo].[News_Envio] ([id_campanha])
GO

Pressione F5 ou Execute esse bloco de instru????es para criar o ??ndice. Antes de testarmos, vamos atualizar os ??ndices e suas estat??sticas.

V?? na tabela desejada, na op????o de ??ndices e escolha Reorganizar ??ndices. Veja o n??vel de fragmenta????o e d?? OK. Em seguida execute:

UPDATE STATISTICS News_Envio

No caso substitua News_Envio pelo nome de sua tabela. Agora execute novamente o primeiro processo e ver?? um ganho significativo de velocidade de consulta. O que levava 1 minuto para executar, em menos de 1 segundo obt??m-se o resultado. Bom n???

Aprecie com modera????o o uso de ??ndices e leiam as refer??ncias para saber quais situa????es onde ?? vantagem ou n??o o uso deles.

Categorias
dicas seguran??a web.config

Vulnerabilidade de Seguran??a no ASP.NET

Recentemente, em um congresso internacional, descobriu-se um problema de vulnerabilidade em sistemas ASP.NET atrav??s do web.config. O problema afeta todas as vers??es do framework… A mat??ria completa de como ?? o ataque e de como se proteger podem ser lidos nesses posts de Scott Guthrie:

  1. Important: ASP.NET Security Vulnerability
  2. Frequently Asked Questions about the ASP.NET Security Vulnerability

A priori, para impedir o ataque, proteja sua aplica????o fazendo com que os erros n??o sejam exibidos para o cliente. No web.config adicione as seguintes tags:

<configuration>
   <system.web>
      <customErrors mode=”On” defaultRedirect=”~/Erro.aspx” />
   </system.web>
</configuration>

Assim, toda vez que ocorrer um erro, ir?? ser redirecionado para uma tela espec??fica.

Categorias
dicas web-service

HTTP 417 Expectation failed (falha de expectativa)

Dica r??pida! Esse erro ocorre quando tenta fazer uma requisi????o por WebRequest, Web-Service ou outra requisi????o entre computadores. Para sanar o problema use a chamada antes de realizar o processo:

System.Net.ServicePointManager.Expect100Continue = false;

Para saber mais detalhes sobre erros HTTP 417, acesse aqui.

Categorias
dicas dll google ip salvador

Localiza????o de Usu??rio: Obter Cidade e Estado pelo IP em ASP.NET

A um certo tempo atr??s isso era um pouco complicado de ser feito ou fic??vamos dependentes (muito) de ferramentas de terceiros. Hoje, claramente, posso afirmar que temos mais flexibilidade por??m continuamos atrelados. Mas n??o seja por isso! A Google disponibilizou uma API inovadora que nos ajuda nesse caso e em muitos outros (relativo ao GoogleMaps). O GoogleMaps.Subgurim.NET ?? um avan??ado controle do GoogleMaps para o ASP.NET e permite uma gama de manipula????es sobre suas funcionalidades e a que iremos demonstrar aqui ?? a de obter informa????es do usu??rio pelo IP (no site deles pode encontrar bem como c??digos avan??ados e demais exemplos). Em contrapartida, ?? preciso de um arquivo extra contendo faixas de IP distribu??das pelo mundo. Ent??o a MaxMind disponibilizou tamb??m um arquivo bin??rio contendo essas informa????es gratuitamente. Voc?? pode obter o arquivo aqui ou aqui (a diferen??a ?? que um ?? o link direto e o outro ?? a p??gina geral que pode-se obter em outros formatos). Esse arquivo ?? mensalmente atualizando inserindo novas faixas, logo, deixo o dica para dar sempre uma atualizada quando poss??vel (com isso aumenta mais a precis??o mas hoje, com esse arquivo, j?? realiza uma boa cobertura).
Para in??cio dos trabalhos, baixe o componente GoogleMaps.Subgurim.NET e o arquivo de faixas GeoLiteCity.dat. Crie um novo Web Site. Adicione a GMaps.dll na pasta Bin do projeto e copie o GeoLiteCity.dat tamb??m (coloque em outra pasta afim de organiz??-los – no meu caso coloquei em uma pasta chamada Data). Agora escreva o seguinte c??digo abaixo:

using Subgurim.Controles;

private void ObtemInfoUser()
{
    string database = Server.MapPath(“~/Data/GeoLiteCity.dat”);
    LookupService servico = new LookupService(database);
    Location localizacao = servico.getLocation(Request.ServerVariables[“REMOTE_ADDR”]);
    if (localizacao != null)
    {
        Response.Write(“Cidade: “ + localizacao.city + “<br />”);
        Response.Write(“Pa??s: “ + localizacao.countryName + “<br />”);
        Response.Write(“C??digo do Pa??s: “ + localizacao.countryCode + “<br />”);
        Response.Write(“Regi??o: “ + localizacao.region + “<br />”);
        Response.Write(“C??digo da ??rea: “ + localizacao.area_code + “<br />”);
        Response.Write(“Latitude: “ + localizacao.latitude + “<br />”);
        Response.Write(“Longitudade: “ + localizacao.longitude);
    }
}
 
Voc?? deve obter a sa??da algo do tipo:
 
Cidade: Salvador
Pa??s: Brazil
C??digo do Pa??s: BR
Regi??o: 5
C??digo da ??rea: 0
Latitude: -12,7636
Longitude: -15,2821
 
* Obs: a latitude e longitude s??o dados fict??cios que eu coloquei 😉
 
Se voc?? estiver testando localmente, n??o ter?? resultado pois o Request.ServerVariables[“REMOTE_ADDR”] ir?? trazer o valor 127.0.0.1. Para saber seu IP externo acesse o MeuIp e substitua-o para visualizar os valores e valid??-los. Em breve estarei escrevendo outros artigos mostrando como aproveitar bem a API do GoogleMaps bem como demais funcionalidades. At?? mais!

UPDATE: Ap??s ler, vejam aqui sobre o pl??gio que fizeram com meu artigo e depois acusaram que eu que copiei. Quem l?? o blog sabe como eu escrevo e como expresso minhas id??ias…

Categorias
clr dicas dll sql server visual studio

Utilizando fun????o de uma DLL Externa no SQL Server

Esse ?? um t??pico que ir?? mostrar algo que definitivamente voc?? j?? precisou mas n??o sabia como fazer e que facilitar?? (e muito) alguns trabalhos. Programadores que usam o Bando de Dados para programar sendo por Stored Procedure, Functions e Triggers j?? passaram por maus bocados para preparar um algoritmo que realizasse um determinado processo, mas que esse mesmo algoritmo ?? mais f??cil de ser escrito (ou possuir funcionalidades que o SGDB n??o possui) em outra linguagem de programa????o. Por exemplo: validar e-mail. ?? poss??vel no SQL Server fazermos um Function que receba um VARCHAR e retorne um BIT informando que um e-mail ?? v??lido ou n??o, contudo seria uma fun????o um tanto que trabalhosa para quem n??o est?? familiarizado com programa????o em banco. Para quem desenvolve em ASP.NET (C# ou VB.NET) basta usarmos express??o regular que, em duas linhas, resolve o problema. Portanto iremos utilizar uma fun????o escrita em C# compilada em uma DLL e usarmos em um Function no SQL Server. Isso ?? poss??vel atrav??s do CLR.
Primeiramente vamos criar a DLL contendo a fun????o (no nosso exemplo vamos fazer a que valida e-mail – mas voc?? pode desenvolver a que quiser). Abra o Visual Studio e crie um Project. Em Project Type escolha Visual C# Windows e o Template opte por uma Class Libary. Note que quando voc?? cria uma classe vem com o nome Class1.cs. Para facilitar a compreens??o, renomeie para FuncoesSql.cs (ou outra) e remova o namespace criado. Agora, escreva a fun????o que deseja e adicione os namespaces necess??rios ficando da seguinte forma:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;

public partial class FuncoesSql
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlBoolean IsMailValido(SqlString email)
    {
        // Cria um objeto de express??es regulares para validar e-mail
        Regex expressaoRegular = new Regex(@”^(([^<>()[]\.,;:s@””]+”
        + @”(.[^<>()[]\.,;:s@””]+)*)(“”.+””))@”
        + @”(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}”
        + @”.[0-9]{1,3}])(([a-zA-Z-0-9]+.)+”
        + @”[a-zA-Z]{2,}))$”);

        // Realiza um teste na valida????o da express??o
        return new SqlBoolean(expressaoRegular.IsMatch(email.ToString()));
    }
}

No caso, precisamos explicitar os tipos de entrada e sa??da utilizados pelo banco de dados para que n??o haja problemas de tipagem. Poderia ser qualquer fun????o ou quantas que quisesse, contanto que respeite os tipos. Agora compile a DLL pressionando F6 ou pelo menu Build. J?? temos a DLL com a fun????o. Copie a DLL (que est?? na pasta binDebug de sua solu????o) e coloque-a em um local onde seu Banco de Dados possa busc??-la. Para exemplo, colocarei em C:SqlDlls no Servidor.
O pr??ximo passo ?? verificar se no SQL Server est?? ativo a funcionalidade CLR, para isso v?? em Iniciar > Todos os Programas > Microsft SQL Server 2008 (ou 2005) > Configuration Tools > SQL Server Surface Area Configuration. Entre em Surface Area Configuration for Features e na guia CLR Integration verifique se a fun????o est?? habilitada. Se n??o estiver, habilite.

D?? OK e agora j?? poder?? usar CLR no SQL Server. Abra o SQL Server Management Studio, conecte-se na base desejada e execute as seguintes instru????es SQL (abra um New Query para isso):

— CRIA O ASSEMBLY INDICANDO SUA ORIGEM
CREATE ASSEMBLY FuncoesSql FROM ‘C:SqlDllsFuncoesSqlServerASPNET.dll’
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
— CRIA A FUN????O
CREATE FUNCTION dbo.Fun_Valida_Mail (@email NVARCHAR(350))
RETURNS BIT
— INDICA A ORIGEM DA FUN????O SQL: ASSEMBLY > CLASSE > FUN????O
AS EXTERNAL NAME [FuncoesSql].FuncoesSql.IsMailValido
GO

Agora execute a Query (ou pressione F5)… Foi criada a fun????o! Pronto… agora ?? s?? usar como se fosse uam fun????o do SQL Server normalmente. Abaixo tem alguns exemplos de consulta e seus retornos:

Execu????es:
SELECT dbo.Fun_Valida_Mail(‘tmarcal@gmail’)
SELECT dbo.Fun_Valida_Mail(‘tmarcal@gmail.com’)
SELECT dbo.Fun_Valida_Mail(‘tmarcal.. @gmail.com’)
 
Retorno:
0
1
0
 
Apesar do trabalho inicial, pode-se aproveitar muito de ambos os recursos e criar cada vez mais fun????es complexas. Quanto ao desempenho da CLR, em compara????o ao T-SQL, deve-se ficar a mesma coisa. A diferen??a ?? praticamente impercept??vel. Espero que tenham gostado… At?? breve!

Categorias
crystal reports dicas dll

N??o foi poss??vel carregar arquivo ou assembly System.Web.Extensions, Version=2.0.0.0

Dica r??pida para quem tiver esse erro…
Acontece quando est?? utilizando uma vers??o do ASP.NET Ajax diferente do Framework da aplica????o. Muitas vezes, tamb??m, acontece quando est?? utilizando o Crystal Report ao renderizar um relat??rio. Ent??o ?? exibido a seguinte mensagem:
A solu????o ?? simples: basta remover a System.Web.Extensions.dll e/ou System.Web.Extensions.Design.dll do projeto (na pasta Bin).

N??o foi poss??vel carregar arquivo ou assembly ‘System.Web.Extensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ ou uma de suas depend??ncias. A defini????o do manifesto do assembly localizado n??o corresponde ?? refer??ncia do assembly. (Exce????o de HRESULT: 0x80131040)

Categorias
dicas sql server

Dicas de Instru????es SQL para facilitar o uso no dia-a-dia

Bom, abaixo separei algumas instru????es SQL que muitos programadores tem d??vidas de como us??-las e que facilitam muitas tarefas.

1) INSERT de SELECT: Fazer inser????es em uma tabela puxando dados de outra(s)

Bem parecido com o SELECT INTO por??m voc?? pode fazer v??rias manipula????es conforme desejar usando um simples SELECT. No caso vou mostrar um exemplo bem f??cil: irei adicionar v??rios Alunos numa tabela sendo que os dados est??o em outra tabela (Cadastros), logo minha instru????o ficaria assim:

INSERT INTO Alunos (nome, email) SELECT nome, email FROM Cadastros

O nome dos campos n??o precisam serem iguais, basta estar na mesma ordem e respeitar o tipo de dados (tamanho tamb??m).

2) UPDATE relacionado com outra tabela

Nessa situa????o o que desejamos ?? fazer um UPDATE na tabela sendo que ?? preciso fazer um JOIN com outra tabela. No nosso exemplo: desejamos alterar o preco de um produto sendo que o valor do mesmo est?? relacionado com seu tipo e ele est?? armazenado em outra tabela. Logo podemos usar a seguinte instru????o:

UPDATE Produto SET preco = T.preco FROM Produto AS P, Tipo AS T WHERE P.Id_Tipo = T.Id

Meio complicado quando se v??, n??? Mas se voc?? reparar detalhadamente ver?? que a atualiza????o do pre??o ?? feita, para cada produto, quando o Id_Tipo (da tabela Produto) for igual ao Id (da tabela Tipo) obtendo assim o preco (da tabela Tipo).

3) Remover registros duplicados deixando apenas um

A explica????o desse objetivo ?? bem ??bvia: remover registros duplicados em uma determinada tabela sob,algum crit??rio. Por??m, sua sintaxe ?? mais complicada, mas vamos l??… Para nosso exemplo iremos remover os registros duplicados (ou mais que um) de e-mails deixando apenas um na tabela Mailing:

;WITH Listagem(email, ranking)
AS
(
SELECT email
,ranking = DENSE_RANK() OVER(PARTITION BY email ORDER BY NEWID() ASC)
FROM Mailing WITH (NOLOCK) WHERE email IS NOT NULL 
)
DELETE Listagem WHERE ranking > 1

Esse emaranhado de instru????es se resume em gerar um ranking indicando quantas vezes o registro se repete. Esse ranking ?? armazenado em uma tabela “tempor??ria” (tabela Listagem) com refer??ncia ?? original (tabela Mailing)… Logo que ?? gerado o ranking, ?? feita a exclus??o dos registros que possuem ranking maior que 1, ou seja, apaga todos aqueles que est??o se repetindo deixando apenas um deles.

Bem, ?? isso! Espero ter ajudado… Lembrando que os exemplos acima foram os mais simples e voc??s podem encontrar situa????es semelhantes ou piores mas que, usando-os, podem ajudar a chegar na resolu????o.

Categorias
dicas javascript jquery mootools

Problema do Mootools dentro de um frame

O Mootools ?? um framework JavaScript para criar abas com um belo design e praticidade no uso. Por??m verifiquei que ele tem um certo “probleminha de comportamento” quando o usa dentro de um frame / frameset no IE. O seu carregamento / aplica????o de estilo se d?? atrav??s de uma adi????o de uma fun????o chamadora na janela (usando window.addEvent). A condi????o para execu????o do script se d?? quando o DOM estiver pronto, ou seja, window.addEvent(‘domready’,function({})); . O problema ?? que, para o Internet Explorer (IE) o carregamento da p??gina ?? meio que desordenado enquanto o Firefox e Chrome (n??o testei nos demais navegadores) possuem uma ??tima engine de carregamento de p??gina. Ou seja, ?? vezes o conte??do da p??gina demora a ser carregado e o DOM fica pronto antes dos controles HTML serem devidamente carregados ocasionando erro na execu????o. Para contornar o problema, basta substituir o ‘domready‘ por ‘load‘. Ent??o a aplica????o do Mootools sobre o conte??do ser?? providenciado logo que a p??gina for totalmente carregada. O problema ?? se houver muito conte??do na p??gina e houver demora no carregamento da p??gina pois o estilo ser?? aplicado apenas no final… da?? ?? s?? ter mesmo paci??ncia (ou remove do frame)!

Obs: outros frameworks JavaScript podem vir a ocasionar o mesmo problema sob as mesmas circunst??ncias.

Categorias
dicas mem??ria sql server

Problema no uso de mem??ria no SQL Server 2008

Se em algum momento, quando em trabalho, estiver recebendo uma das seguintes mensagens abaixo, voc?? est?? tendo s??rios problemas de uso de mem??ria:

“There is insufficient system memory in resource pool ‘internal’ to run this query” *
ou
“H?? mem??ria de sistema insuficiente no pool de recursos internos para executar essa consulta” *

Isso ocorre quando h?? v??rias instru????es SQL sendo executadas em seq????ncia. Como o pool n??o aguenta, os dados, em algumas vezes, podem travar… Mesmo que fisicamente eles estejam l??, n??o se pode mais ser utilizados at?? que o banco seja reiniciado. Para corrigir esse problema h?? duas formas: instalar o hotfix que a Microsoft disponibilizou ou reduzir quantidade de instru????es a serem executadas por vez.

1) Instalar o HotFix

O arquivo est?? dispon??vel em um pack cumulativo p??s SP1 do SQL Server 2008. Para mais informa????es e download, clique aqui.

2) Reduzir a quantidade de instru????es SQL

Fazendo um teste de v??rios UPDATE’s seguidos, consegui obter tal erro. Gerei um arquivo .sql com quase 100mil updates e mandei o SQL Server executar, da?? obtive o erro. Nunca tente isso! Se desejar executar v??rios UPDATE’s ou INSERT’s de vez fragmente a execu????o das instru????es em blocos (nem t??o grandes e nem t??o pequenos) dando uma pausa entre as execu????es. Pode-se utilizar uma Store Procedure buscando os dados em um tabela tempor??ria e executar a instru????o de forma gen??rica (INSERT com SELECT, por exemplo). Tamb??m pode-se usar um artif??cio do ASP.NET, Batch Update, para executar a instru????o de forma gen??rica com alto desempenho.

* A depender da configura????o do SQL Server, ao inv??s de ser o recurso interno (ou internal) pode ser o recurso default.