ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Problema com logica sql postgresql?
Ir à página 1, 2  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 2:12 pm    Assunto: Problema com logica sql postgresql? Responder com Citação

Tenho um problema em um cliente seu banco se eu executar meu select assim
Código:
WITH CTE_Count AS
  (SELECT p.id,
          g.id_grade,
          gav.id_grade_atributo_valor,
          ga.id_grade_atributo,
          CASE
              WHEN g.codigo_barra_pai = g.codigo_barra THEN CAST(p.descricao AS VARCHAR(255))
              ELSE
                 --CASE WHEN gav.id_grade_atributo_valor NOTNULL THEN
                   CASE
                     WHEN
                    -- ga.atributo <> '' THEN
                    gav.id_grade_atributo_valor ISNULL THEN
                       CAST(p.descricao || ' - ' || ga.atributo || ' - ' || gav.valor AS varchar(255))
                     ELSE
                       SPLIT_PART(CAST(p.descricao || ' - ' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)), ',', 1) || ' - ' || SPLIT_PART(CAST(p.descricao || ' - ' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)), ',', 2)
                   END                   
                -- ELSE
                --   CAST(p.descricao || ' - ' || ga.atributo || ' - ' || gav.valor AS varchar(255))
                -- END                     
          END AS descrição,
          g.codigo_barra,
          CAST(CAST(g.qtd_atual AS integer) || '|' || u.sigla AS varchar(20)) AS quantidade_no_estoque,
          c.descricao AS classificação,
          CAST(TO_CHAR(g.valor_varejo_aprazo, 'L9G999G990D99') AS varchar(20)) AS Valor_venda,
          CAST(TO_CHAR(g.valor_atacado_aprazo, 'L9G999G990D99') AS varchar(20)) AS Valor_Atacado,
          p.fabricante,
          CAST('L' AS varchar(10)) AS visualizar,
          CAST('' AS varchar(7)) AS excluir,
          g.codigo_barra_pai,
          COUNT(p.id) OVER(PARTITION BY g.codigo_barra_pai) AS Quantidade_Itens,
          p.prod_serv
   FROM grade g
   LEFT JOIN produto p ON p.id_cadastro = g.id_cadastro
   AND (p.id = g.id_produto
        OR p.id_web = g.id_produto)
   AND g.codigo_barra_pai = p.codigo_barra
   LEFT JOIN classificacao c ON p.id_classificacao = c.id
   LEFT JOIN unidade u ON p.id_unidade = u.id
   LEFT JOIN grade_atributo_valor gav ON CAST(gav.id_grade_atributo_valor AS varchar(255)) = g.id_grade_atributo_valor
   LEFT JOIN grade_atributo ga ON ga.id_grade_atributo = gav.id_atributo
   WHERE p.prod_serv = 'P'
     AND (g.ativo = 1)
     AND p.ativo <> 'E'
     AND ((UPPER(UNACCENT(p.descricao)) LIKE UNACCENT('%'))
          OR (g.codigo_barra LIKE '%'))
   ORDER BY descrição)
SELECT *,
       CAST(CASE
                WHEN codigo_barra_pai <> codigo_barra
                     AND Quantidade_Itens > 1 THEN 'o'
                ELSE ''
            END AS varchar(10)) AS grade
FROM CTE_Count
ORDER BY 1,
         3
LIMIT 20
OFFSET 0


Se eu modifico esta linha
Citação:
gav.id_grade_atributo_valor NOTNULL THEN
do case
ficando assim

Código:
WITH CTE_Count AS
  (SELECT p.id,
          g.id_grade,
          gav.id_grade_atributo_valor,
          ga.id_grade_atributo,
          CASE
              WHEN g.codigo_barra_pai = g.codigo_barra THEN CAST(p.descricao AS VARCHAR(255))
              ELSE
                 --CASE WHEN gav.id_grade_atributo_valor NOTNULL THEN
                   CASE
                     WHEN
                    -- ga.atributo <> '' THEN
                    gav.id_grade_atributo_valor NOTNULL THEN
                       CAST(p.descricao || ' - ' || ga.atributo || ' - ' || gav.valor AS varchar(255))
                     ELSE
                       SPLIT_PART(CAST(p.descricao || ' - ' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)), ',', 1) || ' - ' || SPLIT_PART(CAST(p.descricao || ' - ' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)), ',', 2)
                   END                   
                -- ELSE
                --   CAST(p.descricao || ' - ' || ga.atributo || ' - ' || gav.valor AS varchar(255))
                -- END                     
          END AS descrição,
          g.codigo_barra,
          CAST(CAST(g.qtd_atual AS integer) || '|' || u.sigla AS varchar(20)) AS quantidade_no_estoque,
          c.descricao AS classificação,
          CAST(TO_CHAR(g.valor_varejo_aprazo, 'L9G999G990D99') AS varchar(20)) AS Valor_venda,
          CAST(TO_CHAR(g.valor_atacado_aprazo, 'L9G999G990D99') AS varchar(20)) AS Valor_Atacado,
          p.fabricante,
          CAST('L' AS varchar(10)) AS visualizar,
          CAST('' AS varchar(7)) AS excluir,
          g.codigo_barra_pai,
          COUNT(p.id) OVER(PARTITION BY g.codigo_barra_pai) AS Quantidade_Itens,
          p.prod_serv
   FROM grade g
   LEFT JOIN produto p ON p.id_cadastro = g.id_cadastro
   AND (p.id = g.id_produto
        OR p.id_web = g.id_produto)
   AND g.codigo_barra_pai = p.codigo_barra
   LEFT JOIN classificacao c ON p.id_classificacao = c.id
   LEFT JOIN unidade u ON p.id_unidade = u.id
   LEFT JOIN grade_atributo_valor gav ON CAST(gav.id_grade_atributo_valor AS varchar(255)) = g.id_grade_atributo_valor
   LEFT JOIN grade_atributo ga ON ga.id_grade_atributo = gav.id_atributo
   WHERE p.prod_serv = 'P'
     AND (g.ativo = 1)
     AND p.ativo <> 'E'
     AND ((UPPER(UNACCENT(p.descricao)) LIKE UNACCENT('%'))
          OR (g.codigo_barra LIKE '%'))
   ORDER BY descrição)
SELECT *,
       CAST(CASE
                WHEN codigo_barra_pai <> codigo_barra
                     AND Quantidade_Itens > 1 THEN 'o'
                ELSE ''
            END AS varchar(10)) AS grade
FROM CTE_Count
ORDER BY 1,
         3
LIMIT 20
OFFSET 0


Funciona

Mais ai vem outro problema tenho outo cliente que sua tabela é diferente
ai fica errado pra ele
Gera erro na sintaxe
Código:
NOTICE:  Qtd registros: 4
NOTICE:  1ª v_id_atributo_valor: null
NOTICE:  1ª Pos: 0
NOTICE:  StrId: null


ERROR:  invalid input syntax for integer: "null"
CONTEXT:  PL/pgSQL function fn_get_descricao_grade_adr(character varying) line 28 at assignment
********** Error **********

ERROR: invalid input syntax for integer: "null"
SQL state: 22P02
Context: PL/pgSQL function fn_get_descricao_grade_adr(character varying) line 28 at assignment

Na linha 28 desta função
Código:
id_filtro := cast(str_id as integer);


A função é esta
Código:
--//funcao array tamanho
declare qtdReg integer;
declare i integer;
declare texto varchar(1500);
declare textoAux varchar(1500);
declare str_id varchar(1500);
declare pos integer;
declare id_filtro integer;
begin
   IF (v_id_grade_atributo_valor IS NULL) or (v_id_grade_atributo_valor = '') THEN
      RETURN ' ';
   ELSE
      texto := '';
      qtdReg := CHAR_LENGTH(v_id_grade_atributo_valor);
      raise notice 'Qtd registros: %', qtdReg;
      for i in 1..qtdReg loop     
          /*Pego o id da String de IDs*/
          raise notice '1ª v_id_atributo_valor: %', v_id_grade_atributo_valor;
          pos := STRPOS(v_id_grade_atributo_valor, ',');
          raise notice '1ª Pos: %', pos;
          if v_id_grade_atributo_valor <> '' then
         if (pos = 0) then
           str_id := v_id_grade_atributo_valor;
          else
           str_id := SUBSTR(v_id_grade_atributo_valor, 1, pos-1);
         end if;
         raise notice 'StrId: %', str_id;
         id_filtro := cast(str_id as integer);
         /*Elimina os caracteres já recortados para as variáveis*/
         v_id_grade_atributo_valor := SUBSTR(v_id_grade_atributo_valor, pos+1, 165);
         raise notice '2ª v_id_atributo_valor: %', v_id_grade_atributo_valor;
         /*Faz a verificação*/
         if str_id = ',' then
            texto := texto;
         else
             /*Monto o select com atributo e valor. EX: COR-PRETO*/
             select into textoAux p.atributo || ' - ' || vpg.valor
             from grade_atributo_valor vpg
             inner join grade_atributo p
             on (p.id_grade_atributo = vpg.id_atributo
            --Mgs Adriano Inclui mais este comando por causa do sincronismo Web Local
             or p.id_web = vpg.id_atributo)
             where vpg.ativo = 1 and p.ativo = 1 and
             (vpg.id_grade_atributo_valor = id_filtro or vpg.id_web = id_filtro);
             texto := texto || textoAux || ',';
         end if;
          end if;
      end loop;
      raise notice 'sub de retorno: %', SUBSTR(texto, 1, CHAR_LENGTH(texto)-1);
      return SUBSTR(texto, 1, CHAR_LENGTH(texto)-1);
   END IF;
end


se eu alterar o query naquele case de NOTNULL para ISNULL assim pra este
cliente
Código:
gav.id_grade_atributo_valor ISNULL THEN

Ai funciona porque não entra na função

Como resolver isso?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree


Editado pela última vez por adriano_servitec em Seg Ago 06, 2018 9:52 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 2:29 pm    Assunto: Responder com Citação

Código:
Se eu mudo a função na linha 28 assim
 if cast(str_id as integer) <> null then
           id_filtro := cast(str_id as integer);
        end if;   

Ai não da erro na sintaxe do segundo cliente do caso acima, mas estrago a busca do primeiro cliente que postei as imagens, fica pior.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Ago 03, 2018 3:19 pm    Assunto: Responder com Citação

Boa tarde,

Talvez algumas descrições retornem em branco no primeiro cliente porque os cadastros não estão completos como os do segundo cliente.
Experimente fazer um teste dessa forma para ver se aquelas descrições continuam em branco:

Código:
CASE
  WHEN
    gav.id_grade_atributo_valor ISNULL THEN
      CAST(COALESCE(p.descricao, '') || ' - ' || COALESCE(ga.atributo, '') || ' - ' || COALESCE(gav.valor, '') AS varchar(255))


Espero que ajude


Editado pela última vez por imex em Seg Dez 04, 2023 11:53 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 3:55 pm    Assunto: Responder com Citação

imex escreveu:
Boa tarde,

Talvez algumas descrições retornem em branco no primeiro cliente porque os cadastros não estão completos como os do segundo cliente.
Experimente fazer um teste dessa forma para ver se aquelas descrições continuam em branco:

Código:
CASE
  WHEN
    gav.id_grade_atributo_valor ISNULL THEN
      CAST(COALESCE(p.descricao, '') || ' - ' || COALESCE(ga.atributo, '') || ' - ' || COALESCE(gav.valor, '') AS varchar(255))


Espero que ajude


Olá Imex, então assim não traz o resultado correto
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree


Editado pela última vez por adriano_servitec em Seg Ago 06, 2018 9:53 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 4:02 pm    Assunto: Responder com Citação

Se ajudar segue as tabelas envolvidas
tab produto


tab grade


tab grade_atributo


tab grade_tributo_valor


Obrigado
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree


Editado pela última vez por adriano_servitec em Seg Ago 06, 2018 9:54 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 4:14 pm    Assunto: Responder com Citação

Cheguei a montar uma gambiarra aqui

Montei uma procedure
Código:
procedure SelecionaProdutoGrade(const StrSQL: WideString);
  begin
    with QryPesquisa do
    begin
      Close;
      SQL.Clear;
      /// Se for P é produto   
      if pProdServ = 'P' then
      begin
        SQL.Text := SQL.Text + ' WITH CTE_Count AS (' +
          ' SELECT p.id, g.id_grade, ';
       
        SQL.Text := SQL.Text + StrSQL +     
          ' g.codigo_barra, ' +
          ' CAST(CAST(g.qtd_atual as integer) || ''|'' || u.sigla as varchar(20)) '
          + ' as quantidade_no_estoque, c.descricao as classificação, ' +
          ' CAST(TO_CHAR(g.valor_varejo_aprazo, ''L9G999G990D99'') as varchar(20)) as Valor_venda, '
          + ' CAST(TO_CHAR(g.valor_atacado_aprazo, ''L9G999G990D99'') as varchar(20)) as Valor_Atacado,'
          + ' p.fabricante, ';
      end
      else
        SQL.Text := SQL.Text +
          ' SELECT p.id, g.codigo_barra, CASE WHEN g.codigo_barra_pai = g.codigo_barra THEN '
          + ' CAST(p.descricao AS VARCHAR(255))  ELSE CAST(p.descricao || '' - '' '
          + '  || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)) '
          + ' END AS descrição, ' +
          ' CAST(TO_CHAR(p.custo_medio_venda, ''L9G999G990D99'') as varchar(20)), '
          + ' p.prod_serv, ';

      // verifica qual esta chamando
      if Ativo then
        SQL.Text := SQL.Text + ' CAST(' + QuotedStr('L') +
          ' as varchar(10)) as visualizar,'
      else
        SQL.Text := SQL.Text + ' CAST(' + QuotedStr('8') +
          ' as varchar(10)) as visualizar,';
      // continua o script
      SQL.Text := SQL.Text + ' CAST(' + QuotedStr(Chr(39)) +
        ' as varchar(7)) as excluir';

      if pProdServ = 'P' then
        SQL.Text := SQL.Text +
          ', g.codigo_barra_pai, COUNT(p.id) OVER(PARTITION BY g.codigo_barra_pai) '
          + ' as Quantidade_Itens, p.prod_serv ';

      SQL.Text := SQL.Text + '   FROM grade g ' +
        '   LEFT JOIN produto p ON p.id_cadastro = g.id_cadastro ' +     
        '    AND (p.id = g.id_produto OR p.id_web = g.id_produto)  ' +
        '    AND g.codigo_barra_pai = p.codigo_barra ' +
        '   LEFT JOIN classificacao c on p.id_classificacao = c.id ' +
        '   LEFT JOIN unidade u on p.id_unidade = u.id ' +   
        ' LEFT JOIN grade_atributo_valor gav ON ' +
        '   CAST(gav.id_grade_atributo_valor as varchar(255)) = g.id_grade_atributo_valor '
        + ' LEFT JOIN grade_atributo ga ON ga.id_grade_atributo = gav.id_atributo '
        +     
        '  WHERE p.prod_serv = ' + QuotedStr(pProdServ) +     
        '    AND (g.ativo = 1) '; // OR g.ativo IS NULL) ';
      if Ativo then
        SQL.Text := SQL.Text + '    AND p.ativo <> ''E''  '
      else
        SQL.Text := SQL.Text + '    AND p.ativo = ''E''   ';
      // continua o script
      SQL.Text := SQL.Text +
        '    AND ((UPPER(UNACCENT(p.descricao)) LIKE UNACCENT(:pCAMPO)) OR (g.codigo_barra LIKE :pCAMPO)) '
        + '  ORDER BY descrição  ';
      // continua
      if pProdServ = 'P' then
        SQL.Text := SQL.Text + '  ) SELECT *, ' +
          '     CAST(CASE WHEN codigo_barra_pai <> codigo_barra AND Quantidade_Itens > 1 '
          + '             THEN ''o'' ELSE '''' END  ' +
          '          as varchar(10)) AS grade     ' + '     FROM CTE_Count ' +
          ' ORDER BY 1, 3 ' + ' LIMIT ' + IntToStr(Limit) + ' OFFSET ' +
          IntToStr(Offset);
      // ShowMessage(SQL.Text);

      ParamByName('pCAMPO').AsString := AnsiUpperCase('%' + vCampo + '%');
      Open;

      if not IsEmpty then
        Result := dsPesquisa;

      dsPesquisa.DataSet.Fields[0].Origin :=
        GetTableNameFromQuery(dmCadastros.QryPesquisa.SQL.Text);
    end;
  end;


Chamo ela e no except de um chamo o outro modo
Código:

 
  try
    SelecionaProdutoGrade
      (' CASE                                                     ' +
      '        WHEN g.codigo_barra_pai = g.codigo_barra THEN    ' +
      '          CAST(p.descricao AS VARCHAR(255))              ' +
      '       ELSE                                              ' +
      '          CASE                                           ' +
      '            WHEN ga.atributo <> '''' THEN                  ' +
      '            CAST(p.descricao || '' - '' || ga.atributo || '' - '' || gav.valor AS varchar(255)) '
      + '          ELSE                                           ' +
      '           SPLIT_PART(CAST(p.descricao || '' - '' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)),'','',1) || '' - '' || '
      + '            SPLIT_PART(CAST(p.descricao || '' - '' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)),'','',2) '
      + '          END                                            ' +
      '   END AS descrição,                                     ');
  except
    SelecionaProdutoGrade
      (' CASE                                                    ' +
      '        WHEN g.codigo_barra_pai = g.codigo_barra THEN    ' +
      '          CAST(p.descricao AS VARCHAR(255))              ' +
      '       ELSE                                              ' +
      '            CAST(p.descricao || '' - '' || ga.atributo || '' - '' || gav.valor AS varchar(255)) '
      + '   END AS descrição,                                     ');
  end;


Mais se tiver a solução via sql melhor
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Ago 03, 2018 4:29 pm    Assunto: Responder com Citação

Tentando entender um pouco a query, não sei ao certo, mas me parece que a intenção era:

Código:
CASE
  WHEN
    g.id_grade_atributo_valor ISNULL THEN


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 4:36 pm    Assunto: Responder com Citação

imex escreveu:
Tentando entender um pouco a query, não sei ao certo, mas me parece que a intenção era:

Código:
CASE
  WHEN
    g.id_grade_atributo_valor ISNULL THEN


Espero que ajude
Ai volto no mesmo problema na tabela do segundo cliente
Código:
NOTICE:  Qtd registros: 4
NOTICE:  1ª v_id_atributo_valor: null
NOTICE:  1ª Pos: 0
NOTICE:  StrId: null


ERROR:  invalid input syntax for integer: "null"
CONTEXT:  PL/pgSQL function fn_get_descricao_grade_adr(character varying) line 28 at assignment
********** Error **********

ERROR: invalid input syntax for integer: "null"
SQL state: 22P02
Context: PL/pgSQL function fn_get_descricao_grade_adr(character varying) line 28 at assignment

_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Ago 03, 2018 4:59 pm    Assunto: Responder com Citação

Esse v_id_grade_atributo_valor na função é o parâmetro de entrada?
Estou achando estranho, mas pelas mensagens está parecendo que existem registros nesse segundo cliente em que o campo id_grade_atributo_valor da tabela Grade está igual a string 'null' e não null mesmo.
Verifique se isso está ocorrendo, e se estiver deixe o campo null mesmo ou em branco.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 5:14 pm    Assunto: Responder com Citação

imex escreveu:
Esse v_id_grade_atributo_valor na função é o parâmetro de entrada?
Estou achando estranho, mas pelas mensagens está parecendo que existem registros nesse segundo cliente em que o campo id_grade_atributo_valor da tabela Grade está igual a string 'null' e não null mesmo.
Verifique se isso está ocorrendo, e se estiver deixe o campo null mesmo ou em branco.

Então a função completa é esta
Código:
CREATE OR REPLACE FUNCTION public.fn_get_descricao_grade_adr(v_id_grade_atributo_valor character varying DEFAULT 1500)
  RETURNS character varying AS
$BODY$--//funcao array tamanho
declare qtdReg integer;
declare i integer;
declare texto varchar(1500);
declare textoAux varchar(1500);
declare str_id varchar(1500);
declare pos integer;
declare id_filtro integer;
begin
   IF (v_id_grade_atributo_valor IS NULL) or (v_id_grade_atributo_valor = '') THEN
      RETURN ' ';
   ELSE
      texto := '';
      qtdReg := CHAR_LENGTH(v_id_grade_atributo_valor);
      raise notice 'Qtd registros: %', qtdReg;
      for i in 1..qtdReg loop     
          /*Pego o id da String de IDs*/
          raise notice '1ª v_id_atributo_valor: %', v_id_grade_atributo_valor;
          pos := STRPOS(v_id_grade_atributo_valor, ',');
          raise notice '1ª Pos: %', pos;
          if v_id_grade_atributo_valor <> '' then
         if (pos = 0) then
           str_id := v_id_grade_atributo_valor;
          else
           str_id := SUBSTR(v_id_grade_atributo_valor, 1, pos-1);
         end if;
         raise notice 'StrId: %', str_id;
         --if cast(str_id as integer) <> null then
           id_filtro := cast(str_id as integer);
         --end if;   
         /*Elimina os caracteres já recortados para as variáveis*/
         v_id_grade_atributo_valor := SUBSTR(v_id_grade_atributo_valor, pos+1, 165);
         raise notice '2ª v_id_atributo_valor: %', v_id_grade_atributo_valor;
         /*Faz a verificação*/
         if str_id = ',' then
            texto := texto;
         else
             /*Monto o select com atributo e valor. EX: COR-PRETO*/
             select into textoAux p.atributo || ' - ' || vpg.valor
             from grade_atributo_valor vpg
             inner join grade_atributo p
             on (p.id_grade_atributo = vpg.id_atributo
            --Mgs Adriano Inclui mais este comando por causa do sincronismo Web Local
             or p.id_web = vpg.id_atributo)
             where vpg.ativo = 1 and p.ativo = 1 and
             (vpg.id_grade_atributo_valor = id_filtro or vpg.id_web = id_filtro);
             texto := texto || textoAux || ',';
         end if;
          end if;
      end loop;
      raise notice 'sub de retorno: %', SUBSTR(texto, 1, CHAR_LENGTH(texto)-1);
      return SUBSTR(texto, 1, CHAR_LENGTH(texto)-1);
   END IF;
end
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 1500;
ALTER FUNCTION public.fn_get_descricao_grade_adr(character varying)
  OWNER TO postgres;


Mexi na linha 28 com uma condição
Código:
      --if cast(str_id as integer) <> null then
           id_filtro := cast(str_id as integer);
         --end if;   


Mais não deu certo com a mudança.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Sex Ago 03, 2018 5:16 pm    Assunto: Responder com Citação

Criei esta função referente a este outro problema aqui
http://www.activedelphi.com.br/forum/viewtopic.php?t=93143&sid=5a7377ecea463ac0f8b34174ae15ea78
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Ago 03, 2018 6:04 pm    Assunto: Responder com Citação

Você verificou se tem algum registro com a string 'null' como disse antes?
Porque acho que com o Case abaixo essa função não deveria ser executada se o campo id_grade_atributo_valor fosse null mesmo:

Código:
CASE
  WHEN
    g.id_grade_atributo_valor ISNULL THEN


E repare que existe um If logo no começo da função para desviar a execução do trecho abaixo quando o parâmetro é null ou está em branco:

Código:
   IF (v_id_grade_atributo_valor IS NULL) or (v_id_grade_atributo_valor = '') THEN
      RETURN ' ';
   ELSE


Repare também na mensagem gerada pelo trecho abaixo da função:

Código:
      qtdReg := CHAR_LENGTH(v_id_grade_atributo_valor);
      raise notice 'Qtd registros: %', qtdReg;

Código:
NOTICE:  Qtd registros: 4


Será que retorna 4 quando o parâmetro é null mesmo? O correto não seria a Char_Length retornar zero quando é null mesmo?

Segue uma sugestão de alteração no Case para teste então:

Código:
CASE
  WHEN
    g.id_grade_atributo_valor ISNULL or g.id_grade_atributo_valor = 'null' THEN


Ou então na função:

Código:
   IF (v_id_grade_atributo_valor IS NULL) or
      (v_id_grade_atributo_valor = '') or
      (v_id_grade_atributo_valor = 'null') THEN
      RETURN ' ';
   ELSE


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Seg Ago 06, 2018 9:55 am    Assunto: Responder com Citação

Obrigado Imex, sim este OR aqui na condição resolveu
Código:
CASE
  WHEN
    g.id_grade_atributo_valor ISNULL or g.id_grade_atributo_valor = 'null' THEN

_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Seg Ago 20, 2018 6:45 pm    Assunto: Responder com Citação

Me ajudem a criar uma função de retorno de um array no postgresql

To tentando fazer assim mais não da certo


Código:
CREATE OR REPLACE FUNCTION fn_get_descricao_gr(v_id_grade_atributo_valor character varying DEFAULT 1500)
  RETURNS TEXT AS
$BODY$
DECLARE MTSQL TEXT;
begin
    IF (v_id_grade_atributo_valor IS NULL) or
      (v_id_grade_atributo_valor = '') or
      (v_id_grade_atributo_valor = 'null') THEN
      RETURN ' ';
    ELSE
     SELECT INTO MTSQL
        'SELECT || ARRAY_TO_STRING(ARRAY_AGG(
             CAST(COALESCE(ga.atributo, '' '') || '' - '' || COALESCE(gav.valor, '' '') AS varchar(255))), '','','' '') AS ATRIBUTOS
        FROM GRADE_ATRIBUTO GA
        INNER JOIN GRADE_ATRIBUTO_VALOR GAV
            ON GA.ID_GRADE_ATRIBUTO = GAV.ID_ATRIBUTO
        LEFT JOIN GRADE G ON CAST(gav.id_grade_atributo_valor AS varchar(255)) = g.id_grade_atributo_valor
        WHERE GAV.ID_GRADE_ATRIBUTO_VALOR IN (GAV.id_grade_atributo_valor, v_id_grade_atributo_valor)           
        ORDER BY ATRIBUTOS';
       RETURN MTSQL;
     END IF;   
   
end;
$BODY$
LANGUAGE plpgsql;


Peguei o exemplo que roda corretamente aqui na empresa em mysql e preciso montar igual no postgre
Código:
CREATE DEFINER=`csinform`@`%` FUNCTION `fn_get_descricao_grade`(v_id_grade_atributo_valor VARCHAR(200)) RETURNS VARCHAR(255) CHARSET latin1
BEGIN
   
     IF v_id_grade_atributo_valor IS NULL THEN
     
      RETURN ' ';
     
     ELSE
      RETURN IFNULL(CONCAT(' ',(
         SELECT
         GROUP_CONCAT(p.atributo, '-', vpg.valor ORDER BY p.atributo ASC)
         FROM grade_atributo_valor vpg
         INNER JOIN grade_atributo p
          ON p.id_grade_atributo = vpg.id_atributo
         WHERE FIND_IN_SET(vpg.id_grade_atributo_valor,v_id_grade_atributo_valor)
         ORDER BY p.atributo ASC
        )),'');
   END IF;
                           
END$$

_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Ter Ago 21, 2018 9:15 am    Assunto: Responder com Citação

Não sei mais por onde mexer neste select

agora em outro cliente preciso usar uma nova condição para funcionar
Código:
WITH CTE_Count AS
  (SELECT p.id,
          g.id_grade,
          CASE
              WHEN g.codigo_barra_pai = g.codigo_barra THEN CAST(p.descricao AS VARCHAR(255))
              ELSE CASE
                       WHEN g.id_grade_atributo_valor ISNULL
                            OR UPPER(g.id_grade_atributo_valor) = UPPER('null')
                            OR (g.id_grade_atributo_valor <> '') THEN
                            CAST(COALESCE(p.descricao, '') || ' - ' || COALESCE(ga.atributo, '') || ' - ' || COALESCE(gav.valor, '') AS varchar(255))
                       ELSE
                         SPLIT_PART(CAST(COALESCE(p.descricao, '') || ' - ' || COALESCE(fn_get_descricao_grade_adr(g.id_grade_atributo_valor), '') AS VARCHAR(255)), ',', 1) || ' - ' || SPLIT_PART(CAST(p.descricao || ' - ' || fn_get_descricao_grade_adr(g.id_grade_atributo_valor) AS VARCHAR(255)), ',', 2)
                   END
          END AS descrição,
          g.codigo_barra,
          CAST(CAST(g.qtd_atual AS integer) || '|' || u.sigla AS varchar(20)) AS quantidade_no_estoque,
          c.descricao AS classificação,
          CAST(TO_CHAR(g.valor_varejo_aprazo, 'L9G999G990D99') AS varchar(20)) AS Valor_venda,
          CAST(TO_CHAR(g.valor_atacado_aprazo, 'L9G999G990D99') AS varchar(20)) AS Valor_Atacado,
          p.fabricante,
          CAST('L' AS varchar(10)) AS visualizar,
          CAST('''' AS varchar(7)) AS excluir,
          g.codigo_barra_pai,
          COUNT(p.id) OVER(PARTITION BY g.codigo_barra_pai) AS Quantidade_Itens,
          p.prod_serv
   FROM grade g
   LEFT JOIN produto p ON p.id_cadastro = g.id_cadastro
   AND (p.id = g.id_produto
        OR p.id_web = g.id_produto)
   AND g.codigo_barra_pai = p.codigo_barra
   LEFT JOIN classificacao c ON p.id_classificacao = c.id
   LEFT JOIN unidade u ON p.id_unidade = u.id
   LEFT JOIN grade_atributo_valor gav ON CAST(gav.id_grade_atributo_valor AS varchar(255)) = g.id_grade_atributo_valor
   LEFT JOIN grade_atributo ga ON ga.id_grade_atributo = gav.id_atributo
   WHERE p.prod_serv = 'P'
     AND (g.ativo = 1)
     AND p.ativo <> 'E'
     AND ((UPPER(UNACCENT(p.descricao)) LIKE UNACCENT('%%'))
          OR (g.codigo_barra LIKE '%%'))
   ORDER BY descrição)
SELECT *,
       CAST(CASE
                WHEN codigo_barra_pai <> codigo_barra
                     AND Quantidade_Itens > 1 THEN 'o'
                ELSE ''
            END AS varchar(10)) AS grade
FROM CTE_Count
ORDER BY 3,
         1
--LIMIT 20
OFFSET 0


Esta aqui
OR (g.id_grade_atributo_valor <> '')

Porém ao fazer isso estrago o que ja tinha feito para o outro.

To pensando em mudar aquila função, mais não consegui.
Código:
CREATE FUNCTION wc_get_atributos(v_IDGradeAtributoValor integer) RETURNS
SETOF GRADE_ATRIBUTO AS $$
BEGIN
   RETURN QUERY
     SELECT
 ARRAY_TO_STRING(ARRAY_AGG(
          DISTINCT
            (  CAST(COALESCE(p.descricao, '') || ' - ' || COALESCE(ga.atributo, '') || ' - ' || COALESCE(gav.valor, '') AS varchar(255)) )
            ), ',',' ')

     AS DESCRICAO
        FROM GRADE_ATRIBUTO GA
        INNER JOIN GRADE_ATRIBUTO_VALOR GAV
            ON GA.ID_GRADE_ATRIBUTO = GAV.ID_ATRIBUTO
        INNER JOIN GRADE G ON CAST(gav.id_grade_atributo_valor AS varchar(255)) = g.id_grade_atributo_valor
        INNER JOIN PRODUTO P ON G.ID_PRODUTO = P.ID
        WHERE GAV.ID_GRADE_ATRIBUTO_VALOR IN (v_IDGradeAtributoValor)
        ORDER BY DESCRICAO;   
END;
$$ LANGUAGE 'plpgsql'


Alguma dica?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Ir à página 1, 2  Próximo
Página 1 de 2

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB