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

DbExpress 取得資料表結構的方法

 
sryang
尊榮會員


發表:38
回覆:740
積分:870
註冊:2002-06-27

發送簡訊給我
#1 引用回覆 回覆 發表時間:2012-07-01 01:01:07 IP:114.35.xxx.xxx 訂閱
以前,BDE 時代,要取得資料表結構很簡單,就用 TTable 開啟這個資料表,然後從每個 Field 的屬性就可以得知
但是到了 DbExpress 時代,這個方法已經不靈了,雖然用 TSQLTable 還是可以開啟資料表,還是有 Field 可以看
屬性,不過 Field.Size 屬性跟資料表的實際長度是不相同的。

根據個人的經驗,Field.Size 最少都是 40,一個 NVARCHAR(4) 的欄位,Field.Size 也會是 40
那麼要怎麼做才可以得知真實的資料表結構呢?

當然有人會從資料庫本身儲存資料表結構的資料表來下手 (以 SQL Server 來說,是 sysobjects 跟 syscolumns)
但是這個方法各種資料庫要下的查詢都不相同,實在是有些不方便

而 DbExpress 的 TCustomSQLDataSet 提供了一個方法:
SetSchemaInfo(SchemaType: TSchemaType; SchemaObjectName, SchemaPattern: UnicodeString; PackageName: UnicodeString = '');

怪了,要 "取得" 資料表結構,怎麼方法名用 Set 開頭?
原來這個方法,是要告訴 TCustomSQLDataSet 你想要取得哪些結構資料,設定好之後,Open 出來就是了
使用 TSQLDataSet 還是有些不便,得搭配 TDataSetProvider 跟 TClientDataSet 才能將資料顯示在 TDBGrid 中
那麼就使用 TSimpleDataSet 吧,TSimpleDataSet.DataSet 也是一個 TCustomSQLDataSet
於是,要取得 "Table1" 的欄位資料,就使用

SDS1.Connection := CONN;
SDS1.SetSchemaInfo(stColumns, 'Table1', '%');
SDS1.Open;

得到的資料欄位,會因為 SetSchemaInfo 的第一個參數而有不同,而且從欄位名稱就可以很容易看出代表的意思
就不多說了,大家自己試試看吧
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2012-07-01 20:01:39, 註解 無‧
sryang 重新編輯於 2012-07-03 03:08:11, 註解 無‧
GrandRURU
站務副站長


發表:234
回覆:1648
積分:1741
註冊:2005-06-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2012-07-01 06:31:10 IP:1.160.xxx.xxx 未訂閱
對嘛對嘛
還是DBX最好用了!

讚!

===================引 用 sryang 文 章===================
以前,BDE 時代,要取得資料表結構很簡單,就用 TTable 開啟這個資料表,然後從每個 Field 的屬性就可以得知
但是到了 DbExpress 時代,這個方法已經不靈了,雖然用 TSQLTable 還是可以開啟資料表,還是有 Field 可以看
屬性,不過 Field.Size 屬性跟資料表的實際長度是不相同的。

根據個人的經驗,Field.Size 最少都是 40,一個 NVARCHAR(4) 的欄位,Field.Size 也會是 40
那麼要怎麼做才可以得知真實的資料表結構呢?

當然有人會從資料庫本身儲存資料表結構的資料表來下手 (以 SQL Server 來說,是 sysobjects 跟 syscolumns)
但是這個方法各種資料庫要下的查詢都不相同,實在是有些不方便

而 DbExpress 的 TCuatomSQLDataSet 提供了一個方法:
SetSchemaInfo(SchemaType: TSchemaType; SchemaObjectName, SchemaPattern: UnicodeString; PackageName: UnicodeString = '');

怪了,要 "取得" 資料表結構,怎麼方法名用 Set 開頭?
原來這個方法,是要告訴 TCuatomSQLDataSet 你想要取得哪些結構資料,設定好之後,Open 出來就是了
使用 TSQLDataSet 還是有些不便,得搭配 TDataSetProvider 跟 TClientDataSet 才能將資料顯示在 TDBGrid 中
那麼就使用 TSimpleDataSet 吧,TSimpleDataSet.DataSet 也是一個 TCuatomSQLDataSet
於是,要取得 "Table1" 的欄位資料,就使用

SDS1.Connection := CONN;
SDS1.SetSchemaInfo(stColumns, 'Table1', '*');
SDS1.Open;

得到的資料欄位,會因為 SetSchemaInfo 的第一個參數而有不同,而且從欄位名稱就可以很容易看出代表的意思
就不多說了,大家自己試試看吧
leveon
資深會員


發表:29
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2012-07-02 09:59:59 IP:118.165.xxx.xxx 訂閱
 謝謝分享 ~
順便分享一下之前看到的 ,DBX建立資料結構的新方法
var
MetaDataTable: TDBXMetaDataTable;
DataGenerator: TDbxDataGenerator;
Command: TDBXCommand;
Row: Integer;
begin
MetaDataTable := TDBXMetaDataTable.Create;
MetaDataTable.TableName := 'QCXXX_TABLE';
MetaDataTable.AddColumn(TDBXInt32Column.Create('C1'));
MetaDataTable.AddColumn(TDBXDecimalColumn.Create('C2', 10, 2));
MetaDataTable.AddColumn(TDBXUnicodeCharColumn.Create('C3', 32));
MetaDataProvider.CreateTable(MetaDataTable);
end;



http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devwin32/dbexpress4featureov_xml.html#646245787072657373204D6574616461746120496D70726F76656D656E7473


sryang
尊榮會員


發表:38
回覆:740
積分:870
註冊:2002-06-27

發送簡訊給我
#4 引用回覆 回覆 發表時間:2012-07-02 10:53:47 IP:114.35.xxx.xxx 訂閱
您提供的網頁中,在這一段 code 的後面提到

Note: DBXMetaDataProvider is only supported for managed code on the .NET platform.

是不是 MetaDataProvider 只能在 .Net 環境中使用呢?

===================引 用 leveon 文 章===================
謝謝分享 ~
順便分享一下之前看到的 ,DBX建立資料結構的新方法
var
MetaDataTable: TDBXMetaDataTable;
DataGenerator: TDbxDataGenerator;
Command: TDBXCommand;
Row: Integer;
begin
MetaDataTable := TDBXMetaDataTable.Create;
MetaDataTable.TableName := 'QCXXX_TABLE';
MetaDataTable.AddColumn(TDBXInt32Column.Create('C1'));
MetaDataTable.AddColumn(TDBXDecimalColumn.Create('C2', 10, 2));
MetaDataTable.AddColumn(TDBXUnicodeCharColumn.Create('C3', 32));
MetaDataProvider.CreateTable(MetaDataTable);
end;
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devwin32/dbexpress4featureov_xml.html#646245787072657373204D6574616461746120496D70726F76656D656E7473

------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
leveon
資深會員


發表:29
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#5 引用回覆 回覆 發表時間:2012-07-02 11:26:20 IP:118.165.xxx.xxx 訂閱
不需要.NET
http://docwiki.embarcadero.com/RADStudio/XE/en/DbExpress_4_Feature_Overview#Writing_metadata

需要.NET的應是指Data Explorer那個IDE工具 因為Delphi IDE本身是基於.Net

更詳細一點的範例

http://ppt.cc/hyqd

===================引 用 sryang 文 章===================
您提供的網頁中,在這一段 code 的後面提到

Note: DBXMetaDataProvider is only supported for managed code on the .NET platform.

是不是 MetaDataProvider 只能在 .Net 環境中使用呢?

===================引 用 leveon 文 章===================
謝謝分享 ~
順便分享一下之前看到的 ,DBX建立資料結構的新方法
var
MetaDataTable: TDBXMetaDataTable;
DataGenerator: TDbxDataGenerator;
Command: TDBXCommand;
Row: Integer;
begin
MetaDataTable := TDBXMetaDataTable.Create;
MetaDataTable.TableName := 'QCXXX_TABLE';
MetaDataTable.AddColumn(TDBXInt32Column.Create('C1'));
MetaDataTable.AddColumn(TDBXDecimalColumn.Create('C2', 10, 2));
MetaDataTable.AddColumn(TDBXUnicodeCharColumn.Create('C3', 32));
MetaDataProvider.CreateTable(MetaDataTable);
end;
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devwin32/dbexpress4featureov_xml.html#646245787072657373204D6574616461746120496D70726F76656D656E7473

編輯記錄
leveon 重新編輯於 2012-07-01 21:31:44, 註解 無‧
leveon 重新編輯於 2012-07-01 21:34:01, 註解 無‧
sryang
尊榮會員


發表:38
回覆:740
積分:870
註冊:2002-06-27

發送簡訊給我
#6 引用回覆 回覆 發表時間:2012-07-02 12:23:47 IP:114.35.xxx.xxx 訂閱
原來是這樣用,感謝您提供的資料!
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
GrandRURU
站務副站長


發表:234
回覆:1648
積分:1741
註冊:2005-06-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2012-07-02 13:00:27 IP:59.120.xxx.xxx 未訂閱
原來如此
所以不是用.NET寫的DBX Driver是無法使用Data Explorer所有功能的原因在這裡啊


===================引 用 leveon 文 章===================
不需要.NET
http://docwiki.embarcadero.com/RADStudio/XE/en/DbExpress_4_Feature_Overview#Writing_metadata

需要.NET的應是指Data Explorer那個IDE工具 因為Delphi IDE本身是基於.Net

更詳細一點的範例

http://ppt.cc/hyqd

===================引 用 sryang 文 章===================
您提供的網頁中,在這一段 code 的後面提到

Note: DBXMetaDataProvider is only supported for managed code on the .NET platform.

是不是 MetaDataProvider 只能在 .Net 環境中使用呢?

===================引 用 leveon 文 章===================
謝謝分享 ~
順便分享一下之前看到的 ,DBX建立資料結構的新方法
var
MetaDataTable: TDBXMetaDataTable;
DataGenerator: TDbxDataGenerator;
Command: TDBXCommand;
Row: Integer;
begin
MetaDataTable := TDBXMetaDataTable.Create;
MetaDataTable.TableName := 'QCXXX_TABLE';
MetaDataTable.AddColumn(TDBXInt32Column.Create('C1'));
MetaDataTable.AddColumn(TDBXDecimalColumn.Create('C2', 10, 2));
MetaDataTable.AddColumn(TDBXUnicodeCharColumn.Create('C3', 32));
MetaDataProvider.CreateTable(MetaDataTable);
end;
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devwin32/dbexpress4featureov_xml.html#646245787072657373204D6574616461746120496D70726F76656D656E7473

sryang
尊榮會員


發表:38
回覆:740
積分:870
註冊:2002-06-27

發送簡訊給我
#8 引用回覆 回覆 發表時間:2012-07-04 07:28:56 IP:114.35.xxx.xxx 訂閱
近來發現一個問題,Delphi XE 使用個人提供的方法取得 table schema 時,如果連線到 SQL Server
而且資料庫定序有區分大小寫時,會出現 "SQL State: 42S02, SQL Error Code: 208 Invalid object
name 'SYSTYPES'" 的錯誤訊息

這個原因是因為 DBXMsSqlMetaDataReader.pas 裡面的 TDBXMsSqlMetaDataReader.GetSqlForColumns
這個 function 回傳的 SQL 敘述中,把 SYSTYPES 與 SYSCOLUMNS 都打成大寫,但是實際上這兩個系統
資料表是小寫的。所以,在有區分大小寫的定序之下,就會出錯。

不過因為 DBXMsSqlMetaDataReader.pas 是包在 DBXMSSQLDriver150.bpl 裡面,而且缺少了這個 .bpl
相關的 source code,導致無法自行修改重新編譯。

在死馬當活馬醫的心態之下,個人使用 HEX Editor 直接修改 DBXMSSQLDriver150.bpl,找到了該字串,
把大寫改小寫,竟然就改好了!

在此提出給大家做參考。
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2012-07-03 17:30:07, 註解 無‧
sryang 重新編輯於 2012-07-03 17:30:48, 註解 無‧
leveon
資深會員


發表:29
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2012-07-04 17:31:30 IP:118.165.xxx.xxx 訂閱
謝謝分享~
不過自行更改HEX 會不會太暴力了呀~~呵呵

我自己是覺得內建VCL的BPL分拆 為了配合IDE 實在是分的太細
有用到的 不過是其中的一兩個Unit
自行分割VCL的BPL 會比較輕便

===================引 用 sryang 文 章===================
近來發現一個問題,Delphi XE 使用個人提供的方法取得 table schema 時,如果連線到 SQL Server
而且資料庫定序有區分大小寫時,會出現 "SQL State: 42S02, SQL Error Code: 208 Invalid object
name 'SYSTYPES'" 的錯誤訊息

這個原因是因為 DBXMsSqlMetaDataReader.pas 裡面的 TDBXMsSqlMetaDataReader.GetSqlForColumns
這個 function 回傳的 SQL 敘述中,把 SYSTYPES 與 SYSCOLUMNS 都打成大寫,但是實際上這兩個系統
資料表是小寫的。所以,在有區分大小寫的定序之下,就會出錯。

不過因為 DBXMsSqlMetaDataReader.pas 是包在 DBXMSSQLDriver150.bpl 裡面,而且缺少了這個 .bpl
相關的 source code,導致無法自行修改重新編譯。

在死馬當活馬醫的心態之下,個人使用 HEX Editor 直接修改 DBXMSSQLDriver150.bpl,找到了該字串,
把大寫改小寫,竟然就改好了!

在此提出給大家做參考。
sryang
尊榮會員


發表:38
回覆:740
積分:870
註冊:2002-06-27

發送簡訊給我
#10 引用回覆 回覆 發表時間:2012-07-04 21:38:58 IP:114.35.xxx.xxx 訂閱
如果給我們source code讓我們自己編譯,不就不需要這樣暴力了嗎?
這個問題有人反應給原廠,不過並沒有解決,似乎原廠看不懂那人提出的問題
直接改HEX是沒辦法中的辦法啊!
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
系統時間:2017-09-25 3:19:21
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!