Ajuda com strore procedure 2

Firebird

09/08/2010

Pessoal
tenho uma lista de logins que passo como string (separando-as por ,(virgula) para essa store procedure.

Como poderia lista todos os compromissos da lista de logins passada por parâmetro.

Login := 'carlos,pedro,maria' -> desejo, no SQL que esta dentro de uma store procedude listar todos os compromissos desses logins?

SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESSOA_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.ID_TIPOPESSOA = 0
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.ID_TIPOPESSOA = 1
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PJ.IDENTIFICADOR WHERE C.DATA BETWEEN :DATA_01 AND :DATA_02 AND C.LOGIN in Lista_de_Logins


Como posso resolver isso?



Carlos Phelippe

Carlos Phelippe

Curtidas 0

Respostas

Eriley Barbosa

Eriley Barbosa

09/08/2010

Se retorna mais de uma linha, tem que passar o For antes do select. Cada nome é uma string logo tem que ser passado entre aspas simples, se estiver utilizando Delphi, fica assim: Login := QuotedStr('carlos') + ',' + QuotedStr('pedro') + ',' + QuotedStr('maria'); Veja que QuotedStr aceita qualquer string e tem a função de envolver uma string por aspas e Lista_de_logins deve ser um parametro do tipo string e tudo que se refere ao in deve estar entre parenteses e cada elemento envolvido por aspas e separado por virgula. Ai quando (:Lista_de_Logins) receber QuotedStr('carlos') + ',' + QuotedStr('pedro') + ',' + QuotedStr('maria'), seria interpretado para 'carlos','pedro','maria'. ficando assim: AND C.LOGIN in ('carlos','pedro','maria')
FOR
SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESSOA_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.ID_TIPOPESSOA = 0
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.ID_TIPOPESSOA = 1
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PJ.IDENTIFICADOR WHERE C.DATA BETWEEN :DATA_01 AND :DATA_02 AND C.LOGIN in (:Lista_de_Logins)

Atenciosamente   Eriley
GOSTEI 0
Carlos Phelippe

Carlos Phelippe

09/08/2010

O retorno esta certo... eu esqueci de por aqui no forum o FOR...

Meu problema ocorre que na terei que passar um parâmetro em forma de lista (lista de logins).

E no SQL quebrar essa lista...

C.LOGIN in (:Lista_de_Logins)

Como poderei quebrar essa lista dentro da store procedure?


GOSTEI 0
Eriley Barbosa

Eriley Barbosa

09/08/2010

Não sei se entendi, mas cada pessoa que estiver na sua lista de login deve estar entre aspas simples como lhe informei e separado por virgula, no SQL o que quebra a linha é o Enter, que no Delphi é o #13.   Atenciosamente   Eriley
GOSTEI 0
Carlos Phelippe

Carlos Phelippe

09/08/2010

Amigo... ERILEY VILAGRANDE BARBOSA tentei o que você sugeriu ... mas não consegui.

Minha SP esta assim:

FOR
SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESS0A_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PF
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PJ
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_C_PJ
WHERE
C.DATA BETWEEN :DATA_01 AND :DATA_02 AND
COALESCE(C.TEXTO,'') CONTAINING :TEXTO_ AND
COALESCE(PJ.NOME,'')||COALESCE(PF.NOME,'')||COALESCE(C_PJ.NOME,'') CONTAINING :NOME AND
C.OPCAO IN (:OPCAO_01, :OPCAO_02, :OPCAO_03) AND
C.LOGIN IN (:C_LOGIN)
INTO :IDENTIFICADOR, :DATA, :HORA, :TEXTO, :OPCAO, :PUBLICO, :LOGIN, :QUEM
DO


Onde estou errando?
GOSTEI 0
Eriley Barbosa

Eriley Barbosa

09/08/2010

Aparentemente está tudo correto, está dando algum erro, como você está passando os parametros e testando esta stored procedure? Atenciosamente   Eriley  
GOSTEI 0
Carlos Phelippe

Carlos Phelippe

09/08/2010

Teste com apenas UM login:

ParamByName('LOGIN').AsString := QuotedStr('ASAP'); //Login

Não dá erro nenhum. Apenas não retorna nada.


GOSTEI 0
Carlos Phelippe

Carlos Phelippe

09/08/2010

Se na SP troco C.LOGIN in (:ListaLogin) por C.LOGIN = :Login passando apenas um parâmetro funciona... mas preciso passar mais de um ...


GOSTEI 0
Eriley Barbosa

Eriley Barbosa

09/08/2010

Opa LOGIN é o parametro de saída, C_LOGIN é o parametro de entrada como no seu código abaixo: AND
C.LOGIN IN (:C_LOGIN)/* Este é um parametro de entrada */
INTO :IDENTIFICADOR, :DATA, :HORA, :TEXTO, :OPCAO, :PUBLICO, :LOGIN, :QUEM
DO/* Tudo que está depois do INTO é parametro de saída */   Logo:   ParamByName('C_LOGIN').AsString := QuotedStr('ASAP'); //É C_LOGIN que é parametro de entrada e não LOGIN que é parametro de saída.   Atenciosamente   Eriley
GOSTEI 0
Eriley Barbosa

Eriley Barbosa

09/08/2010

Vamos nos ater a sua stored procedure como está abaixo:  
FOR
SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESS0A_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PF
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PJ
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_C_PJ
WHERE
C.DATA BETWEEN :DATA_01 AND :DATA_02 AND
COALESCE(C.TEXTO,'') CONTAINING :TEXTO_ AND
COALESCE(PJ.NOME,'')||COALESCE(PF.NOME,'')||COALESCE(C_PJ.NOME,'') CONTAINING :NOME AND
C.OPCAO IN (:OPCAO_01, :OPCAO_02, :OPCAO_03) AND
C.LOGIN IN (:C_LOGIN)
INTO :IDENTIFICADOR, :DATA, :HORA, :TEXTO, :OPCAO, :PUBLICO, :LOGIN, :QUEM
DO

Logo você terá um parâmetro chamado C_LOGIN para passar a lista de logins, que deve ser passada assim:   ParamByName('C_LOGIN').AsString := QuotedStr('ASAP') + ',' + QuotedStr('ERILEY') + ',' + QuotedStr('CARLOS'); //É C_LOGIN que é parametro de entrada e não LOGIN que é parametro de saída.   Atenciosamente   Eriley
GOSTEI 0
Carlos Phelippe

Carlos Phelippe

09/08/2010

Meu código:

FOR
SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESS0A_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PF
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PJ
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_C_PJ
WHERE
C.DATA BETWEEN :DATA_01 AND :DATA_02 AND
COALESCE(C.TEXTO,'') CONTAINING :TEXTO_ AND
COALESCE(PJ.NOME,'')||COALESCE(PF.NOME,'')||COALESCE(C_PJ.NOME,'') CONTAINING :NOME AND
C.OPCAO IN (:OPCAO_01, :OPCAO_02, :OPCAO_03) AND
C.LOGIN IN (:C_LOGIN)
INTO :IDENTIFICADOR, :DATA, :HORA, :TEXTO, :OPCAO, :PUBLICO, :LOGIN, :QUEM
DO


Mas não funciona ainda...
GOSTEI 0
Carlos Phelippe

Carlos Phelippe

09/08/2010

Acredito ser problema da passagem de parâmetro...

No IBCONSOLE faço assim e funciona:

select * from retornacompromissos(0, 1, 2, '', '', current_date, current_date, 'ASAP', 0, 1, 2)


Como passar a lista de logins usando o TIBXQuery? Acredito que é aqui que estou errando....
GOSTEI 0
Eriley Barbosa

Eriley Barbosa

09/08/2010

FOR
SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESS0A_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PF
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PJ
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_C_PJ
WHERE
C.DATA BETWEEN :DATA_01 AND :DATA_02 AND
COALESCE(C.TEXTO,'') CONTAINING :TEXTO_ AND
COALESCE(PJ.NOME,'')||COALESCE(PF.NOME,'')||COALESCE(C_PJ.NOME,'') CONTAINING :NOME AND
C.OPCAO IN (:OPCAO_01, :OPCAO_02, :OPCAO_03) AND
C.LOGIN IN (:C_LOGIN)
INTO :IDENTIFICADOR, :DATA, :HORA, :TEXTO, :OPCAO, :PUBLICO, :LOGIN, :QUEM
DO

Utilize o componente IBStoredProc, configure as seguintes propriedades: Database = SeuIBDtabase Transaction = SeuIBTransaction StoredProcName = RETORNACOMPROMISSOS   Feito isso clique nas reticências ao lado da propriedade Params, veja se os parametros foram adicionados senão vai ter de adicionar e configurar um a um.   Para executar: IBStoredProc.ParamByName('DATA_01').asDateTime := IBStoredProc.ParamByName('DATA_02').asDateTime := IBStoredProc.ParamByName('NOME').asString := IBStoredProc.ParamByName('OPCAO_01').asInteger := IBStoredProc.ParamByName('OPCAO_02').asInteger := IBStoredProc.ParamByName('OPCAO_03').asInteger := IBStoredProc.ParamByName('C_LOGIN').asString := IBStoredProc.ExecProc;   Atenciosamente   Eriley  
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

09/08/2010

não é possível passar uma lista como parâmetro.

para fazer o que você precisa, sugiro condicionar o retorno da stored procedure.

altere a instrução para:

FOR
SELECT
  C.IDENTIFICADOR, C.DATA, C.HORA, C.TEXTO, C.OPCAO, C.PUBLICO, C.LOGIN, C.QUEM
FROM
  COMPROMISSO C
LEFT JOIN PESS0A_COMPROMISSO PC ON
  PC.ID_COMPROMISSO = C.IDENTIFICADOR
LEFT JOIN PESSOAFISICA PF ON
  PF.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PF
LEFT JOIN PESSOAJURIDICA PJ ON
  PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_PJ
LEFT JOIN CONTATO_PJ C_PJ ON
  C_PJ.IDENTIFICADOR = PC.ID_PESSOA AND PC.TIPO_PESSOA = :TIPO_PESSOA_C_PJ
WHERE
C.DATA BETWEEN :DATA_01 AND :DATA_02 AND
COALESCE(C.TEXTO,'') CONTAINING :TEXTO_ AND
COALESCE(PJ.NOME,'')||COALESCE(PF.NOME,'')||COALESCE(C_PJ.NOME,'') CONTAINING :NOME AND
C.OPCAO IN (:OPCAO_01, :OPCAO_02, :OPCAO_03)
INTO :IDENTIFICADOR, :DATA, :HORA, :TEXTO, :OPCAO, :PUBLICO, :LOGIN, :QUEM
DO

note que acima não tem mais o condicional de login. será retornado tudo que atende às condições, independente do login.

daí, você condiciona o retorno da stored procedure, pois ela funciona da mesma forma que uma tabela comum:

select * from retornacompromissos(0, 1, 2, '', '', current_date, current_date, 0, 1, 2) -- não passa mais o login
where login in ('ASAP', 'ADMIN')

fazendo dessa forma, você pode montar a lista de logins em tempo de execução.

var
  sSQL, sListaLogin: string;
  nLista: word;
begin
  // note que não passa mais o login
  sSQL := 'select * from retornacompromissos(:param1, :param2, :param3, :param4, :param5, :param6, :param7, :param8, :param9, :param10)'

  if lLoginEspecifico then
  begin
    sListaLogin := '';
    for nLista := 0 to lstListaLogin.count-1 do
    begin
      if sListaLogin <> '' then sListaLogin := sListaLogin + ', ';
      sListaLogin := sListaLogin + lstListaLogin.Items[nLista];
    end;

    sSQL := sSQL + ' where LOGIN in (' + sListaLogin + ')';
  end

  TIBXQuery.SQL.Text := sSQL;
  TIBXQuery.Params()...
  TIBXQuery.Open;

end;


GOSTEI 0
POSTAR