Вопрос

Я разработчик 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, параметры имеют проблемы с 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;

Я заменил только один из параметров, но вы должны подумать о том, чтобы заменить их все, поскольку это улучшит производительность сервера, включив его кэш предложений.

Возвращаясь к вашему первоначальному вопросу, я думаю, что единственный способ реорганизации всего приложения - это иметь программу рефакторинга, которая может проанализировать ваш код, найти эти ситуации и следовать шаблону, чтобы заменить один кусок кода другим.

Я не знаю ни одного инструмента, который может сделать это в настоящее время.

Возможно, использование находки/замены, которое поддерживает регулярные выражения, может помочь вам, но это, безусловно, не будет исправить случаи в одном проходе. Вам придется запустить серию фаз замены, чтобы преобразовать ваш код из того, что вы хотите, до того, что вы хотите.

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