2013-11-08 6 views
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") '; 

Программа генерирует исключение:

недопустимое имя столбца 'дд/мм/гггг'.

Я установил другой запрос для сравнения:

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

Поскольку ваш SQLServer поддерживает IIF, вы, похоже, находитесь на версии 2012. Тем не менее, вам придется исправить все/большинство запросов, что было бы oaccasion для переключения на параметры, как и для PayDate, в любом месте , здесь, например, для cashNum = '+ IntToStr (i). Возможно, вы могли бы переместить все SQL-запросы в качестве констант в один (resoure) файл для корректировок futur. – bummi

+0

Спасибо. Я заменяю все параметры на дату, через 'qryTemp.Parameters.ParamByName ('D'). Значение: = DateTimeToStr (Date);' –

+3

Что такое определение столбца для PayDate, это datetime или строка? – whosrdaddy

ответ

4

Предполагая, что 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. для более ранних версий использовать выражение CASE.


В старых версиях 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) 
... 
+0

Thans. Я уже использую SQL Server 2012 express. –

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

Я стараюсь. Это не работа. –

+0

Я думаю, что формат даты неверен в «формате» !. Это должно быть «dd/MM/yyyy» вместо «dd/mm/yyyy». Потому что ** мм ** - минуты. Ректифицированный. Попробуй еще раз. –

+0

Минуты NN, так что это не проблема ... – whosrdaddy

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; 

я заменил только один из параметров, но вы должны рассмотреть вопрос о замене всех из них, так как это позволит повысить производительность сервера, позволяя его кеш предложения.

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

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

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

Смежные вопросы