午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

動態(tài)創(chuàng)建ClientDataSet的表定義

 quasiceo 2014-06-06
分類: Delphi 2003-10-21 00:07 2847人閱讀 評論(1) 收藏 舉報

前言

很多人都在問,ClientDataSet如何才能在不連接數(shù)據(jù)庫得情況下,用程序創(chuàng)建起來,并打開數(shù)據(jù)集。

在研究了一下TClientDataSet數(shù)據(jù)集后,發(fā)現(xiàn)如果要讓ClientDataSet打開的話(Open),必須滿足三個條件中的一個:

  1. ProviderName屬性賦值,即有數(shù)據(jù)源提供者。
  2. Data屬性賦值。即從其它已經(jīng)打開的數(shù)據(jù)集中獲得表結(jié)構(gòu)和數(shù)據(jù)。
  3. FileName賦值,即從本地文件獲取數(shù)據(jù)和MetaData。

這三個條件是TClientDataSet的Active屬性的幫助中說的。思考一下,第一和第二基本被排除,我如果有了現(xiàn)成的數(shù)據(jù)集,還要創(chuàng)建干嗎?第三個又不是那么容易,你哪知道文件的格式是什么呢?

那到底該怎么做呢?

失敗的嘗試

突然想起TClientDataSet中支持InternalCalc(內(nèi)部計算)字段。內(nèi)部計算字段可以在設(shè)計期加進去,或者也可以在運行期動態(tài)加入。我們?yōu)榱朔奖?,就在設(shè)計期加入。見下圖:

可以通過雙擊控件(TClientDataSet)進入字段編輯器,然后右鍵選擇“New Field”命令,得到如圖所示的界面。填寫Name,Type和FieldType。

記?。篎ieldType一定要是“InternalCalc”。如此反復(fù),你可以選擇添加多個字段。

打開!報錯:“ProviderName”或Data沒有賦值。

這個方法不正確,既然要Data,我嘗試著,從其它ClientDataSet的Data屬性賦值上。得到結(jié)果是:自己新建的字段和數(shù)據(jù)源的字段都顯示。

我又進行了進一步的嘗試:那就是讓這個有著新建的字段和原有字段的ClientDataSet的Data賦值到另一個新的ClientDataSet上,卻發(fā)現(xiàn)新建的字段沒有進入。

總得來說,這次嘗試是失敗的,不過有如下總結(jié):

  1. 光靠新建內(nèi)部計算字段是不可行的。
  2. 新建的計算字段不可以進入Data屬性而被傳遞給第二個ClientDataSet。

XML

又是XML!ClientDataSet本就是斷開連接的數(shù)據(jù)集控件,應(yīng)此提供了將數(shù)據(jù)緩存到磁盤的功能SaveToFile(),其詳細聲明如下:

  procedure SaveToFile(const FileName: string = ''; Format: TDataPacketFormat = dfBinary);

注意到其中的TDataPacketFormat。它是個枚舉類型,全部的枚舉值如下:

  TDataPacketFormat = (dfBinary, dfXML, dfXMLUTF8);

大家可能注意到了,dfBinary和dfXMLUTF8都不是我們需要關(guān)心的,關(guān)心一下我們的dfXML格式。這是個讓人興奮的消息。有了XML,我們就可以查看ClientDataSet的MetaData的定義,而且更有了修改的可能!

調(diào)用一下SaveToFile功能,注意保存格式為dfXML。打開文件,如下顯示:

  <?xml version="1.0" standalone="yes" ?> 
- <DATAPACKET Version="2.0">
- <METADATA>
- <FIELDS>
-  <FIELD attrname="NormInfoID" fieldtype="i4">
    <PARAM Name="PROVFLAGS" Value="7" Type="i4" Roundtrip="True" /> 
   </FIELD>
   <FIELD attrname="Description" fieldtype="string.uni" WIDTH="160" /> 
   <FIELD attrname="NormInfoVal" fieldtype="string.uni" WIDTH="510" /> 
   <FIELD attrname="NewField" fieldtype="i4" /> 
   <FIELD attrname="Boolean" fieldtype="Boolean" /> 
   <FIELD attrname="Date" fieldtype="date" /> 
   <FIELD attrname="Time" fieldtype="time" /> 
  </FIELDS>
  <PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" /> 
  </METADATA>
  <ROWDATA /> 
  </DATAPACKET>

看這個全部的,比較混亂,先看一下結(jié)構(gòu):

  <?xml version="1.0" standalone="yes" ?> 
- <DATAPACKET Version="2.0">
  + <METADATA>
    <ROWDATA /> 
  </DATAPACKET>

這下比較清楚了:

整個XML定義為一個DataPacket,DataPacket包括兩個部分:MetaData和RowData。顯然對我們來說,RowData可以忽視,到時候?qū)owData的節(jié)點清空就是。而MetaData呢?

看看全部的XML格式,可以看出:MetaData包括Fields和Params。即字段和數(shù)據(jù)集參數(shù)。

字段

先重點考慮Fields??匆幌翭ield節(jié)點的定義,大概可以看出一些:

  1. attrname是指FieldName
  2. fieldtype是指字段類型
  3. width是需要寬度的字段類型的參數(shù)
  4. 如果需要定義字段的屬性,再加上<Param />節(jié)點

下面我們來研究一下字段類型,我想這也是最主要的!其它屬于高級用法。

MSSQL Type fieldtype WIDHT SUBTYPE DECIMALS READONLY
Binary bin.hex 50      
Bit boolean        
Char string 10 FixedChar    
DateTime dateTime        
Decimal fixed 18      
Float r8        
Image bin.hex   Binary    
Int i4        
Money fixed 19   4  
nChar string.uni 20      
nText bin.hex   Text    
Numeric fixed 18      
nVarChar string.uni 100      
SmallDateTime dateTime        
Real r8        
SmallInt i2        
SmallMoney fixed 10   4  
Text bin.hex   Text    
TimeStamp bin.hex 8     true
tinyInt i2        
UniqueIdentifier string 38 Guid    
VarBinary bin.hex 50 Binary    
VarChar string 50      

見上表,這是我在SQLServer2000中,將所有類型的字段都用上,然后在ClientDataSet中得到的,類型對應(yīng)關(guān)系。注意到有SubType屬性,來幫助決定類型。其中沒有值的單元格,表示該屬性沒有用到。寬度值中,除了UniqueIdentifier是38外,其余都是采用系統(tǒng)默認寬度。

分析一下這一張表,可以得到如下一些特點:

  1. 后綴uni表示unicode,沒有后綴,則表示是AnsiCode
  2. 后綴hex表示16進制
  3. i后的數(shù)字表示整數(shù)所占用的位數(shù),默認為4位
  4. r8表示8位浮點數(shù)

字段參數(shù)

注意到某些字段的定義下有節(jié)點:

<PARAM Name="PROVFLAGS" Value="7" Type="i4" Roundtrip="True" /> 

先來解釋一下“PROVFLAGS”,在Delphi的源碼里查找可以發(fā)現(xiàn)其實就是對應(yīng)著TField的屬性ProviderFlags,那么7也就是好理解的了。

看TProviderFlag和TProviderFlags的定義

  TProviderFlag = (pfInUpdate, pfInWhere, pfInKey, pfHidden);
  TProviderFlags = set of TProviderFlag;

既然是集合,那么7很顯然就是一個集合的整數(shù)表示:按順序排的話,7其實就是表示結(jié)合[pfInUpdate, pfInWhere, pfInKey]。

不過不知道為什么,查看TField的屬性,pfInKey不在集合中。

MetaData屬性

看看

  <PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" /> 

可以看出DEFAULT_ORDER和PRIMARY_KEY的意思,但是后面的值呢?研究之后,發(fā)現(xiàn),它是主鍵或索引字段的Index。如果同時兩個字段都是索引,那么它的格式是:"1 2",中間采用空格隔開。

如何使用XML格式?

好了,格式大概都知道了,現(xiàn)在問題是如何轉(zhuǎn)載到ClientDataSet呢?

文件是可以,但是顯然不滿足我們當初的需求,在查看一下接口定義,發(fā)現(xiàn)除了LoadFromFile還有LoadFromStream。查看一下源碼,其實LoadFromFile就是調(diào)用了LoadFromStream。

好了,只要我們創(chuàng)建了這樣的XML流,就可以動態(tài)創(chuàng)建ClientDataSet了!

至于如何創(chuàng)建XML流,不在此討論了

更多 0

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多