문제

저는 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에서 소개되었습니다. 이전 버전 사용 사례 표현.


구형 비 유니 코드 델파이 버전에서는 매개 변수가 유니 코드에 문제가 있습니다.
그래서, 당신이 ~하지 않다 다음을 사용할 수있는 매개 변수를 사용하십시오.

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 테이블. 이를 고려할 때 매개 변수는 a입니다 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/Replare를 사용하면 도움이 될 수 있지만 한 번의 패스로 케이스를 해결하지는 않습니다. 코드를 원하는대로 바꾸려면 일련의 교체 단계를 실행해야합니다.

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