Ajuda com strore procedure 2
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?
Como posso resolver isso?
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
Curtidas 0
Respostas
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')
Atenciosamente Eriley
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
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?
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
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
09/08/2010
Amigo... ERILEY VILAGRANDE BARBOSA tentei o que você sugeriu ... mas não consegui.
Minha SP esta assim:
Onde estou errando?
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
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
09/08/2010
Teste com apenas UM login:
ParamByName('LOGIN').AsString := QuotedStr('ASAP'); //Login
Não dá erro nenhum. Apenas não retorna nada.
ParamByName('LOGIN').AsString := QuotedStr('ASAP'); //Login
Não dá erro nenhum. Apenas não retorna nada.
GOSTEI 0
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
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
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
09/08/2010
Vamos nos ater a sua stored procedure como está abaixo:
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
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
09/08/2010
Meu código:
Mas não funciona ainda...
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
09/08/2010
Acredito ser problema da passagem de parâmetro...
No IBCONSOLE faço assim e funciona:
Como passar a lista de logins usando o TIBXQuery? Acredito que é aqui que estou errando....
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
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
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;
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