2

私は Java 開発者です。Delphi に古いプログラムがあります。古いバージョンでは、mdb. SQL Server と接続できるように修正しました。すべての SQL クエリは で実装され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") ';

プログラムは例外をスローします。

列名 'dd/mm/yyyy' が無効です。

比較のために他のクエリを修正しました:

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

プロジェクト全体を書き直さずに、SQL Server で動作するすべてのクエリをすばやく修正できますか?

4

3 に答える 3

4

が MSSQL で/PayDateとして定義されていると仮定すると、次のようにパラメーターを使用できます。datedatetime

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;

cashNumパラメータにも変更します。

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

書式設定して文字列を使用するよりも、常に互換性のあるデータ型をパラメーターで使用することをお勧めします。データ型を明示的に定義できる場合、SQL はデータ型を推測する必要はありません。

注: IIFSQL Server 2012 で導入されました。古いバージョンではCASE式を使用します。


古い非 Unicode Delphi バージョンでは、パラメータに Unicode に関する問題があります。
したがって、パラメーターを使用しない場合は、次を使用できます。

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;

クエリは次のようになります。

...
+' and PayDate<' + SqlDateTimeStr(Date, True)
...
于 2013-11-08T09:35:16.617 に答える
2

列が表のようにPayDate宣言されている可能性が非常に高いです。それを考慮すると、次のように、パラメーターはではなく である必要があります。DATEcashTDateTimestring

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;

パラメータの 1 つだけを置き換えましたが、センテンス キャッシュを有効にすることでサーバーのパフォーマンスが向上するため、すべてのパラメータを置き換えることを検討する必要があります。

元の質問に戻ると、すべてのアプリケーションをリファクタリングする唯一の方法は、コードを解析し、それらの状況を見つけ、パターンに従ってコードを別のコードに置き換えるリファクタリング プログラムを用意することだと思います。

私は今それを行うことができるツールを知りません。

正規表現をサポートする検索/置換を使用すると役立つ場合がありますが、1回のパスでケースを修正することはできません. コードを現在の状態から目的の状態に変換するには、一連の置換フェーズを実行する必要があります。

于 2013-11-08T09:41:38.490 に答える