我是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") ';
该程序抛出异常:
列名无效&#39; dd / mm / yyyy&#39;。
我已修复其他查询以进行比较:
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的查询而无需重写整个项目?
答案 0 :(得分:4)
假设MSSQL中PayDate
被定义为date
/ datetime
,您可以使用以下参数:
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不需要猜测您的数据类型。
注意:SQL Server 2012中引入了IIF
。旧版本使用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)
...
答案 1 :(得分:2)
很有可能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;
我只替换了其中一个参数,但您应该考虑更换所有参数,因为这会通过启用其句子缓存来提高服务器性能。
回到原来的问题,我想重构所有应用程序的唯一方法就是有一个重构程序,可以解析你的代码,找到那些情况并按照一个模式来替换另一个代码。< / p>
我不知道现在能做到的任何工具。
也许使用支持正则表达式的find / replace可以帮助你,但它肯定不会在一次通过中修复案例。您必须运行一系列替换阶段才能将代码从原来的代码转换为您希望的代码。
答案 2 :(得分:1)
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)+'''';