Pergunta

Eu sou desenvolvedor Java.Eu tenho um programa antigo em Delphi.Na versão antiga eles trabalham com mdb.Eu consertei para conexão com SQL Server.Todas as consultas SQL são implementadas com TAdoQuery.

qryTemp.SQL.Text:='select  sum(iif(ComeSumm>0,comesumm,0)),sum(iif(lostSumm>0,lostsumm,0)) from cash '+
   'where (IdCashClause is null or idcashclause<>8) '+
  ' and cashNum='+IntToStr(i)+
  ' and CashType=0'+
  ' and format(PayDate,"dd/mm/yyyy")=format('''+DateToStr(Date)+''',"dd/mm/yyyy") ';

O programa lança uma exceção:

Nome de coluna inválido 'dd/mm/yyyy'.

Corrigi outra consulta para comparação:

 qryTemp.SQL.Text:=' select top 1 iif(ComeSumm>0,comesumm,0) from cash '
                     +' where idCashReason=1 and idCashClause=8 and cashNum='+IntToStr(i)
                     +' and PayDate<:D'
                     +' order by payDate desc';
qryTemp.Parameters.ParamByName('D').Value:=DateTimeToStr(Date);

Posso corrigir rapidamente todas as consultas para trabalhar com o SQL Server sem reescrever todo o projeto?

Foi útil?

Solução

Assumindo PayDate é definido como date/datetime No MSSQL, você pode usar parâmetros da seguinte forma:

qryTemp.SQL.Text:=' select top 1 iif(ComeSumm>0,comesumm,0) from cash '
                     +' where idCashReason=1 and idCashClause=8 and cashNum='+IntToStr(i)
                     +' and PayDate<:D'
                     +' order by payDate desc';
qryTemp.Parameters.ParamByName('D').Value := Date;
qryTemp.Parameters.ParamByName('D').DataType := ftDateTime;

Eu também mudaria cashNum para o parâmetro ie:

...
+' where idCashReason=1 and idCashClause=8 and cashNum=:cashNum'+
...
qryTemp.Parameters.ParamByName('cashNum').Value := i;

Sempre prefira usar tipos de dados compatíveis com seus parâmetros, em vez de formatar e usar strings. O SQL não precisa adivinhar seus tipos de dados se você pode defini -los explicitamente.

Observação: IIF foi introduzido no SQL Server 2012. Para uso da versão mais antiga CASO expressão.


Nas versões não-unicode antigas Delphi, os parâmetros têm problemas com o Unicode.
Então, se você não Use parâmetros que você pode usar o seguinte:

function DateTimeToSqlDateTime(const DT: TDateTime): WideString;
begin
  Result := FormatDateTime('yyyy-MM-dd', DT) + ' ' + FormatDateTime('hh:mm:ss', DT);
end;

function SqlDateTimeStr(const DT: TDateTime; const Is_MSSQL: Boolean): WideString;
var
  S: WideString;
begin
  S := DateTimeToSqlDateTime(DT);
  if Is_MSSQL then
    Result := Format('CONVERT(DATETIME, ''%s'', 102)', [S]) 
  else
    Result := Format('#%s#', [S]); // MS-ACCESS
end;

E sua consulta parecerá a seguir:

...
+' and PayDate<' + SqlDateTimeStr(Date, True)
...

Outras dicas

É muito provável que o PayDate A coluna é declarada como DATE no cash tabela. Considerando isso, seu parâmetro deve ser um TDateTime e não um string, assim:

qryTemp.SQL.Text:=' select top 1 iif(ComeSumm>0,comesumm,0) from cash '
                     +' where idCashReason=:cashReason and idCashClause=8 and cashNum='+IntToStr(i)
                     +' and PayDate<:D'
                     +' order by payDate desc';
qryTemp.Parameters.ParamByName('D').Value := Date;

Substituí apenas um dos parâmetros, mas você deve substituir todos eles, pois isso melhorará o desempenho do servidor, permitindo o cache da frase.

Voltando à sua pergunta original, acho que a única maneira de refatorar todo o aplicativo seria ter um programa de refatoração que pudesse analisar seu código, encontrar essas situações e seguir um padrão para substituir uma peça de código por outra.

Não conheço nenhuma ferramenta que possa fazer isso agora.

Talvez usar o Find/Substituir que suporta expressões regulares possa ajudá -lo, mas certamente não consertará os casos em um único passe. Você teria que executar uma série de fases de substituição para transformar seu código do que é o que você deseja.

DateToStr usa informações de localização contidas em variáveis ​​globais para formatar a sequência de datas.Talvez este seja o problema.

Você pode tentar FormatDateTime:

qryTemp.SQL.Text:='select  sum(iif(ComeSumm>0,comesumm,0)),sum(iif(lostSumm>0,lostsumm,0)) from cash '+
   'where (IdCashClause is null or idcashclause<>8) '+
  ' and cashNum='+IntToStr(i)+
  ' and CashType=0'+
  ' and format(PayDate,"dd/MM/yyyy")='''+FormatDateTime('dd/mm/yyyy',Date)+'''';
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top