سؤال

أنا مطور جافا. لدي بعض البرنامج القديم في دلفي. في الإصدار القديم يعملون معهم 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.
لذلك ، إذا كنت لا استخدم المعلمات التي يمكنك استخدام ما يلي:

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;

لقد استبدلت واحدة فقط من المعلمات ، ولكن يجب عليك التفكير في استبدالها جميعًا ، لأن هذا سيحسن أداء الخادم من خلال تمكين ذاكرة التخزين المؤقت للجملة.

بالعودة إلى سؤالك الأصلي ، أعتقد أن الطريقة الوحيدة لإعادة تهيئة كل التطبيق هي أن يكون لديك برنامج إعادة إنشاء يمكنه تحليل الكود الخاص بك ، والعثور على تلك المواقف واتباع نمط لاستبدال قطعة رمز أخرى.

لا أعرف أي أداة يمكنها القيام بذلك الآن.

ربما يمكن أن يساعدك استخدام Find/Replace الذي يدعم التعبيرات العادية ، ولكنه بالتأكيد لن يصلح الحالات في تمريرة واحدة. سيكون عليك تشغيل سلسلة من مراحل الاستبدال من أجل تحويل الكود الخاص بك من ما تريده.

يستخدم 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