【问题标题】:TAdoquery date formatTAdoquery 日期格式
【发布时间】:2013-11-08 06:24:35
【问题描述】:

我是 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?

【问题讨论】:

  • 由于您的 SQLServer 支持 IIF,您似乎使用的是 2012 版。不过,您必须修复所有/大部分查询,这将是切换到参数的机会,就像您为PayDate,在任何地方,例如这里对于 cashNum='+IntToStr(i)。也许您可以将所有 SQL 作为 const 移动到单个(资源)文件中以供将来调整。
  • 谢谢。我用日期替换所有参数,通过qryTemp.Parameters.ParamByName('D').Value:=DateTimeToStr(Date);
  • PayDate 的列定义是什么,是日期时间还是字符串??
  • 格式为date

标签: delphi ado tadoquery


【解决方案1】:

假设PayDate在MSSQL中定义为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 就不需要猜测您的数据类型。

注意:IIF 是在 SQL 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)
...

【讨论】:

    【解决方案2】:

    很可能PayDate 列在cash 表中被声明为DATE。考虑到这一点,您的参数应该是 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;
    

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

    回到您最初的问题,我想重构所有应用程序的唯一方法是拥有一个重构程序,该程序可以解析您的代码,找到这些情况并遵循一种模式将一段代码替换为另一段代码。

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

    也许使用支持正则表达式的查找/替换可以帮助您,但它肯定不会一次性解决问题。您必须运行一系列替换阶段才能将您的代码从原来的样子转换成您想要的样子。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我认为“格式”中的日期格式不正确!。它必须是“dd/MM/yyyy”而不是“dd/mm/yyyy”。因为 mm 是分钟。纠正。再试一次。
      • 我认为你错了。 FORMAT 是 SQL Server 2012 的新功能。MM 是月份。 msdn.microsoft.com/es-es/library/ee634398.aspx@whosrdaddy
      • 问题是如果 paydate 是一个日期时间列,查询应该使用参数,而不是这种格式地狱
      • 当然可以。但我更愿意自己决定;-)
      • FORMAT 是 MS SQL 2012 中包含的新功能。如果您的 MS SQL 版本较早,请尝试使用 Convert。一个例子(西班牙语,对不起):3engine.net/wp/2011/09/…
      猜你喜欢
      • 2010-11-03
      • 2017-12-17
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      相关资源
      最近更新 更多