none
SQL com resultados "aleatórios" RRS feed

  • Pergunta

  • Bom dia,

    Alguém ja viu algo do tipo onde voce executa uma query e cada hora traz um resultado? Esse resultado, segundo o desenvolvedor, não devaria mudar pois ninguém está mexendo no dado e ele está dizendo que o problema é no SQL, onde não consegui encontrar uma solução/problema que seja o SQL.

    Estou usando o SQL2008 R2 SP2 inglês em cluster.

    Li algo no SP3 que existe um bug onde queries que estão usando paralelismo com Union, particionanmento pode ser que ocorra. Eu ja tentei tirar o paralelismo, mas não teve efeito. Não sei mais o que fazer.

    Se alguém ja passou por isso, por favor, me dê uma luz.

    Obrigado.
    segunda-feira, 25 de maio de 2015 14:11

Respostas

  • Nelson, o uso de With(Nolock) da a liberdade para famosas leituras fantasmas, por conta de quando se inicia uma transação a tabela fica alocada, e com o uso de

    With(Nolock) o SQL não entende que é para aguardar o FIM da Transação e caso a transação seja desfeita, o resultado da consulta também mudara, por isso a cada execução o resultado muda.

    Mas como é regra da empresa, deixe claro que qualquer tipo de consulta em produção não terá nenhum tipo de Atomicidade na consulta.

    Att,

    Diego Cunha

    • Marcado como Resposta Nelson Kezan terça-feira, 16 de junho de 2015 16:25
    quarta-feira, 10 de junho de 2015 17:19
  • Outra coisa que pode estar acontecendo é o usode tabelas temporarias. Elas sao ligadas à conexao ativa. Sugiro vc suprimir toda tabela temporaria antes de rodar essa relatorio deste jeito:

    IF OBJECT_ID('tempdb..#Results') IS NOT NULL
        DROP TABLE #Results

    att


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

    • Marcado como Resposta Nelson Kezan terça-feira, 16 de junho de 2015 16:26
    quarta-feira, 10 de junho de 2015 17:30

Todas as Respostas

  • O que muda no resultado??? Quantidade de linhas ?? Conteúdo ??

    Poderia explicar melhor ???

    Coloque uma coluna de auditoria na tabela que será atualizada por trigger de insert ou update com gedate() a cada vez que o trigger for disparado.

    segunda-feira, 25 de maio de 2015 15:41
  • Sua consulta possui um "order by" ? Senao ele esta buscando pela ordem natural. Outra coisa pode ser o indice (se este existe)...

    Nos de mais detalhes, se possivel um exemplo da query que esta sendo executada.

    De uma olhada neste artigo, caso sua query nao tenha "order by"

    http://blogs.msdn.com/b/conor_cunningham_msft/archive/2008/08/27/no-seatbelt-expecting-order-without-order-by.aspx

    att


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


    segunda-feira, 25 de maio de 2015 15:44
  • Muda a quantidade de linha...
    terça-feira, 26 de maio de 2015 00:35
  • Não tem order by...em relação ao indice, você quer dizer que esta com 'problemas'?

    Nesta query tem nolock...ela roda apenas uma vez por dia.

    Nesta mesma query, o resultado, traz resultados corretos e os incorretos.


    terça-feira, 26 de maio de 2015 00:40
  • >em relação ao indice, você quer dizer que esta com 'problemas'?

    Não. O que eu disse é que se nao tem order by é o indice primario que define em qual ordem é exibido.

    Agora voce disse que o problema nao é a ordem e sim a quantidade de registros. Sem conhecer a query ou sua estrutura de tabelas vai ser muito dificil ajudar... Isso pode ter varias causas, por exemplo, voce usa tabelas temporarias? Linked Server? 

    Nos de mais detalhes, se possivel poste aqui sua query e a estrutura da(s) tabela(s) envolvida(s) na consulta

    Att


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


    terça-feira, 26 de maio de 2015 13:31
  • Willian segue a query:

    SELECT DISTINCT DOPEETRFS AS DOPES 
    INTO #OPEAUTO 
    FROM OPERACAO 
    UNION ALL
    SELECT DISTINCT DOPESTRFS AS DOPES FROM OPERACAO
    GO

    SELECT A.EMPDOPNUMS,A.CPROS,E.EMPS,E.GRUPOOS AS GRUPOS,E.CONTAOS AS CONTAS,
    SUM(A.QTDS * CASE WHEN D.CESTOS = 2 THEN A.PESOS ELSE 1 END * CASE WHEN B.OPERS = 3 THEN CASE WHEN A.OPERS = 'E' THEN 1 ELSE -1 END ELSE CASE WHEN B.ESTORIGS = 1 THEN 1 ELSE -1 END END) AS QTDS
    INTO #ITENS
    FROM ITENS A WITH (NOLOCK)
    INNER JOIN OPERACAO B WITH (NOLOCK) ON A.DOPES = B.DOPES
    INNER JOIN PRODUTO C WITH (NOLOCK) ON A.CPROS = C.CPROS
    INNER JOIN SLJUNI D WITH (NOLOCK) ON C.CUNIS = D.CUNIS
    INNER JOIN GRUPO G WITH (NOLOCK) ON C.CGRUS = G.CGRUS
    INNER JOIN CABECALHO E WITH (NOLOCK) ON A.EMPDOPNUMS = E.EMPDOPNUMS
    WHERE E.DATAS >= '20100101' AND B.ESTOQS = 1 AND B.MENUS <> 'DIST' AND A.DOPES <> 'RETORNO' AND A.DOPES NOT IN (SELECT DOPES FROM #OPEAUTO )
    AND B.ESTORIGS IN (1,2,4) AND NOT ((B.ESTORIGS = 4 AND A.OPERS = 'E') OR (B.OPERS = 3 AND A.OPERS = 'E' AND B.AGREGAS = 4)) AND G.CESTOQS = 1
    GROUP BY A.EMPDOPNUMS,A.CPROS,E.EMPS,E.GRUPOOS,E.CONTAOS

    UNION ALL

    SELECT A.EMPDOPNUMS,(CASE WHEN F.TRCODBAR = 1 AND A.CPRO2S <> ' ' THEN A.CPRO2S ELSE A.CPROS END) AS CPROS,
    (CASE WHEN E.EMPDS <> ' ' AND NOT B.TRANSS IN (0,2,4) THEN E.EMPDS ELSE E.EMPS END) AS EMPS,E.GRUPODS AS GRUPOS,E.CONTADS AS CONTAS,
    SUM(A.QTDS * (CASE WHEN D.CESTOS = 2 THEN A.PESOS ELSE 1 END) * (CASE WHEN B.OPERS = 3 THEN (CASE WHEN B.ESTDESTS = 4 THEN (CASE WHEN A.OPERS = 'E' THEN 1 ELSE -1 END)
    ELSE (CASE WHEN A.OPERS = 'E' THEN -1 ELSE 1 END) END ) ELSE (CASE WHEN ESTDESTS = 1 THEN 1 ELSE -1 END) END)) AS QTDS
    FROM ITENS A WITH (NOLOCK)
    INNER JOIN OPERACAO B WITH (NOLOCK) ON A.DOPES = B.DOPES
    INNER JOIN OPERACAO5 F WITH (NOLOCK) ON A.DOPES = F.DOPES
    INNER JOIN PRODUTO C WITH (NOLOCK) ON A.CPROS = C.CPROS
    INNER JOIN SLJUNI D WITH (NOLOCK) ON C.CUNIS = D.CUNIS
    INNER JOIN GRUPO G WITH (NOLOCK) ON C.CGRUS = G.CGRUS
    INNER JOIN CABECALHO E WITH (NOLOCK) ON A.EMPDOPNUMS = E.EMPDOPNUMS
    WHERE E.DATAS >= '20100101'  AND B.ESTOQS = 1 AND B.MENUS <> 'DIST' AND A.DOPES <> 'RETORNO' AND A.DOPES NOT IN (SELECT DOPES FROM #OPEAUTO )
    AND B.ESTDESTS IN (1,2,4) AND NOT (B.ESTDESTS = 4 AND A.OPERS = 'S') AND G.CESTOQS = 1
    GROUP BY A.EMPDOPNUMS,(CASE WHEN F.TRCODBAR = 1 AND A.CPRO2S <> ' ' THEN A.CPRO2S ELSE A.CPROS END),
    (CASE WHEN E.EMPDS <> ' ' AND NOT B.TRANSS IN (0,2,4) THEN E.EMPDS ELSE E.EMPS END),E.GRUPODS,E.CONTADS
    GO

    SELECT A.ORIDOPNUMS AS EMPDOPNUMS,A.CPROS,A.EMPS,A.GRUPOS,A.ESTOS AS CONTAS,
    SUM(A.QTDS * CASE WHEN A.OPERS = 'S' THEN 1 ELSE -1 END) AS QTDS
    INTO #HIS
    FROM HISTORICO A WITH (NOLOCK)
    INNER JOIN OPERACAO B WITH (NOLOCK) ON A.DOPES = B.DOPES
    INNER JOIN PRODUTO C WITH (NOLOCK) ON A.CPROS = C.CPROS
    INNER JOIN GRUPO D WITH (NOLOCK) ON C.CGRUS = D.CGRUS
    WHERE A.DATAS >= '20100101' AND NOT (D.CESTOQS <> 1 OR (B.DOPES = ' ' AND A.OPERS = 'E'))
    AND B.ESTOQS = 1 AND B.MENUS <> 'DIST' AND A.DOPES <> 'RETORNO' AND A.DOPES NOT IN (SELECT DOPES FROM #OPEAUTO )
    GROUP BY A.ORIDOPNUMS,A.CPROS,A.EMPS,A.GRUPOS,A.ESTOS
    GO

    SELECT * INTO #AGRUPA FROM #HIS
    UNION ALL
    SELECT * FROM #ITENS
    GO

    SELECT EMPDOPNUMS,CPROS,EMPS,GRUPOS,CONTAS,SUM(QTDS) AS QTDS INTO #TMPRESULT FROM #AGRUPA 
    GROUP BY EMPDOPNUMS,CPROS,EMPS,GRUPOS,CONTAS
    HAVING SUM(QTDS) <> 0
    ORDER BY 1
    GO

    SELECT EMPDOPNUMS,CPROS,EMPS,GRUPOS,CONTAS,QTDS,
    (SELECT DATAS FROM CABECALHO WITH (NOLOCK) WHERE CABECALHO.EMPDOPNUMS=#TMPRESULT.EMPDOPNUMS ) DATAS,
    (SELECT DTALTS FROM CABECALHO WITH (NOLOCK) WHERE CABECALHO.EMPDOPNUMS=#TMPRESULT.EMPDOPNUMS ) DTALTS 
    INTO #TMPRESULT2
    FROM #TMPRESULT 
    GO


    SELECT * FROM #TMPRESULT2

    terça-feira, 26 de maio de 2015 18:24
  • Caro Nelson,

    Qual o motivo para a utilização do NOLOCK?

    Faça testes sem esta hint e leia sobre pra ver se não é o caso:

    http://blogs.msdn.com/b/davidlean/archive/2009/04/06/sql-server-nolock-hint-other-poor-ideas.aspx

    Abs,


    Luiz Mercante | MCITP SQL 2008 | MCTS SQL 2008 | MTA Database Fundamentals | MCTS Windows Apps | MCTS Windows Network | MCP 2003 | sqldicas@outlook.com | http://sqldicas.com.br --&gt; Se a resposta foi útil de alguma forma, classifique como resposta ou vote como útil.

    sábado, 6 de junho de 2015 16:07
    Moderador
  • Rapaz é o seguinte, tente fazer isso aqui e veja se deu certo quando executar uma query.

    Union select 1 table_name from information_schema.tables where table_name not in ('cadastro)

    Essa query retorna o nome da primeira tabela do banco de dados.

    sábado, 6 de junho de 2015 22:11
  • É uma "regra" da empresa, se não usar o nolock, fica travado e não consigo rodar a query, aqui roda milhares de processos juntos...bem dificil!

    Todos aqui sabem dissos, mas não mudam.

    Abs.


    quarta-feira, 10 de junho de 2015 12:16
  • Nelson, o uso de With(Nolock) da a liberdade para famosas leituras fantasmas, por conta de quando se inicia uma transação a tabela fica alocada, e com o uso de

    With(Nolock) o SQL não entende que é para aguardar o FIM da Transação e caso a transação seja desfeita, o resultado da consulta também mudara, por isso a cada execução o resultado muda.

    Mas como é regra da empresa, deixe claro que qualquer tipo de consulta em produção não terá nenhum tipo de Atomicidade na consulta.

    Att,

    Diego Cunha

    • Marcado como Resposta Nelson Kezan terça-feira, 16 de junho de 2015 16:25
    quarta-feira, 10 de junho de 2015 17:19
  • Outra coisa que pode estar acontecendo é o usode tabelas temporarias. Elas sao ligadas à conexao ativa. Sugiro vc suprimir toda tabela temporaria antes de rodar essa relatorio deste jeito:

    IF OBJECT_ID('tempdb..#Results') IS NOT NULL
        DROP TABLE #Results

    att


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

    • Marcado como Resposta Nelson Kezan terça-feira, 16 de junho de 2015 16:26
    quarta-feira, 10 de junho de 2015 17:30
  • Ok, obrigado.
    terça-feira, 16 de junho de 2015 16:25
  • Ok, farei isso.

    Obrigado.

    terça-feira, 16 de junho de 2015 16:26