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

在用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,
case when c.system_type_id in (165, 167, 231) and c.max_length = -1 then t.name + '(Max)' else t.name end,
c.
precision,
case (c.max_length) when -1 then 0 else case when c.system_type_id in (99, 231, 239) then (c.max_length/2) else (c.max_length) end end as colnA,
c.scale,
case(c.is_computed) when 1 then convert(varchar(8000), (select z.definition from [%CATALOG%.]sys.computed_columns z where z.object_id = c.object_id and z.column_id = c.column_id)) else '' end as colnB,
case(c.is_nullable) when 1 then 'NULL' else 'NOTNULL' end,
case(c.is_identity) when 1 then 'identity' else '' end,
case when(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 '' end as colnC,
convert(varchar(8000), d.definition),
case (c.is_identity) when 1 then convert(varchar, i.seed_value) + ', ' + convert(varchar, i.increment_value) else '' end as colnD,
(
select convert(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) when 1 then 'true' else 'false' end,
d.name,
case(c.is_sparse) when 1 then 'true' else 'false' end,
case(c.is_filestream) when 1 then 'true' else 'false' end,
case(c.is_rowguidcol) when 1 then 'true' else 'false' end
from
[%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)
left outer join [%CATALOG%.]sys.identity_columns i on (i.object_id = c.object_id and i.column_id = c.column_id)
left outer join [%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%]
order by 1, 2, 3

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

(select convert(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,
case when c.system_type_id in (165, 167, 231) and c.max_length = -1 then t.name + '(Max)' else t.name end,
c.
precision,
case (c.max_length) when -1 then 0 else case when c.system_type_id in (99, 231, 239) then (c.max_length/2) else (c.max_length) end end as colnA,
c.scale,
case(c.is_computed) when 1 then convert(varchar(8000), (select z.definition from sys.computed_columns z where z.object_id = c.object_id and z.column_id = c.column_id)) else '' end as colnB,
case(c.is_nullable) when 1 then 'NULL' else 'NOTNULL' end,
case(c.is_identity) when 1 then 'identity' else '' end,
case when(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 '' end as colnC,
convert(varchar(8000), d.definition),
case (c.is_identity) when 1 then convert(varchar, i.seed_value) + ', ' + convert(varchar, i.increment_value) else '' end as colnD,
(
select convert(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) when 1 then 'true' else 'false' end,
d.name,
case(c.is_sparse) when 1 then 'true' else 'false' end,
case(c.is_filestream) when 1 then 'true' else 'false' end,
case(c.is_rowguidcol) when 1 then 'true' else 'false' end
from
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)
left outer join sys.identity_columns i on (i.object_id = c.object_id and i.column_id = c.column_id)
left outer join 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'
order by 1, 2, 3

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

邀月工作室

但字段類型全亂了。

邀月工作室

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

http://manuals.sybase.com/onlinebooks/group-pd/pdd1100e/advanced/@Generic__BookTextView/1302;hf=0

裏面有關於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
Option Explicit
ValidationMode
= True
InteractiveMode
= im_Batch
Dim mdl 'the current model
'
get the current active model
Set mdl = ActiveModel
If (mdl Is Nothing) Then
MsgBox "There is no current Model"
ElseIf Not mdl.IsKindOf(PdPDM.cls_Model) Then
MsgBox "The current model is not an Physical Data model."
Else
ProcessFolder mdl
End If
'This routine copy name into code for each table, each column and each view
'
of the current folder
Private sub ProcessFolder(folder)
Dim Tab 'running table
for each Tab in folder.tables
if not tab.isShortcut then
tab.comment
= tab.name
Dim col 'running column
for each col in tab.columns
col.comment
= col.name
next
end if
next
Dim view 'running view
for each view in folder.Views
if not view.isShortcut then
view.comment
= view.name
end if
next
'go into the sub-packages
Dim f 'running folder
For Each f In folder.Packages
if not f.IsShortcut then
ProcessFolder f
end if
Next
end 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!

邀月工作室

邀月注:本文版權由邀月和博客園共同所有,轉載請註明出處。
助人等於自助!  [email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章