none
Recuperar registros de uma TempTable e comparar valores em um outro Select existente - Procedure RRS feed

  • Pergunta

  • Bom dia Galera,

    Estou em uma situação onde eu recebo como parametro na minha procedure uma String de valores ID, esses valores são separados por pipe (|), com um While eu separo esses valores e armazeno em um campo dentro de uma TempTable, por exemplo, se eu receber 3 IDs na string ( 25|26|27) a minha TemTable terá 3 registros um com 25 outro com 26 e outro com 27.

    O problema é que preciso comparar esses 3 registros com um campo de uma tabela que está em um Select abaixo, estou utilizando CASE para comparar alguns campos, mas como essa TempTable eu posso ter mais que um registro eu não consigo seguir a mesma idéia, tentei um WHILE dentro do CASE e SELECT do campo da TempTable e também não rolou, enfim, não tenho idéia de como fazer essa comparação registro a registro, alguem poderia me ajudar?

    Obrigado!

    Abraço!

    Denis

    sexta-feira, 18 de janeiro de 2013 13:49

Respostas

  •   -------------------------------- MINHA TABELA
    
    DECLARE @T TABLE(CHAVE INT IDENTITY, CODIGO INT)
    
    INSERT INTO @T(CODIGO)VALUES ('10')
    INSERT INTO @T(CODIGO)VALUES ('20')
    INSERT INTO @T(CODIGO)VALUES ('30')
    INSERT INTO @T(CODIGO)VALUES ('40')
    INSERT INTO @T(CODIGO)VALUES ('50')
    INSERT INTO @T(CODIGO)VALUES ('60')
    
    ----------------- VERIFICAÇÃO DO PARAMETRO COM OS CÓDIGOS DA MINHA TABELA
    
    SELECT 
    	CASE 
    		WHEN CODIGO in(Select CODIGO FROM DBO.SPLIT('20|10|25|30|', '|')) 
    		THEN 'OK' ELSE 'Não OK'
    	END Teste
    FROM @T

    Exemplo:


    Atenciosamente, Samuel dos Anjos

    sexta-feira, 18 de janeiro de 2013 22:52

Todas as Respostas

  • Cara,

    Da uma olhada e veja se lhe ajuda:

    Função Split:

    CREATE FUNCTION dbo.SPLIT(@VALOR VARCHAR(8000), @CARACTER CHAR(1)) 
    RETURNS @T TABLE (CHAVE INT IDENTITY, CODIGO VARCHAR(8000))
    
    AS
    
    BEGIN
    
    DECLARE @POSICAO INT
    
    WHILE (SELECT LEN(@VALOR)) > 0
    BEGIN
    
    SET @POSICAO=CHARINDEX(@CARACTER, @VALOR, 0)
    
    INSERT INTO @T(CODIGO)
    SELECT SUBSTRING(@VALOR,0,@POSICAO) CODIGO
    
    IF @POSICAO > 0
    SET @VALOR = SUBSTRING(@VALOR, @POSICAO + 1, (SELECT LEN(@VALOR)))
    ELSE
    SET @VALOR = NULL
    
    END
    
    RETURN
    
    END

    Chamando a função:

    SELECT T.CODIGO FROM DBO.SPLIT('20|10|25|30|', '|') T

    Usando em um select para comparação de valores:

    -------------------------------- MINHA TABELA
    
    DECLARE @T TABLE(CHAVE INT IDENTITY, CODIGO INT)
    
    INSERT INTO @T(CODIGO)VALUES ('10')
    INSERT INTO @T(CODIGO)VALUES ('20')
    INSERT INTO @T(CODIGO)VALUES ('30')
    INSERT INTO @T(CODIGO)VALUES ('40')
    INSERT INTO @T(CODIGO)VALUES ('50')
    INSERT INTO @T(CODIGO)VALUES ('60')
    
    ----------------- VERIFICAÇÃO DO PARAMETRO COM OS CÓDIGOS DA MINHA TABELA
    SELECT * FROM @T WHERE CODIGO IN(SELECT T.CODIGO FROM DBO.SPLIT('20|10|25|30|', '|') T)

    Além disse essa função e o modo como chama é ajustavel:

    SELECT T.CODIGO FROM DBO.SPLIT('20|10|25|30|', '|') T
    
    -- ou
    
    SELECT T.CODIGO FROM DBO.SPLIT('20,10,25,30,', ',') T
    
    -- ou
    
    SELECT T.CODIGO FROM DBO.SPLIT('20#10#25#30#', '#') T
    
    -- ou
    
    SELECT T.CODIGO FROM DBO.SPLIT('20$10$25$30$', '$') T
    
    etc...


    Atenciosamente, Samuel dos Anjos

    sexta-feira, 18 de janeiro de 2013 16:11
  • Samuel,

    Obrigado pela função, mas me ajudou 50%, o retorno eu tinha atpe conseguido, mas o "comparar" que eu mencionei nao seria "filtrar" de acordo com os valores d eminha tabela e sim para eu conseguir um outro resultado através da minha comparação:

    -- SELECT TESTE
    	SELECT ce.int_id_candidato,
    		-- Condição será alterada quando tivermos os Cargos Correlatos
    		(CASE WHEN ce.int_id_cargo = @IdCargo THEN @PontuacaoMaximaCargo ELSE @PontuacaoMinimaCargo END) AS 'int_pontuacao_cargo',
    		(CASE 
    			WHEN ci.int_id_idioma = @IdIdioma AND ci.int_id_nivel >= @IdIdiomaNivel THEN @PontuacaoMaximaIdioma
    			WHEN ci.int_id_idioma = @IdIdioma AND ci.int_id_nivel <= @IdIdiomaNivel THEN @PontuacaoMinimaIdioma ELSE 0 
    		 END) AS 'int_pontuacao_idioma',
    		(CASE 
    			WHEN ((cp.num_salario_min BETWEEN @SalarioDe AND @SalarioAte) OR (cp.num_salario_max BETWEEN @SalarioDe AND @SalarioAte)) THEN @PontuacaoMaximaSalario
    			WHEN ((cp.num_salario_min > @SalarioAte) AND (@Salarioe40PorcentoSalarioAte < cp.num_salario_min)) THEN 0
    			WHEN ((cp.num_salario_max < @SalarioDe) AND (@SalarioMenos40PorcentoSalarioDe > cp.num_salario_max)) THEN 0
    			WHEN ((cp.num_salario_min > @SalarioAte) AND (@Salarioe40PorcentoSalarioAte >= cp.num_salario_min AND @Salarioe20PorcentoSalarioAte <= cp.num_salario_min)) THEN @PontuacaoMinimaSalario
    			WHEN ((cp.num_salario_max < @SalarioDe) AND (@SalarioMenos40PorcentoSalarioDe <= cp.num_salario_max AND @SalarioMenos20PorcentoSalarioDe >= cp.num_salario_max)) THEN @PontuacaoMinimaSalario
    			WHEN ((cp.num_salario_max < @SalarioDe) AND (@SalarioMenos20PorcentoSalarioDe < cp.num_salario_max)) THEN 3
    			WHEN ((cp.num_salario_min > @SalarioAte) AND (@Salarioe20PorcentoSalarioAte > cp.num_salario_min)) THEN 3 
    		 END) AS 'int_pontuacao_salario',
    		(CASE
    			WHEN DATEDIFF(YEAR, CONVERT(DATETIME,c.dt_data_nascimento,103), CONVERT(DATETIME,GETDATE(),103)) < @IdadeMinima - 5 OR @IdadeCandidato > @IdadeMaxima + 5 THEN 0 -- Candidato tem + de 5 anos acima ou abaixo da idade 
    			WHEN DATEDIFF(YEAR, CONVERT(DATETIME,c.dt_data_nascimento,103), CONVERT(DATETIME,GETDATE(),103)) >= @IdadeMinima AND @IdadeCandidato <= @IdadeMaxima THEN @PontuacaoMaximaIdade -- Candidato tem exatamente a idade (ou faixa de idade)
    			ELSE @PontuacaoMinimaIdade -- Candidato tem de 1 a 5 anos acima ou abaixo da idade 
    		END) AS 'int_pontuacao_idade',
    		(CASE 
    			WHEN SELECT cen.int_id_regiao_estado = T.CODIGO FROM DBO.SPLIT(@IdRegiaoEstado, ',') T THEN @PontuacaoMaximaRegiaoEstado ELSE @PontuacaoMinimaRegiaoEstado
    		 END) AS 'int_pontuacao_regiaoestado',
    		(CASE WHEN c.int_id_escolaridade_grau >= @IdEscolaridade THEN @PontuacaoMaximaEscolaridade ELSE @PontuacaoMinimaEscolaridade END) AS 'int_pontuacao_escolaridade',
    		(CASE 
    			WHEN DATEDIFF(MM,c.dt_alteracao, GETDATE()) > 3 THEN 0
    			WHEN DATEDIFF(MM,c.dt_alteracao, GETDATE()) BETWEEN 1 AND 3 THEN @PontuacaoMinimaUltAtualizacao 
    		 ELSE @PontuacaoMaximaUltAtualizacao END) AS 'int_pontuacao_ultimaatualizacao'
    		FROM tb_candidato c
    			INNER JOIN tb_candidato_experiencia ce WITH(NOLOCK) ON (c.int_id_candidato = ce.int_id_candidato)
    			INNER JOIN tb_candidato_pretensao cp WITH(NOLOCK) ON (c.int_id_candidato = cp.int_id_candidato)
    			LEFT OUTER JOIN tb_candidato_idioma ci WITH(NOLOCK) ON (c.int_id_candidato = ci.int_id_candidato)
    			LEFT OUTER JOIN tb_candidato_endereco cen WITH(NOLOCK) ON (c.int_id_candidato = cen.int_id_candidato)
    		WHERE (ce.int_id_cargo = @IdCargo) AND
    			  (c.bit_ativo = 1 AND ce.bit_ativo = 1 AND cp.bit_ativo = 1 AND ci.bit_ativo = 1) AND 
    				 EXISTS
    					(SELECT tef.int_id_estado
    						FROM @Table_Estados_Filtrados tef 
    						WHERE tef.int_id_estado = cen.int_id_estado)

    Veja no meu SELECT o ultimo CASE, eu estou chamando a sua função, só que ali eu preciso comparar da seguinte forma:

    Se a função SPLIT retornar 25 e 26 e caso tenha algum registro com 25 ou 26 ele devolve @PontuacaoMaximaRegiaoEstado senão ele devolve @PontuacaoMinimaRegiaoEstado.

    Isso seria possivel dessa forma?

    Obrigado!!!




    sexta-feira, 18 de janeiro de 2013 16:41
  • Cara,

    Substitua essa linha:

    		(CASE 
    			WHEN SELECT cen.int_id_regiao_estado = T.CODIGO FROM DBO.SPLIT(@IdRegiaoEstado, ',') T THEN @PontuacaoMaximaRegiaoEstado ELSE @PontuacaoMinimaRegiaoEstado
    		 END) AS 'int_pontuacao_regiaoestado',
    

    Por essa:

     (CASE 
    	 WHEN cen.int_id_regiao_estado in(Select T.CODIGO FROM DBO.SPLIT(@IdRegiaoEstado, ','))	 
    	 THEN @PontuacaoMaximaRegiaoEstado ELSE @PontuacaoMinimaRegiaoEstado
      END) AS 'int_pontuacao_regiaoestado',


    Atenciosamente, Samuel dos Anjos

    sexta-feira, 18 de janeiro de 2013 22:51
  •   -------------------------------- MINHA TABELA
    
    DECLARE @T TABLE(CHAVE INT IDENTITY, CODIGO INT)
    
    INSERT INTO @T(CODIGO)VALUES ('10')
    INSERT INTO @T(CODIGO)VALUES ('20')
    INSERT INTO @T(CODIGO)VALUES ('30')
    INSERT INTO @T(CODIGO)VALUES ('40')
    INSERT INTO @T(CODIGO)VALUES ('50')
    INSERT INTO @T(CODIGO)VALUES ('60')
    
    ----------------- VERIFICAÇÃO DO PARAMETRO COM OS CÓDIGOS DA MINHA TABELA
    
    SELECT 
    	CASE 
    		WHEN CODIGO in(Select CODIGO FROM DBO.SPLIT('20|10|25|30|', '|')) 
    		THEN 'OK' ELSE 'Não OK'
    	END Teste
    FROM @T

    Exemplo:


    Atenciosamente, Samuel dos Anjos

    sexta-feira, 18 de janeiro de 2013 22:52
  • Samuel, deu certo, Obrigado!!!
    segunda-feira, 21 de janeiro de 2013 12:07