none
DotNet RRS feed

  • Pergunta

  • Bom dia.

    Gostaria de uma ajuda. 

    Aqui na empresa tem uma aplicação (DotNet) que insere milhões de registros na base de dados, esta semana tive um problema enorme de lentidão, monitorei meu banco e detectei uma algumas querys ruim (Bem Ruins) em todos os sentidos, segue uma parte do desastre: 

    WHERE(CONVERT(CHAR, CAMPO_DATA, 103)='DD/MM/AAAA')-- O DATATYPE DA TABELA É DATETIME

    Cheguei nos supostos "Caras de DEV" e disseram que não dá para mexer na aplicação!!! - "Sem comentários".

    Dúvidas: É possível e de qual forma posso tratar isso no código da aplicação para que segue no Banco de Dados no formato correto e sem o CONVERT.

    Obrigado

    Denis

    DBA SQL SERVER

    sexta-feira, 7 de novembro de 2014 12:51

Todas as Respostas

  • A nao ser que vc crie um complicado programa para "sniffar" todas chamadas ao banco de dados, trata-las da forma correta, e devolver a informaçao, entao a reposta é NÃO.

    Por experiencia, isso só vai ser resolvido se vc provar que a pratica de desenvolvimento está ruim e pelo que eu vi "insegura" tambem... Eu diria para vc verificar a possibilidade de injeçao SQL. Pelo que eu vi os desenvolvedores usam manipulaçao string para construir as querys.

    Se voce provar que o sistema é vulneravel a Injeçao SQL entao a cabe a diretoria (ou chefia) decidir o rumo do desenvolvimento. É o que eu faria. 

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Sugerido como Resposta Mr. GMSOFT sexta-feira, 7 de novembro de 2014 14:30
    sexta-feira, 7 de novembro de 2014 14:23
  • William,

    Neste cenário eu posso ter SQL Injection.

    Como você notou a prática de desenvolvimento está extremamente ruim e veraneável.

    Se este ambiente utilizasse as boas práticas, como seria o desenvolvimento correto para que este problema não existisse? 

    Att,

    Denis

    sexta-feira, 7 de novembro de 2014 16:34
  • Olhe esse artigo:

    http://msdn.microsoft.com/en-us/library/ff648339.aspx

    O ideal mesmo seria a utilizaçao de um ORM (como o Entity ou nHibernate), mas isso implicaria em um esforço bem grande da parte de desenvolvimento, mas blindaria o programa contra SQLInjection e ainda voce teria querys otimizadas. 

    att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    sexta-feira, 7 de novembro de 2014 16:45
  • Olá Denis,

     como o William disse o ideal seria utilizar ORMs, mas analisando sua pergunta eu acho dificil os "DEV" aceitar utilizar ORM at[e porque teriam que aprender Linq... Mas query utilizada dessa forma era somente no VB6 em .Net o minimo que deve ser feito é passar as query com Parameter para evitar Injeção, tente essa alternativa também é mais simples o aprendizado, mas com ORM o ganho será maior.

    sexta-feira, 7 de novembro de 2014 17:53
  • William,

    Gostei do ORM .

    O que você me sugeria fazer para eu resolver este problema, onde o usuário através da aplicação passa a data no formato dd/mm/aaaa e chegue na base de dados SQL já convertido no formato AAAA-AA-DD?

    Obrigado.

    Att,

    Denis

    sexta-feira, 7 de novembro de 2014 18:55
  • Olá Daniel,

    Obrigado pela resposta.

    o usuário através da aplicação passa a data no formato dd/mm/aaaa, mesmo passando através de parâmetro o CONVERT está sendo realizado no SQL.

    Usando parâmetros como eu resolveria o problema do CONVERT na aplicação e chema na base de dados SQL no formato  americano AAAA-AA-DD?

    Att,

    Denis

    sexta-feira, 7 de novembro de 2014 19:13
  • Denis, como a transformação do ORM seria muito custosa, sugiro o seguinte:

    - Peça para que os "DEV's" criem uma procedure e passe a data como parâmetro, através do ADO.NET

    O código da procedure seria bem simples, como mostro abaixo:

    CREATE PROCEDURE dbo.SP_LISTAR( @DT_BUSCA DATETIME )
    AS
    BEGIN

    SELECT ... 
    FROM ...
    WHERE CAMPO_DATA = @DT_BUSCA

    END

    Já na parte .NET seria importante utilizar o SqlCommand, para que, segue um link com um exemplo.

    http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.parameters(v=vs.110).aspx

    Espero ter ajudado,

    wcristoni


    domingo, 9 de novembro de 2014 23:18
  • Olá Wilson,

    Até está parte eu entendi,

    A dúvida é: O usuário vai passar a data no formato DD/MM/AAAA através da aplicação, como será feito a conversão deste formato para que chegue no SQL no formato AAAA/MM/DD?

    Att,

    Denis

    segunda-feira, 10 de novembro de 2014 19:33
  • O formato chega como 'YYYYMMDD' (ou 'YYYYMMDD HH:mm:ss' caso tenha a parte tempo)  que é um formato neutro universal (independente de qual collation vc use)

    Teste:

    select convert(date,'20140101')


    Do lado do codigo, vc sempre vai trabalhar com um objeto do tipo datetime. Neste caso cabe ao desenvolvedor formata-lo para exibiçao (normalmente um datepicker que utiliza a formataçao definida nas configuraçoes regionais), mas é ORM que mapeia um objeto do tipo DateTime à uma coluna do tipo Date, sem a interferencia do desenvolvedor e sem manipulaçao da string da query.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------



    segunda-feira, 10 de novembro de 2014 19:56
  • Caro Denis, quando você utilizar o SqlCommand, a parte .NET já obrigará o desenvolvedor a utilizar o tipo de dado correto (@Datetime) e com isso você não precisará se preocupar com o formato, pois o tipo já resolve isso para você.

    Essa preocupação só é válida, quando a instrução vem via concatenação de string.

    Espero ter ajudá-lo,

    wcristoni

    terça-feira, 11 de novembro de 2014 01:26
  • Usar ORM para resolver o problema de data ou SQL Injection é usar um canhão pra matar uma barata IMHO.

    Eles podem usar simplesmente SqlCommand e SqlParameters como já citaram previamente, além de informar uma cultura/formato para a data ao criar o SqlParameter, isso já deve ser o suficiente e o custo para alteração bem menor.

    E pra concluir, ORM não é nenhuma bala de prata. Em alguns casos as queries não são muito bacanas também, além do acesso nativo ADO.Net ser bem mais rápido já que insere milhões de registros. Mas aí já é outra discussão.


    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, remember to "Mark as Answer".

    Se achou este post útil, por favor clique em "Votar como Útil". Se por um acaso respondeu sua dúvida, lembre de "Marcar como Resposta".

    terça-feira, 11 de novembro de 2014 10:12
  • Denis,

    Procure não arrumar conflitos desnecessários com o pessoal de DEV porque você apenas vai arrumar "dor de cabeça".

    Sugiro que você faça um e-mail informal (bem simples) demonstrando como funciona a consulta atual e uma "sugestão" sobre a mesma consulta utilizando às condições na cláusula WHERE de modo adequado (revise também os JOINs e os índices). Envie este e-mail apenas para a equipe, mas se o relacionamento entre gerentes/"líderes de projeto" for bom, então adicione eles em cópia.

    Solicite para que os envolvidos no desenvolvimento realizem as duas consulta no SSMS para compararem o desempenho e esclareça que a decisão final "é deles". Afinal, você é responsável pelo serviço e pela estrutura para execução e manipulação de objetos no SQL Server e não pela programação.

    Você precisa demonstrar que você é um parceiro para esta equipe, que apenas procura ajudar "eles terem um bom desempenho" e assim todos vão sair ganhando.

    Mostrar o tempo de execução é fundamental, e tenha "calma" e humildade em demonstrar que existe uma "alternativa" melhor (eu sei que às vezes dá vontade de mandar... mas procure melhorar o ambiente, seja "você" o diferencial positivo para a empresa).

    Em resumo, não tente "forçar" uma correção porque:

    - você vai criar um processo à mais que pode gerar lentidão com o tempo;

    - o problema atual vai persistir e novos surgirão (afinal o DEV continua sem aplicar Boas Práticas);

    - você vai passar a ter de revisar e aplicar correções para outras consultas mal feitas;

    - você, se envolvendo com uma responsabilidade do DEV passa a ser co-responsável por algo que não é de sua alçada (você deve apenas "mostrar o caminho" e não "carregar no colo");

    Se mesmo assim eles insistirem no erro, você pode demonstrar(de modo "sereno") para os responsáveis pelo sistema/projeto que você fez a sua parte e procurou orientar os envolvidos à melhorar suas condições de aprendizagem(afinal estamos sempre aprendendo, por mais conhecimento e certificados que possa ter) e também no uso dos dados para os clientes (tudo documentado por e-mail).

    Mantenha a calma e boa sorte!

    Se ajudou na sua solução, não esqueça de marcar como resposta !

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    terça-feira, 11 de novembro de 2014 10:59