powerdesigner逆向工程生成PDM时的列注释解决方案

powerdesigner逆向工程生成PDM时的列注释解决方案
2011年03月14日
  在用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\SqlListQu ery下的Value值如下:
  
  {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
  {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语句,将语句提取出来,也可以获取结果: 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
  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/pdd 1100e/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\SqlListQue ry下的Value的第一行中
  {OWNER, TABLE, TABLE_TYPE, Comment }的Comment改为{OWNER, TABLE, TABLE_TYPE, TNAME }
  生成结果,如下:
  
  至此,我的基本目的,已经达到了,虽然没有直接生成Comment列,但可以通过以下vbs脚本,从Name列生成Comment列:
  '代码一:将name生成comment的脚本 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
  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!
  
  from http://blog.csdn.net/downmoon/archive/2011/03/04/6 224597.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值