Question

Je suis un développeur Java. J'ai un ancien programme à Delphi. Dans la vieille version, ils travaillent avec mdb. Je l'ai corrigé pour la connexion avec SQL Server. Toutes les requêtes SQL sont implémentées avec 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") ';

Le programme lance une exception:

Nom de la colonne non valide 'dd / mm / yyyy'.

J'ai corrigé une autre requête pour comparaison:

 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);

Puis-je résoudre rapidement toutes les requêtes pour travailler avec SQL Server sans réécrire l'ensemble du projet?

Était-ce utile?

La solution

En supposant PayDate est défini comme date/datetime Dans MSSQL, vous pouvez utiliser les paramètres comme suit:

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;

Je changerais aussi cashNum au paramètre IE:

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

Préférez toujours utiliser des types de données compatibles avec vos paramètres, plutôt que la mise en forme et l'utilisation de chaînes. SQL n'a pas besoin de deviner vos types de données si vous pouvez les définir explicitement.

Noter: IIF a été introduit dans SQL Server 2012. Pour une version ancienne CAS expression.


Dans les versions de Delphi non Unicode plus anciennes, les paramètres ont un problème avec Unicode.
Donc, si tu ne le faites pas Utilisez des paramètres que vous pouvez utiliser ce qui suit:

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;

Et votre requête sera la suivante:

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

Autres conseils

Il est très probable que le PayDate la colonne est déclarée comme DATE dans le cash table. Considérant que votre paramètre devrait être un TDateTime Et pas un string, comme ça:

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;

Je n'ai remplacé qu'un seul des paramètres, mais vous devriez envisager de les remplacer tous, car cela améliorera les performances du serveur en permettant le cache de sa phrase.

Revenant à votre question initiale, je suppose que la seule façon de refactor toute l'application serait d'avoir un programme de refactorisation qui pourrait analyser votre code, trouver ces situations et suivre un modèle pour remplacer un morceau de code par un autre.

Je ne connais aucun outil qui peut le faire de nos jours.

Peut-être que l'utilisation de trouver / remplacer qui prend en charge les expressions régulières peut vous aider, mais cela ne corrigera certainement pas les cas en une seule passe. Vous devrez exécuter une série de phases de remplacement afin de transformer votre code de ce que vous voulez.

DateToStr utilise les informations de localisation contenues dans les variables globales pour formater la chaîne de date. C'est peut-être le problème.

Vous pouvez essayer 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)+'''';
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top