2016-03-09 47 views
1

我在使用TADOQuery組件時出現了一個奇怪的問題。在C++ Builder 6和Windows 7 64位上的ADOQuery

我目前的工作地點是使用在Windows XP虛擬機上運行的Borland C++ Builder應用程序。因此,我們希望轉移到Windows 7並將其作爲終端提供服務,這樣員工就可以使用Windows 10接收新計算機,而無需在每臺計算機上再次創建Win XP虛擬機。

目前該應用程序使用BDE組件,它在XP上運行良好。我們創建了一個用於測試的Win7 64位虛擬機,並安裝了必要的驅動程序等,但是BDE無法正常工作。當我嘗試通過Borland附帶的SQL Explorer進行登錄時,它只是掛起。它發送請求但從未得到響應。我花了一個多星期的時間試圖調試這個問題,但沒有得到它的任何地方。

無論如何,我放棄了BDE,並想嘗試改用ADO。所以我開始時只需創建一個TDBGrid並使用ADO組件填充數據。它在XP和Win7上都很棒!所以現在我試圖將應用程序的BDE組件(TDataBase,TQuery等)轉換爲ADO組件。

嘗試使用參數時遇到了一個有趣的問題。下面是一個查詢示例:

SELECT t1.SEC_CODE, t1.CODE, t1.CTRL_NUM, t1.CHECK_CODE, 
t1.CHECK_NO, t1.CLIENT_ID, t1.AMOUNT, t1.TRANS_NO, decode(t2.prefix,null,t2.name,t2.name||', '||t2.prefix) as fullName, 
t1.ENTRY_DATE, t1.DEPOSIT_DATE, t1.ACCT_COMMENT, t2.NAME, t2.PREFIX 
FROM ACCOUNTING.ACCT_CHECK_IN t1, OISC.CLIENT t2 
WHERE 
(:BEN =1 OR (:BEN =0 AND t1.ENTRY_DATE=:DATE) 
OR (:BEN =2 AND t1.DEPOSIT_DATE IS NOT NULL) 
OR (:BEN =3 AND t1.DEPOSIT_DATE IS NULL)) AND 
(:ALEX =1 OR (:ALEX =0 AND t1.ENTRY_DATE>=:DATE1 AND 
t1.ENTRY_DATE<=:DATE2) OR (:ALEX =2 AND t1.DEPOSIT_DATE>=:DATE1 
AND t1.DEPOSIT_DATE<=:DATE2)) 
AND T2.CLIENT_ID(+)=T1.CLIENT_ID 

ORDER BY t1.SEC_CODE, t1.CHECK_CODE, fullName, t1.check_no 

請不要注意參數的名字,這對我來說有點滑稽,但你們將無法進行連接。

這裏的第一個問題是,即使某些參數是相同的名稱,ADO將它們視爲單個參數!所以,如果我這樣做:

checkload1->Parameters->ParamByName("BEN")->Value=0 

ADO不會取代0「BEN」的每一次出現,我結束了一個結果集的0記錄!相反,我使用的是:

checkload1->Parameters->Items[0]->Value = 0; // BEN param 
checkload1->Parameters->Items[1]->Value = 0; 
checkload1->Parameters->Items[3]->Value = 0; 
checkload1->Parameters->Items[4]->Value = 0; 

基本上,將基於參數索引的每個「BEN」參數替換爲0。

這給我帶來了結果,但不是馬上。

所以,它是如何工作的:應用程序是一個基於樹的用戶界面。有一個節點會顯示「今天的支票」,並在展開時顯示今天的支票。好極了,現在這個BDE的工作很棒,我只分配參數值一次,它會自動替換它看到的所有「BEN」等。

當使用ADO組件時,我展開「Today's Checks」節點和代碼運行,加載參數,激活查詢組件,我沒有結果!所以節點保持摺疊狀態。如果我再次點擊+標誌展開樹,它會加載檢查!之後每次都會加載它們。

因此,在應用程序中有一個日期選項,默認爲今天的日期。如果我將其更改爲昨天的日期,我仍然得到今天的檢查...這就像參數沒有得到更新。如果我試着從一開始就用不同的日期開始,我沒有得到任何結果!它會帶來今天的結果,但在此之後它不會接受不同的日期。

我調試了代碼和日期正在改變,但由於某些原因,參數沒有改變。這裏是我的代碼塊:

checkload1->Filter="" ; 
checkload1->Filtered=false ; 
switch(params) 
    { 
    case 0: checkload1->Parameters->Items[0]->Value = 1; // BEN param 
      checkload1->Parameters->Items[1]->Value = 1; 
      checkload1->Parameters->Items[3]->Value = 1; 
      checkload1->Parameters->Items[4]->Value = 1; 
      // ALEX Param 
      checkload1->Parameters->Items[5]->Value = 0; 
      checkload1->Parameters->Items[6]->Value = 0; 
      checkload1->Parameters->Items[9]->Value = 0; 
      checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS NOT IN ('Refunded', 'Posted') "; 
      break ; 
    case 1: checkload1->Parameters->Items[0]->Value = 0; // BEN param 
      checkload1->Parameters->Items[1]->Value = 0; 
      checkload1->Parameters->Items[3]->Value = 0; 
      checkload1->Parameters->Items[4]->Value = 0; 
      checkload1->Parameters->ParamByName("DATE")->Value=FormatDateTime("dd-mmm-yyyy", Date()) ; 
      checkload1->SQL->Strings[13] = " "; 
      break ; 
    case 2: checkload1->Parameters->Items[0]->Value = 2; // BEN param 
      checkload1->Parameters->Items[1]->Value = 2; 
      checkload1->Parameters->Items[3]->Value = 2; 
      checkload1->Parameters->Items[4]->Value = 2; 
      //ALEX param 
      checkload1->Parameters->Items[5]->Value = 2; 
      checkload1->Parameters->Items[6]->Value = 2; 
      checkload1->Parameters->Items[9]->Value = 2; 
      checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS IN ('Deposited') "; 
      break ; 
    case 3: checkload1->Parameters->Items[0]->Value = 3; // BEN param 
      checkload1->Parameters->Items[1]->Value = 3; 
      checkload1->Parameters->Items[3]->Value = 3; 
      checkload1->Parameters->Items[4]->Value = 3; 
      //ALEX param 
      checkload1->Parameters->Items[5]->Value = 0; 
      checkload1->Parameters->Items[6]->Value = 0; 
      checkload1->Parameters->Items[9]->Value = 0; 
      checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS IN ('Held') "; 
      break ; 
    } 
if(!mainform->date1->Checked){ 
checkload1->Parameters->Items[5]->Value = 1; 
checkload1->Parameters->Items[6]->Value = 1; 
checkload1->Parameters->Items[9]->Value = 1; 
} 
checkload1->Parameters->Items[7]->Value = FormatDateTime("dd-mmm-yyyy", fromdate); 
checkload1->Parameters->Items[10]->Value = FormatDateTime("dd-mmm-yyyy", fromdate); 
checkload1->Parameters->Items[8]->Value = FormatDateTime("dd-mmm-yyyy", todate); 
checkload1->Parameters->Items[11]->Value = FormatDateTime("dd-mmm-yyyy", todate); 

if(filters != "") checkload1->SQL->Strings[12] = filters; 
else checkload1->SQL->Strings[12]=" " ; 
checkload1->Prepared = true; 
checkload1->Active=true ; 

有人可以有經驗告訴我這個嗎?

我知道這是古老的東西,但這些程序的字面意思是15 - 20年前,他們正在轉向基於Web的用戶界面,但仍在構建中。在此之前,我需要將所需的更改/更新作爲我工作的一部分。

回答

1

好吧,我得到了這個工作!

對於那些與BDE一起努力工作在Windows 7 64位上的人,這裏有一個解決方案!請記住我正在處理的數據庫是使用C++ Builder 6構建的Oracle 8i和Borland C++應用程序。

請按照照片和箭頭。我試圖把每張照片都帶上自己的評論,但是這個網站說我不能發佈2個以上的鏈接......與他們見面,所以我把所有的照片放在一張照片上。

Follow the arrows and hopefully you can connect it with my comments below.

這TQuery的例如正在尋找bnetdata作爲數據庫。太棒了,在下一張圖片中,我們添加了一個ADOConnection組件

單擊突出顯示的連接字符串。

選擇使用連接字符串,然後單擊構建。

選擇突出顯示的提供程序,然後單擊下一步。

檢查使用數據源名稱,然後單擊箭頭以選擇一個。請注意,您稍後將輸入用戶名和密碼並檢查是否允許保存密碼。

選擇與BDE組件使用的數據源相同的數據源。請注意,這是ODBC管理器中您的系統DSN下的源之一。如果它不在那裏,那就創建一個。

這是來自ODBC管理員的一個鏡頭。請注意,這仍然是XP環境。你將需要在Windows 7機器上創建相同的數據源(在我的情況下是bnetdata)。

現在點擊高級並從列表中選擇readwrite選項。

單擊ADOConnection組件上的OK後,就像您現在在對象檢查器中看到的一樣。看看突出顯示的區域。現在,我們需要將連接屬性設置爲true。當你這樣做時,它會要求你登錄到數據庫。輸入用戶名和密碼,然後單擊確定。連接屬性現在將成爲真實的。之後,您需要將LoginPrompt屬性設置爲false。現在點擊保存項目。假設你有BDE數據庫組件,點擊它,然後清除別名和驅動程序名稱,然後把你的數據庫名稱放在databaseName屬性下(在我的情況下它是bnetdata)。

保存項目並在XP中編譯。複製應用程序並將其粘貼到Windows 7機器中,然後雙擊它,它就會起作用!我已成功轉換所有應用程序以在Windows 7上運行。最難的部分是安裝Borland並讓Windows 7在ODBC管理器的「驅動程序」選項卡下識別Oracle ODBC驅動程序。

再一次,Borland安裝附帶的SQL Explorer不起作用。所以,我仍然需要在我的Windows XP虛擬機上開發,但用戶可以使用Windows 7虛擬機中的應用程序作爲Windows服務器上的終端...適用於我!

希望這可以幫助別人!

編輯:

我也試過的Microsoft OLE DB提供程序的Oracle中的ADOConnection,它也工作了。沒有看到對速度或性能產生可衡量的影響。兩者似乎都以相同的方式執行。我很驚訝如何添加ADOConnection組件允許應用程序連接到數據庫並像在XP中一樣工作!

也只是爲了清除問題,您不需要更改應用程序中的BDE組件。只需要添加ADOConnection和所有其他組件即可(BDE組件)。我試圖轉換爲使用ADO組件,但沒有必要了。

Microsoft OLE DB Provider for Oracle