1. 程式人生 > >powerdesigner逆向工程生成PDM時的列註釋(ColumnComment)解決方案

powerdesigner逆向工程生成PDM時的列註釋(ColumnComment)解決方案

原文:http://www.cnblogs.com/luluping/archive/2011/03/06/1972316.html

在用powerdesigner逆向工程生成PDM時,列註釋(ColumnComment)始終無法生成,歷經數小時的探索,找到一個折衷的方法,現分享如下。並希望有高手指點更好的方法。

邀月使用的是Powerdesigner 15.2,資料庫為SQL Server 2008 r2

方法如下:

1、在PowerDesigner介面-File-Reverse Engineer-Database,然後選擇一個DBMS,我這裡選取一個由系統預設的SQL Server 2008 DBMS修改而來的SQL_2008_MyDefine。

選好odbc,輸入正確的連線串,選擇資料庫及表。

生成效果:Name為英文,且Comment列為空。

而我們希望的是Name列為中文,Comment為中文。

查看了下線上幫助,發現在SQL_2008_MyDefine::Script\Objects\Column\SqlListQuery下的Value值如下:

View Code 複製程式碼 {OWNER, TABLE, S, COLUMN, DTTPCODE, LENGTH, SIZE, PREC, COMPUTE, NOTNULL, IDENTITY, DOMAIN, DEFAULT, ExtIdentitySeedInc, COMMENT, ExtCollation, ExtIdtNotForReplication, ExtDeftConstName, Sparse, FileStream, ExtRowGuidCol}
select u.name, o.name, c.column_id, c.name, casewhen c.system_type_id in (165, 167, 231) and c.max_length =-1then t.name +'(Max)'else t.name end, c.precision, case (c.max_length) when-1then0elsecasewhen c.system_type_id in (99, 231, 239) then (c.max_length/2) else (c.max_length) endendas colnA, c.scale,
case(c.is_computed) when1thenconvert(varchar(8000), (select z.definition from[%CATALOG%.]sys.computed_columns z where z.object_id= c.object_idand z.column_id = c.column_id)) else''endas colnB, case(c.is_nullable) when1then'NULL'else'NOTNULL'end, case(c.is_identity) when1then'identity'else''end, casewhen(c.user_type_id <> c.system_type_id) then (select d.name from[%CATALOG%.]sys.types d where d.user_type_id = c.user_type_id) else''endas colnC, convert(varchar(8000), d.definition), case (c.is_identity) when1thenconvert(varchar, i.seed_value) +', '+convert(varchar, i.increment_value) else''endas colnD, (selectconvert(varchar(8000), value) from ::fn_listextendedproperty(NULL, 'user', u.name, 'table', o.name, 'column', c.name) where name ='MS_Description') as colnE, c.collation_name, case (i.is_not_for_replication) when1then'true'else'false'end, d.name, case(c.is_sparse) when1then'true'else'false'end, case(c.is_filestream) when1then'true'else'false'end, case(c.is_rowguidcol) when1then'true'else'false'endfrom[%CATALOG%.]sys.columns c join[%CATALOG%.]sys.objects o on (o.object_id= c.object_id) join[%CATALOG%.]sys.schemas u on (u.schema_id = o.schema_id) join[%CATALOG%.]sys.types t on (t.user_type_id = c.system_type_id) leftouterjoin[%CATALOG%.]sys.identity_columns i on (i.object_id= c.object_idand i.column_id = c.column_id) leftouterjoin[%CATALOG%.]sys.default_constraints d on (d.object_id= c.default_object_id) where o.type in ('U', 'S', 'V') [ and u.name = %.q:OWNER%][ and o.name=%.q:TABLE%]orderby1, 2, 3 複製程式碼

注意該值中上面是PDM對應的列名,下面是從SQL資料庫中取到的相關屬性值。其中“

(selectconvert(varchar(8000), value) from ::fn_listextendedproperty(NULL, 'user', u.name, 'table', o.name, 'column', c.name) where name ='MS_Description') as colnE,

”是可以取到Comment值的,可是生成的PDM為什麼Comment列為空呢?嘗試修改該SQL語句,將語句提取出來,也可以獲取結果:

View Code 複製程式碼 select u.name, o.name, c.column_id, c.name, casewhen c.system_type_id in (165, 167, 231) and c.max_length =-1then t.name +'(Max)'else t.name end, c.precision, case (c.max_length) when-1then0elsecasewhen c.system_type_id in (99, 231, 239) then (c.max_length/2) else (c.max_length) endendas colnA, c.scale, case(c.is_computed) when1thenconvert(varchar(8000), (select z.definition from sys.computed_columns z where z.object_id= c.object_idand z.column_id = c.column_id)) else''endas colnB, case(c.is_nullable) when1then'NULL'else'NOTNULL'end, case(c.is_identity) when1then'identity'else''end, casewhen(c.user_type_id <> c.system_type_id) then (select d.name from sys.types d where d.user_type_id = c.user_type_id) else''endas colnC, convert(varchar(8000), d.definition), case (c.is_identity) when1thenconvert(varchar, i.seed_value) +', '+convert(varchar, i.increment_value) else''endas colnD, (selectconvert(varchar(8000), value) from ::fn_listextendedproperty(NULL, 'user', u.name, 'table', o.name, 'column', c.name) where name ='MS_Description') as colnE, c.collation_name, case (i.is_not_for_replication) when1then'true'else'false'end, d.name, case(c.is_sparse) when1then'true'else'false'end, case(c.is_filestream) when1then'true'else'false'end, case(c.is_rowguidcol) when1then'true'else'false'endfrom sys.columns c join sys.objects o on (o.object_id= c.object_id) join sys.schemas u on (u.schema_id = o.schema_id) join sys.types t on (t.user_type_id = c.system_type_id) leftouterjoin sys.identity_columns i on (i.object_id= c.object_idand i.column_id = c.column_id) leftouterjoin sys.default_constraints d on (d.object_id= c.default_object_id) where o.type in ('U', 'S', 'V') and u.name =N'dbo'and o.name=N'Age'orderby1, 2, 3 複製程式碼

後來發現,直接用生成表的SQL,而不是用資料庫就可以生成註釋。如下圖:

但欄位型別全亂了。

難道Powerdesigner真的這麼弱嗎?google了一下,看到官方文件:

裡面有關於SqlListQuery的解釋。

再看看上面的SQL語句,突然想到,既然可以在SQL查詢出結果,那麼出錯一定在生成PDM的時候,

在SQL_2008_MyDefine::Script\Objects\Column中看到這麼一段:

The following system variables are available: (parent table items are also available for columns) "COLNNAME" // name of the column "COLNCODE" // code of the column

將上面的Value值中上面的一行中“Comment”修改為“COLNNAME”會如何?即

{OWNER, TABLE, S, COLUMN, DTTPCODE, LENGTH, SIZE, PREC, COMPUTE, NOTNULL, IDENTITY, DOMAIN, DEFAULT, ExtIdentitySeedInc, COMMENT, ExtCollation, ExtIdtNotForReplication, ExtDeftConstName, Sparse, FileStream, ExtRowGuidCol}改為

{OWNER, TABLE, S, COLUMN, DTTPCODE, LENGTH, SIZE, PREC, COMPUTE, NOTNULL, IDENTITY, DOMAIN, DEFAULT, ExtIdentitySeedInc, COLNNAME, ExtCollation, ExtIdtNotForReplication, ExtDeftConstName, Sparse, FileStream, ExtRowGuidCol}

結果生成如下:

同理將SQL_2008_MyDefine::Script\Objects\Table\SqlListQuery下的Value的第一行中

{OWNER, TABLE, TABLE_TYPE, Comment}的Comment改為{OWNER, TABLE, TABLE_TYPE, TNAME}

生成結果,如下:

至此,我的基本目的,已經達到了,雖然沒有直接生成Comment列,但可以通過以下vbs指令碼,從Name列生成Comment列:

'程式碼一:將name生成comment的指令碼

View Code OptionExplicit ValidationMode =True InteractiveMode = im_Batch Dim mdl 'the current model 'get the current active model Set mdl = ActiveModel If (mdl IsNothing) ThenMsgBox"There is no current Model"ElseIfNot mdl.IsKindOf(PdPDM.cls_Model) ThenMsgBox"The current model is not an Physical Data model."Else ProcessFolder mdl EndIf'This routine copy name into code for each table, each column and each view 'of the current folder Privatesub ProcessFolder(folder) Dim Tab 'running table foreach Tab in folder.tables ifnot tab.isShortcut then tab.comment = tab.name Dim col 'running column foreach col in tab.columns col.comment= col.name nextendifnextDim view 'running view foreach view in folder.Views ifnot view.isShortcut then view.comment = view.name endifnext'go into the sub-packages Dim f 'running folder ForEach f In folder.Packages ifnot f.IsShortcut then ProcessFolder f endifNextend sub

仔細思索:為什麼從SQL生成的指令碼有Comment,可是到生成PDM時為什麼沒有轉化成功呢?是否Comment名稱不對應?

於是將原來的COMMENT加上COLNNAME,同時在下面的SQL語句中增加一列與COMMENT相同的值:

(select convert(varchar(8000), value) from ::fn_listextendedproperty(NULL, 'user', u.name, 'table', o.name, 'column', c.name) where name = 'MS_Description') as colnF,

如下圖:

這樣,Name列和Comment同時生成,終於OK!