Erro em sql dinâmica.
Eu tenho uma consulta usando query dinâica, que funciona bem. Acontece que eu precisei incluir um BETWEEN, e aí a ´vaca foi pro brejo´. Como fazê-las funcionar bem, eis abaixo a sql:
var
sql: string;
i: integer;
begin
sql:=´Select * From Cliente where´;
If Length(Tipo.Text) > 0
then Sql := Sql + ´ TIPO = ´´+Tipo.Text+´´ AND´;
If (Length(Data5.Text)) and (Length(Data6.Text)) > 0
then Sql := Sql + ´ Data between ´´+data5.Text+´´ AND ´´+data6.Text+´´´;
If Copy(Sql,Length(Sql)-2,3) = ´AND´
Then Delete(Sql,Length(Sql)-2,3);
If Copy(Sql,Length(Sql)-4,5) = ´WHERE´
Then Delete(Sql,Length(Sql)-4,5);
Cliente.SQL.Text:=sql;
Cliente.Active:=True;
sem a linha do between, ela funciona bem.
var
sql: string;
i: integer;
begin
sql:=´Select * From Cliente where´;
If Length(Tipo.Text) > 0
then Sql := Sql + ´ TIPO = ´´+Tipo.Text+´´ AND´;
If (Length(Data5.Text)) and (Length(Data6.Text)) > 0
then Sql := Sql + ´ Data between ´´+data5.Text+´´ AND ´´+data6.Text+´´´;
If Copy(Sql,Length(Sql)-2,3) = ´AND´
Then Delete(Sql,Length(Sql)-2,3);
If Copy(Sql,Length(Sql)-4,5) = ´WHERE´
Then Delete(Sql,Length(Sql)-4,5);
Cliente.SQL.Text:=sql;
Cliente.Active:=True;
sem a linha do between, ela funciona bem.
Paulo
Curtidas 0
Respostas
Motta
18/09/2003
O problema está na forma que o sql de seu bd formata a data.
No Oracle seria algo assim
data between to_date(´01-sep-03´,´dd-mmm-yy´) and
to_date(´18-sep-03´,´dd-mmm-yy´)
ou seja vc terá de formatar a data
outra solucao
var
sql: string;
i: integer;
begin
sql:=´Select * From Cliente where´;
If Length(Tipo.Text) > 0
then Sql := Sql + ´ TIPO = ´´+Tipo.Text+´´ AND´;
If (Length(Data5.Text)) and (Length(Data6.Text)) > 0
then Sql := Sql + ´ Data between ´´+´:d1´+´´ AND ´´+´:d2´+´´´;
If Copy(Sql,Length(Sql)-2,3) = ´AND´
Then Delete(Sql,Length(Sql)-2,3);
If Copy(Sql,Length(Sql)-4,5) = ´WHERE´
Then Delete(Sql,Length(Sql)-4,5);
Cliente.SQL.Text:=sql;
cliente.params[0].AsDateTime := strtodate(edit1.text);
cliente.params[1].AsDateTime := strtodate(edit2.text);
Cliente.Active:=True;
desde que o formato da data nos edits seja válido
No Oracle seria algo assim
data between to_date(´01-sep-03´,´dd-mmm-yy´) and
to_date(´18-sep-03´,´dd-mmm-yy´)
ou seja vc terá de formatar a data
outra solucao
var
sql: string;
i: integer;
begin
sql:=´Select * From Cliente where´;
If Length(Tipo.Text) > 0
then Sql := Sql + ´ TIPO = ´´+Tipo.Text+´´ AND´;
If (Length(Data5.Text)) and (Length(Data6.Text)) > 0
then Sql := Sql + ´ Data between ´´+´:d1´+´´ AND ´´+´:d2´+´´´;
If Copy(Sql,Length(Sql)-2,3) = ´AND´
Then Delete(Sql,Length(Sql)-2,3);
If Copy(Sql,Length(Sql)-4,5) = ´WHERE´
Then Delete(Sql,Length(Sql)-4,5);
Cliente.SQL.Text:=sql;
cliente.params[0].AsDateTime := strtodate(edit1.text);
cliente.params[1].AsDateTime := strtodate(edit2.text);
Cliente.Active:=True;
desde que o formato da data nos edits seja válido
GOSTEI 0
Ljr
18/09/2003
Acho que com estas alteracoes o codigo ira funcionar.
var
sql: string;
i: integer;
Par: Boolean
begin
sql:=´Select * From Cliente where´;
If Length(Tipo.Text) > 0 then
Sql := Sql + ´ TIPO = ´´+Tipo.Text+´´ AND´;
{ If (Length(Data5.Text)) and (Length(Data6.Text)) > 0 then
Sql := Sql + ´ Data between ´´+data5.Text+´´ AND ´´+data6.Text+´´´;}
If (Length(Data5.Text)) and (Length(Data6.Text)) > 0 then
begin
Sql := Sql + ´ Data between :Dini AND :Dfim´;
Par:= True;
end;
If Copy(Sql,Length(Sql)-2,3) = ´AND´ Then
Delete(Sql,Length(Sql)-2,3);
If Copy(Sql,Length(Sql)-4,5) = ´WHERE´ Then
Delete(Sql,Length(Sql)-4,5);
Cliente.SQL.Text:=sql;
if Par then
begin
cliente.ParamByName(´DINI´).Value:= StrToDate(data5.Text);
cliente.ParamByName(´DFIM´).Value:= StrToDate(data6.Text);
end;
Cliente.Open;
end;
So nao testei, para ver o resultado.
var
sql: string;
i: integer;
Par: Boolean
begin
sql:=´Select * From Cliente where´;
If Length(Tipo.Text) > 0 then
Sql := Sql + ´ TIPO = ´´+Tipo.Text+´´ AND´;
{ If (Length(Data5.Text)) and (Length(Data6.Text)) > 0 then
Sql := Sql + ´ Data between ´´+data5.Text+´´ AND ´´+data6.Text+´´´;}
If (Length(Data5.Text)) and (Length(Data6.Text)) > 0 then
begin
Sql := Sql + ´ Data between :Dini AND :Dfim´;
Par:= True;
end;
If Copy(Sql,Length(Sql)-2,3) = ´AND´ Then
Delete(Sql,Length(Sql)-2,3);
If Copy(Sql,Length(Sql)-4,5) = ´WHERE´ Then
Delete(Sql,Length(Sql)-4,5);
Cliente.SQL.Text:=sql;
if Par then
begin
cliente.ParamByName(´DINI´).Value:= StrToDate(data5.Text);
cliente.ParamByName(´DFIM´).Value:= StrToDate(data6.Text);
end;
Cliente.Open;
end;
So nao testei, para ver o resultado.
GOSTEI 0
Paulo
18/09/2003
Mota, eu fiz como vc disse: Agora dá o erro, que não é possível o campo data ficar vazio. Esta consulta(dinâmica), é feita exatamente para isso, ou seja, alguns campos serem preenchidos ou não.
Eu tenho dois campos:
1º - Uma combobox, onde eu entro com o tipo de imóvel a ser consultado
2º - Há dois maskedit, para formatar a data. A consulta deve-se fazer da seguinte forma:
Ou eu entro com todos os dados, ou eu entro só com o tipo de imóvel ou o período, e a consulta deve prosseguir. Eu tenho outra consulta semelhante a esta, só que com muito mais campos, como, Tipo, Localização, Bairro, Valor e etc.. e a consulta funciona, tanto eu preencher todos os campos ou somente um ou alguns deles(Query Dinâmica). É isto o que eu quero, só que com períodos de datas(BETWEEN).
Eu tenho dois campos:
1º - Uma combobox, onde eu entro com o tipo de imóvel a ser consultado
2º - Há dois maskedit, para formatar a data. A consulta deve-se fazer da seguinte forma:
Ou eu entro com todos os dados, ou eu entro só com o tipo de imóvel ou o período, e a consulta deve prosseguir. Eu tenho outra consulta semelhante a esta, só que com muito mais campos, como, Tipo, Localização, Bairro, Valor e etc.. e a consulta funciona, tanto eu preencher todos os campos ou somente um ou alguns deles(Query Dinâmica). É isto o que eu quero, só que com períodos de datas(BETWEEN).
GOSTEI 0
Motta
18/09/2003
que bd vc usa ?
tente apenas formatar a data .
no meu exemplo tinha um furo , pois se o controle que tem a data está vazio iria passar nulo para o parametro.
costumo fazer isto formatando a data no sql p/ o Oracle
tente apenas formatar a data .
no meu exemplo tinha um furo , pois se o controle que tem a data está vazio iria passar nulo para o parametro.
costumo fazer isto formatando a data no sql p/ o Oracle
GOSTEI 0
Paulo
18/09/2003
Eu uso Paradox. Ljr, fiz como vc disse, e dá o mesmo erro que o exemplo que o Mota me mandou, ou seja, / / , is not valid date, esse é o erro. Lembrando, que esta consulta é para informar ou não o período de datas. nem sempre ele(período) será informado, assim como o tipo nem sempre será informado. Se eu preencho o tipo mas não o período, então, dá o erro acima. Se eu preencho o período e não o Tipo, não dá erro e a consulta procede como eu gostaria.
GOSTEI 0
Motta
18/09/2003
exemplo de sql extraido do help do paradox
SELECT *
FROM Orders
WHERE (SaleDate <= ´1/23/1998´)
tente formatar a data assim entre aspas duplas e deve funcionar
SELECT *
FROM Orders
WHERE (SaleDate <= ´1/23/1998´)
tente formatar a data assim entre aspas duplas e deve funcionar
GOSTEI 0
Paulo
18/09/2003
Mota, não é o formato de data, mas é a pesquisa não está aceitando a data vazia, e eu preciso da consulta com data vazia também, por isso eu optei por query´s dinâmicas. Cmo foi declarado parâmetro, creio que por causa disso é que não aceita data vazia.
GOSTEI 0
Ljr
18/09/2003
Entao quando a data for nula qual deve ser o comportamento da query?
GOSTEI 0
Motta
18/09/2003
costumo fazer assim
query1.sql.add(´select *´);
query1.sql.add(´from tabela´);
// condicao obrig
query1.sql.add(´where campo1=12345´);
// condicao opcional
if edit1.text <> ´´ then
query1.sql.add(´ and campo2=´+edit1.text);
// outra opcional
if edit2.text <> ´´ then
query1.sql.add(´ and campo3<>´edit2.text);
só tome cuidado para que a sintaxe fique legal
query1.sql.add(´select *´);
query1.sql.add(´from tabela´);
// condicao obrig
query1.sql.add(´where campo1=12345´);
// condicao opcional
if edit1.text <> ´´ then
query1.sql.add(´ and campo2=´+edit1.text);
// outra opcional
if edit2.text <> ´´ then
query1.sql.add(´ and campo3<>´edit2.text);
só tome cuidado para que a sintaxe fique legal
GOSTEI 0
Adilsond
18/09/2003
begin with Cliente do begin if Active then Close; SQL.Clear; SQL.Add(´select *´); SQL.Add(´from Cliente´); if Trim(Tipo.Text) <> ´´ then SQL.Add(´where tipo = ´ + QuotedStr(Tipo.Text)); if (Trim(Data5.Text) <> ´/ /´) and (Trim(Data6.Text) <> ´/ /´) then begin if SQL.Count = 2 then SQL.Add(´where data between :dtini and :dtfin´) else SQL.Add(´ and data between :dtini and :dtfin´); ParamByName(´dtini´).AsDate := StrToDate(Data5.Text); ParamByName(´dtfin´).AsDate := StrToDate(Data6.Text); end else if (Trim(Data5.Text) <> ´/ /´) or (Trim(Data6.Text) <> ´/ /´) then begin if Trim(Data5.Text) = ´/ /´ then begin if SQL.Count = 2 then begin SQL.Add(´where (data is null´); SQL.Add(´ or data <= :dtfin)´); end else begin SQL.Add(´ and (data is null´); SQL.Add(´ or data <= :dtfin)´); end; ParamByName(´dtfin´).AsDate := StrToDate(Data6.Text); end else begin if SQL.Count = 2 then begin SQL.Add(´where (data is null´); SQL.Add(´ or data >= :dtini)´); end else begin SQL.Add(´ and (data is null´); SQL.Add(´ or data >= :dtini)´); end; ParamByName(´dtini´).AsDate := StrToDate(Data5.Text); end; end; Open; end; end;
GOSTEI 0
Paulo
18/09/2003
Deixa eu explicar melhor. As querys dinâmicas servem para, por exemplo, eu tenho cinco edits para consulta. Eu uso query dinâmica para não necessariamente usar todos os itens dos edits para satisfazer a consulta, consulta muito comum na Internet, assim: Digamos que eu tenha 4 combobox:
1ª - Localização
2ª - Bairro
3ª - Condomínio
4ª - Valor
Então o cliente ele quer, usar as quatros, a consulta vem pelas quatro. Mas um outro cliente, por exemplo, só quer o valor e o bairro, e assim por diante, por isso o uso de query dinâmica. Comigo é semelhante, só que ao invés de um campo fixo, direto, eu uso um período de datas e o tipo de imóvel. Se os campos de Data(Data_Ini e Data_Fim) estiverem vazios, a pesquisa vem só pelo tipo, ou seja, a data é ignorada, o contrário é válido também.
1ª - Localização
2ª - Bairro
3ª - Condomínio
4ª - Valor
Então o cliente ele quer, usar as quatros, a consulta vem pelas quatro. Mas um outro cliente, por exemplo, só quer o valor e o bairro, e assim por diante, por isso o uso de query dinâmica. Comigo é semelhante, só que ao invés de um campo fixo, direto, eu uso um período de datas e o tipo de imóvel. Se os campos de Data(Data_Ini e Data_Fim) estiverem vazios, a pesquisa vem só pelo tipo, ou seja, a data é ignorada, o contrário é válido também.
GOSTEI 0
Adilsond
18/09/2003
Então utilize apenas a primeira parte do código anterior:
begin with Cliente do begin if Active then Close; SQL.Clear; SQL.Add(´select *´); SQL.Add(´from Cliente´); if Trim(Tipo.Text) <> ´´ then SQL.Add(´where tipo = ´ + QuotedStr(Tipo.Text)); if (Trim(Data5.Text) <> ´/ /´) and (Trim(Data6.Text) <> ´/ /´) then begin if SQL.Count = 2 then SQL.Add(´where data between :dtini and :dtfin´) else SQL.Add(´ and data between :dtini and :dtfin´); ParamByName(´dtini´).AsDate := StrToDate(Data5.Text); ParamByName(´dtfin´).AsDate := StrToDate(Data6.Text); end; Open; end; end;
GOSTEI 0