none
Como Pegar as Colunas da Procedure que usa Tabela Temporário num Relatório RRS feed

  • Pergunta

  • Amigo, boa tarde.

    Estou com um problema que não sei se tem solução! Vou tentar ser bem explicito!

    Seguinte, eu crio no "SQL Server Management Studio" a minha procedure, faço todos os testes e ela fica funcionando numa boa. Então, quando eu quero usar essa procedure na minha ferramenta de Criação de Relarórios, eu tenho uma certa dificuldade, por que tipo: o relatório precisa recobrar (receber) as colunas que a procedure retorna, que na verdade é uma tabela temporária, e quando executo a procedure na criação de uma fonte de dados para pegar as colunas e fazer o diacho do relatório, ele me dá um erro, dizendo que a tabela tal (temporaria) não existe.

    Então, eu fasso o seguinte: vou na minha procedure e comento ela quase toda, e crio um select normal com as mesmas especificações da tabela temporaria, compilo, vonto no meu relatório e executo a procedure, ai sim ele me retorna as colunas da procedure para que eu possa distribulas como eu quero.

    Fazer isso dá muito trabalho, por que cada vez que eu crio um campo na tabela temporário, tenho que por ele no select que fica comentado, ai as vezes eu esqueço e as vezes dá problema de nº de campo (nada demais eh claro), mas é um processo que imagino que possa ser dinamizado.

    Segue a SP para verem como eu faço.

    O primeiro bloco comentado é o que bloco que descomento quando quero passar ele pro relatório, e o que esta abaixo dele eu comento, depois de pegar as colunas no relatório, eu volto lá e deixo como estava.

    Bem, se alguma Mega Master ai puder ajudar com essa dica, fico muito agradecido.. grande abraço amigos... ..

    USE [GAT_DB]
    GO
    /****** Object:  StoredProcedure [dbo].[GAT_Rel_Contrato_Franquia_Global]    Script Date: 05/27/2009 09:10:28 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[GAT_Rel_Contrato_Franquia_Global]
    	@contrato AS VARCHAR(20),
    	@inicio AS DATETIME, 
    	@fim AS DATETIME,
    	@franquiaTotal AS BIGINT,
    	@valorFranquia AS MONEY,
    	@valorExcedente AS MONEY
    AS
    
    DECLARE
    	@varSomaTotalCopias as int; SET @varSomaTotalCopias = 10;
    
    SET DATEFORMAT dmy;
    /*
    --## Selecao Para Firmamento das Colunas da Tabela ##
    SELECT
    	ecoCodigo as 'COL_ecoCodigo',
    	ecoCodigoSerie as 'COL_ecoCodigoSerie',
    	proDescricao+' - '+proMarca+' - '+proModelo AS 'COL_descMaquina',
    	isnull(maqSerieNumero,'') + isnull(serNumeroSerie,'') as 'COL_numeroSerie',
    	cloSetor as 'COL_cloSetor',
    	ecoCodigo as 'COL_codLeituraAnterior', 
    	ecoCodigo as 'COL_codLeituraAtual',
    	ecoCodigo as 'COL_leituraAnterior', 
    	ecoCodigo as 'COL_leituraAtual',
    	ecoCodigo as 'COL_copiasTiradas'
    FROM CadastroEquipamentoContratado
    	INNER JOIN CadastroProdutoMaquina on maqCodigo = ecoCodigoSerie
    	INNER JOIN CadastroProduto on proCodigo = maqProduto 
    	LEFT JOIN CadastroSerie on maqSerieCodigo = serCodigo
    	INNER JOIN CadastroClienteLocalInstalacao on cloCodigo = maqClienteLocal
    */
    
    -- ## Cria a Tabela Temporária Caso ela ainda nao exista ##
    IF (SELECT OBJECT_ID('tempdb..#DTB')) IS NULL BEGIN
    	CREATE TABLE #DTB (
    		COL_ecoCodigo INT,
    		COL_ecoCodigoSerie INT,
    		COL_descMaquina VARCHAR(100),		
    		COL_numeroSerie VARCHAR(50),
    		COL_cloSetor VARCHAR(30),
    		COL_cccNumeroCC VARCHAR(10),
    
    		COL_codLeituraAnterior int,
    		COL_codLeituraAtual int,
    		COL_leituraAnterior BIGINT,
    		COL_leituraAtual BIGINT,
    		COL_copiasTiradas BIGINT,
    
    		COL_ecoFranquia BIGINT,
    		COL_excedente BIGINT,
    		COL_excedenteUnit MONEY,
    		COL_excedenteValor MONEY 
    
    	)
    	SELECT * FROM #DTB;
    	RETURN;
    
    END ELSE BEGIN
    	SELECT * FROM #DTB;
    	RETURN;
    
    	--DROP TABLE #DTB
    END
    
    -- ## Insere dados na Tabela Temporária ##
    INSERT INTO #DTB (COL_ecoCodigo, COL_ecoCodigoSerie, COL_descMaquina, COL_numeroSerie, COL_cloSetor, COL_cccNumeroCC, COL_ecoFranquia)
    	SELECT 
    		ecoCodigo, 
    		ecoCodigoSerie,		
    		proDescricao+' - '+proMarca+' - '+proModelo,
    		isnull(maqSerieNumero,'')+isnull(serNumeroSerie,''),
    		cloSetor,
    		cccNumero,
    		ecoFranquia
    	FROM CadastroEquipamentoContratado
    		INNER JOIN CadastroProdutoMaquina on maqCodigo = ecoCodigoSerie
    		INNER JOIN CadastroProduto on proCodigo = maqProduto 
    		LEFT JOIN CadastroSerie on maqSerieCodigo = serCodigo
    		INNER JOIN CadastroClienteLocalInstalacao on cloCodigo = maqClienteLocal
    		INNER JOIN CadastroCentroCusto on cccCodigo = maqClienteCentroCusto
    	WHERE
    		ecoCodigoContrato = @contrato
    
    -- Seleciona os Códigos das Leituras pelas Datas
    UPDATE #DTB SET
    COL_codLeituraAnterior = (
    	SELECT ccoCodigoAnterior FROM CadastroLeituraContador
    	WHERE ccoDataLeitura between @inicio and @fim AND ccoCodigoMaquina = COL_ecoCodigoSerie
    ),
    COL_codLeituraAtual = (
    	SELECT ccoCodigo FROM CadastroLeituraContador
    	WHERE ccoDataLeitura between @inicio and @fim AND ccoCodigoMaquina = COL_ecoCodigoSerie
    )
    
    -- Seleciona as Leituras Através dos Códigos
    UPDATE #DTB SET
    COL_leituraAnterior = (
    	SELECT sum(ccoContTotal) FROM CadastroLeituraContador
    	WHERE ccoCodigo = COL_codLeituraAnterior
    ),
    COL_leituraAtual = (
    	SELECT sum(ccoContTotal) FROM CadastroLeituraContador
    	WHERE ccoCodigo = COL_codLeituraAtual
    )
    
    -- Calcula Cópias Tiradas através das Leituras
    UPDATE #DTB SET
    COL_copiasTiradas = (
    	isnull(COL_leituraAtual,0) - isnull(COL_leituraAnterior,0)
    )
    
    -- Se Houver uma franquia Global, então a Franquia por Máquina é nula
    /*
    UPDATE #DTB SET
    COL_ecoFranquia = (
    	NULL
    )
    WHERE @franquiaTotal IS NOT NULL
    */
    
    -- Seleciona os Códigos das Leituras Devidas
    UPDATE #DTB SET
    COL_excedente = (
    	COL_copiasTiradas - COL_ecoFranquia
    ) WHERE COL_copiasTiradas > COL_ecoFranquia
    
    -- Seta Valor do Excedente na Coluna
    UPDATE #DTB SET
    COL_excedenteUnit = (
    	@valorExcedente
    )
    
    UPDATE #DTB SET
    COL_excedenteValor = (
    	COL_excedente * COL_excedenteUnit
    )
    
    -- ## Retorna a Seleção Final ##
    SELECT * 
    FROM #DTB
    ORDER BY COL_ecoCodigo
    
    PRINT @varSomaTotalCopias;
    
    RETURN

    quarta-feira, 27 de maio de 2009 17:08

Respostas

  • Amigos,

    Vou marcar aqui como encerrado para fechar o tópico.

    Agradeço a todos os que se empenharam em me ajudar, de coração.

    Enquanto nao encontro uma solução, vou deixar do jeito que está.

    Abraço a todos ... .. .
    • Marcado como Resposta Bruno Neves segunda-feira, 1 de junho de 2009 18:39
    segunda-feira, 1 de junho de 2009 18:39

Todas as Respostas

  • Olá Bruno,

    1. Qual é examente o erro que está sendo retornado? Poderia postá-lo aqui?
    2. Remova o IF que verifica a existência da tabela temporária. Temporárias normais (não globais) são criadas em tempo de execução, uma para cada usuário. Ou seja, se 100 usuários chamarem a tua proc, 100 temporárias serão criadas, com seus respectivos identificadores internos. Não tenho como olhar com calma o teu cenário, mas a lógica pode estar se perdendo no momento de deletar a temporária (ou ele não acha o objeto, ou acha um objeto de outro usuário e não cria a temporária para a sua sessão, algo assim).
    3. Caso precise ou queria manter a lógica de deleção, sugiro que você coloque alguns PRINTs no meio do código (algo como PRINT 'passou por aqui 1') para você "debugar" a proc e saber em qual condição do IF ele caiu e até onde a execução foi realizada.

    A criação de uma temp é um processo simples e não faz sentido a proc funcionar com uma query em tabelas físicas e não funcionar em tabelas temporárias. Por isto insisto: dê uma checada na lógica de deleção da temporária, e se possível, exclua isto.

    Um grande abraço,
    Raul Santos Neto
    http://raulsantosneto.wordpress.com
    quarta-feira, 27 de maio de 2009 17:30
  • Boa Tarde,

    Seu SQL Server é 2005 ? Qual ferramenta de relatórios você está utilizando ?

    [ ]s,

    Gustavo Maia Aguiar
    http://gustavomaiaaguiar.spaces.live.com

    Como executar tarefas ao iniciar o SQL Server ?
    http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!570.entry
    Classifique as respostas. O seu feedback é imprescindível
    quarta-feira, 27 de maio de 2009 18:36
  • Cara,

    Se você está usando, ele entende que o resultset é o último comando que retorna dados da procedure, no seu caso,
    PRINT
     @varSomaTotalCopias;
    Remova o print e faz o teste.

    Abraços



    Demétrio Silva
    quarta-feira, 27 de maio de 2009 19:28
  • Fala ae Gustavo, blz irmao...

    Uso o 2005 Sim ... e a Ferramenta de Relarórios é o StiMulsoft Report ( o melhor que encontrei ) !

    Desde já agradeço ... .. .
    quarta-feira, 27 de maio de 2009 20:03
  • Olá Bruno,

    Tentou minha sugestão?

    Abraços

    Demétrio Silva
    quarta-feira, 27 de maio de 2009 20:08
  • Olá Demétrio,

    O que é retornado pela proc são os result sets (no caso, tudo o que normalmente aparece na aba Results (pode ser apenas uma, ou um monta de queries.. cada um será tratado com um result set diferente).

    O PRINT, normalmente exibido na aba Messages, não é tratado como um resultado. Lá ficam os PRINTs, as linhas afetadas, e quaisquer outra mensagem de erro ou warning. Não creio que seja este o problema.

    Um abraço,
    Raul Santos Neto
    http://raulsantosneto.wordpress.com
    quinta-feira, 28 de maio de 2009 12:42
  • Fala ai Demétrio, blz cara ...

    Fiz um teste com a sua sugestão aqui e fica na mesma...

    Ele continua me dizendo que a tabela não existe quando peço pra Ferramenta de Relatórios recobrar as colunas existentes na seleção da Procedure.

    Erro: Invalid object name '#DTB'.

    Eu acho que devo resolver isso com uma especie de IF no começo da procedure, mas eu sou novo com isso e nao achei nada na net que possa me ajudar.

    Mas agradeço de coração pela ajuda !!! Esse print tava sobrando ai hehe ... .. .
    quinta-feira, 28 de maio de 2009 12:48
  • Fala ai Raul, td blz meu amigo...

    Bem, como Jack, vamos por partes:

    1 - O Erro que o programa me retorna é o seguinte:

    - Quando executo a procedure somente para que ele me traga as colunas, no caso assim:

    EXECUTE GAT_Rel_Contrato_Franquia_Global
    NULL,NULL,NULL,NULL,NULL,NULL

    ele me diz o seguinte: Invalid object name '#DTB'.

    - Se eu executo ela com os parametros mesmo, no caso assim:

    EXECUTE GAT_Rel_Contrato_Franquia_Global
    '1','01/07/2009','30/07/2009',106000,0.0730,0.1250

    ele me diz o seguinte: Error converting data type varchar to datetime.

    Agora não sei por que esse erro de conversão de data, se dentro do SQL Manager ele não dá esse erro:
    Já tentei setar o tipo de data junto a esse comando mas dá no mesmo, tipo assim:

    SET DATEFORMAT dmy;
    EXECUTE GAT_Rel_Contrato_Franquia_Global
    '1','01/07/2009','30/07/2009',106000,0.0730,0.1250

    Bem, acredito que passando por este erro ele consiga pegar as colunas.


    2 - Bem, como eu sou iniciante em SP, eu realmente nem imagino como usar a linguagem pra criticar esta situação.
    Gostaria se possível que voce me passasse um exemplo bem dinamico de SP que voce tenha ai, que talvez a logica de como usar este IF esteja correta, por que as SP que uso aprendi fuçando na NET, mas nunca soube se é a melhor maneira.
    O que é estranho que é que em execução normal este if se apresenta correto, mas nesta situação não dá certo.


    3 - Bem, quanto aos Prints, a SP esta funcionando perfeitamente... demorei uns dias p fazer e testei todas possibilidades. O resultado esta acontecendo realmente!

    Raul, agreço de coração pela disposição em me ajudar amigo... grande abraço ... .. .
    quinta-feira, 28 de maio de 2009 13:00
  • Realmente Raul,

    Me enganei.

    Abraços
    Demétrio Silva
    quinta-feira, 28 de maio de 2009 13:13
  • Amigos,

    Vou marcar aqui como encerrado para fechar o tópico.

    Agradeço a todos os que se empenharam em me ajudar, de coração.

    Enquanto nao encontro uma solução, vou deixar do jeito que está.

    Abraço a todos ... .. .
    • Marcado como Resposta Bruno Neves segunda-feira, 1 de junho de 2009 18:39
    segunda-feira, 1 de junho de 2009 18:39