我是Java开发人员。我在德尔福有一些旧程序。在旧版本中,他们与 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合作的所有查询,而无需重写整个项目吗?

有帮助吗?

解决方案

假设 PayDate 被定义为 date/datetime 在MSSQL中,您可以使用以下参数:

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不需要猜测您的数据类型。

笔记: IIF 是在SQL Server 2012中引入的。用于较旧版本 案子 表达。


在较旧的非固定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)
...

其他提示

很有可能 PayDate 列被称为 DATE 在里面 cash 桌子。考虑到这一点,您的参数应该是 TDateTime 而不是一个 string, , 像这样:

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;

我仅替换了一个参数,但是您应该考虑替换所有参数,因为这将通过启用其句子缓存来改善服务器性能。

回到您的原始问题,我想重构所有应用程序的唯一方法是制定一个可以解析您的代码,找到这些情况并遵循模式以另一个代码替换一件代码的重构程序。

我不知道现在可以做到这一点的工具。

也许使用find/替换支持正则表达式可以帮助您,但是它肯定不会在一次通过中解决案例。您将必须运行一系列替换阶段,以将代码从它的原状转换为您想要的。

DateToSTR使用全局变量中包含的本地化信息来格式化日期字符串。也许这是问题。

您可以尝试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)+'''';
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top