全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2191
推到 Plurk!
推到 Facebook!

有關SQL查詢,欄位長度超過512的問題

缺席
coa
一般會員


發表:1
回覆:16
積分:13
註冊:2004-07-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-01-04 15:22:33 IP:203.75.xxx.xxx 訂閱
各位前輩們好, 以下為小弟寫程式的環境
OS: WinXP
DataBase : Oracle
Tool : BCB5.0 update1
今天小弟要從一個 Table A 查詢資料,欄位假設如下
家族 XXX XXX 親人(VARCHAR(6)) 子女(VARCHAR(6)) 財產(VARCHAR(512))
父 子 1,2,135.....
女 3,6,9.....

原始查詢的 SQL 程式碼如下:

void get_lot_db_data(String v_家族, String v_xxx, String v_親人, String v_子女)
{
int rc;
String sqlstr;

sqlstr.sprintf("SELECT 親人, 子女, 財產");
sqlstr.cat_sprintf(" FROM A");
sqlstr.cat_sprintf(" WHERE 家族 = '%s'", v_家族);
sqlstr.cat_sprintf(" AND xxx = '%s'", v_xxx);
sqlstr.cat_sprintf(" AND 親人 = '%s'", v_親人);
sqlstr.cat_sprintf(" AND 子女 = '%s'", v_子女);


sq->Close();
sq->SQL->Clear();
sq->SQL->Add(sqlstr);
sq->Prepare();
sq->Open();

if (sq->RecordCount == 0)
return;

for (rc = 0; rc < sq->RecordCount; rc )
{
親人 = sq->Fields->FieldByName("親人")->AsString;
.....processing

sq->Next();
}
}
但是因為財產的欄位過長(VARCHAR(512)), 所以造成 sq->RecordCount 回傳值為 -1
而造成 for loop 裡面的 code 無法執行,

目前小弟想出來的方法有三種, 其中第三種因為不知道要如何設定, 因此請各位不吝指教, 謝謝^^
方法三(未解): 元件TDatabase 裡的 Params 的設定, 想要將抓取欄位長度的設定加長
SERVER NAME=xxx
USER NAME=xxx
NET PROTOCOL=TNS
OPEN MODE=READ/WRITE
SCHEMA CACHE SIZE=8
LANGDRIVER=
SQLQRYMODE=
SQLPASSTHRU MODE=SHARED NOAUTOCOMMIT
SCHEMA CACHE TIME=-1
MAX ROWS=-1
BATCH COUNT=200
ENABLE SCHEMA CACHE=FALSE
SCHEMA CACHE DIR=
ENABLE BCD=FALSE
ENABLE INTEGERS=FALSE
LIST SYNONYMS=NONE
ROWSET SIZE=20
BLOBS TO CACHE=64
BLOB SIZE=32
OBJECT MODE=TRUE
DATABASE NAME=
ODBC DSN=xxx
PASSWORD=xxx

原本以為是將 SCHEMA CACHE SIZE=8 改為 11(2的11次方 = 2048)
或是 BATCH COUNT=200 改為 2048, 但是都沒有用

方法一(可以正確執行): 使用 sq->Eof 判斷是否為最後一筆 Record
//for (rc = 0; rc < sq->RecordCount; rc )-->換成
while (!sq->Eof)
{
親人 = sq->Fields->FieldByName("親人")->AsString;
.....processing

sq->Next();
}

方法二(可以正確執行): 將財產資料另外查詢
sqlstr.sprintf("SELECT 親人, 子女");
sqlstr.cat_sprintf(" FROM A");
sqlstr.cat_sprintf(" WHERE 家族 = '%s'", v_家族);
sqlstr.cat_sprintf(" AND xxx = '%s'", v_xxx);
sqlstr.cat_sprintf(" AND 親人 = '%s'", v_親人);
sqlstr.cat_sprintf(" AND 子女 = '%s'", v_子女);


sq->Close();
sq->SQL->Clear();
sq->SQL->Add(sqlstr);
sq->Prepare();
sq->Open();

if (sq->RecordCount == 0)
return;

for (rc = 0; rc < sq->RecordCount; rc )
{
親人 = sq->Fields->FieldByName("親人")->AsString;

.....processing

sqlstr.sprintf("SELECT 財產");
sqlstr.cat_sprintf(" WHERE 家族 = '%s'", v_家族);
sqlstr.cat_sprintf(" AND xxx = '%s'", v_xxx);
sqlstr.cat_sprintf(" AND 親人 = '%s'", v_親人);
sqlstr.cat_sprintf(" AND 子女 = '%s'", v_子女);

sq2->Close();
sq2->SQL->Clear();
sq2->SQL->Add(sqlstr);
sq2->Prepare();
sq2->Open();

財產 = sq->Fields->FieldByName("財產")->AsString;

sq->Next();
}

pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-01-04 17:48:19 IP:61.219.xxx.xxx 未訂閱
插個提外話, Database Name, Table Name, Field Name 等建議不要使用中文, 避免以後升級或移植可能發生不必要的問題
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
coa
一般會員


發表:1
回覆:16
積分:13
註冊:2004-07-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-01-04 18:47:39 IP:203.75.xxx.xxx 訂閱
To pcboy2 :
謝謝您的建議, 我在文章裡面所提的 Table Name, Field Name 其實只是我舉例來說明的而已.
實際上在公司的 DataBase Name, Table Name, Field Name 的 Naming 都是英文
如果是用中文的話, 我應該還不用寫程式寫到抱怨, 我老闆可能早就已經發 mail 罵人了XD
coa
一般會員


發表:1
回覆:16
積分:13
註冊:2004-07-18

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-01-09 10:39:32 IP:59.124.xxx.xxx 訂閱
不好意思麻煩各位了,
小弟一開始就犯了個錯=>沒先在 Help 裡面找Orz
TBDEDataSet::RecordCount
Note: Use RecordCount with care, because record counting can be a costly operation, especially for SQL queries that return large result sets. Generally, an application should only use RecordCount with Paradox and dBASE tables.
另外, 小弟在 Delphi 的討論區找到相關的討論, 可以一開始就抓到 Record 的總數,
而不必用 !sq->Eof 在抓資料的同時再統計數量
http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=76743 sryang #02, #04篇的說明
http://delphi.ktop.com.tw/board.php?cid=30&fid=66&tid=37104 heartsong #06 篇的說明
再次謝謝各位的幫忙
系統時間:2024-04-19 14:37:41
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!