+ -
当前位置:首页 → 问答吧 → Sybase自动生成数据库内所有表的DDL语句的存储过程

Sybase自动生成数据库内所有表的DDL语句的存储过程

时间:2010-09-15

来源:互联网

提供一个能够自动生成Sybase数据库内所有表的表结构、索引语法的存储过程。

存储过程名字:sp_gettabledll 下载

过程语法如下:
  1. if exists(select 1 from sysobjects where name = 'sp_gettabledll' and type = 'P')
  2.   drop procedure sp_gettabledll
  3. go

  4. create procedure sp_gettabledll
  5. @tblname varchar(30) = null,
  6. @prechar varchar(4) = null,   –$:no print
  7. @table_dll varchar(16384) = null out,
  8. @dbname varchar(32) = null,
  9. @droptg char(1) = '1',
  10. @prxytx varchar(255) = null,
  11. @replace varchar(20) = null,
  12. @tabtype varchar(1) = 'A', –A:所有表;P:代理表;U:用户表
  13. @indextg varchar(3) = 'TPI',  –T:纯表;P:主键;I:纯索引;J:除主键外的纯索引(和TP使用与I相同,和I同时使用I失效)
  14. @table_seg varchar(32) = null,
  15. @index_seg varchar(32) = null
  16. as
  17. begin
  18.      set nocount on  

  19.     if @tblname is null begin
  20.         declare @c_tblname varchar(30)
  21.         declare cur_1 cursor for
  22.         select name from sysobjects where type = 'U' order by name
  23.         open cur_1
  24.         fetch cur_1 into @c_tblname
  25.         while @@sqlstatus = 0 begin
  26.             exec sp_gettabledll  
  27.                 @tblname = @c_tblname,
  28.                 @prechar = @prechar,
  29.                 @dbname  = @dbname ,
  30.                 @droptg  = @droptg ,
  31.                 @prxytx  =  @prxytx ,
  32.                 @replace = @replace,
  33.                 @tabtype = @tabtype, –A:所有表;P:代理表;U:用户表
  34.                 @indextg = @indextg, –A:表和索引;T:纯表;I:纯索引
  35.                 @table_seg = @table_seg,
  36.                 @index_seg = @index_seg
  37.             fetch cur_1 into @c_tblname
  38.         end
  39.         close cur_1
  40.         deallocate cursor cur_1
  41.         return
  42.     end

  43.     declare @obj_id int
  44.     declare @sysstat2 int
  45.     declare @username varchar(30)

  46.      select @obj_id = id, @sysstat2 = sysstat2 ,@username  = user_name(uid)
  47.         from sysobjects where name = @tblname and type = 'U'
  48.     if @@rowcount <> 1
  49.     begin
  50.         print 'table %1! not exists', @tblname
  51.         goto err
  52.     end
  53.      if @sysstat2 & 1024 = 1024 begin
  54.         if upper(@tabtype) in ('U')
  55.             goto ok
  56.     end
  57.     else begin
  58.         if upper(@tabtype) in ('P')
  59.             goto ok
  60.     end

  61.     declare @colname varchar(30)        –列名
  62.     declare @typename varchar(30)       –类型名称
  63.     declare @usertype smallint          –类型ID
  64.     declare @length int                 –长度
  65.     declare @prec tinyint               –有效位数
  66.     declare @scale tinyint              –精度
  67.     declare @def_id int             –默认值id
  68.     declare @nulls tinyint              –空值
  69.     declare @ident tinyint              –标识列
  70.     declare @index_dll varchar(16384)

  71.     declare @def_text varchar(100)
  72.     declare @ide_text varchar(30)
  73.     declare @nul_text varchar(30)

  74.     declare @cns_text varchar(500)
  75.     declare @uni_pri varchar(40), @non_clu varchar(40), @non_uni varchar(40)

  76.     declare @lock_scheme varchar(100)

  77.     declare @keys varchar(500), @i int
  78.     declare @thiskey varchar(30)
  79.     declare @sorder char(4)
  80.     select @keys = "", @i = 1

  81.     declare @cns_name varchar(30), @status int, @indid int
  82.     declare @idx_name varchar(50)

  83.     declare @CRNW varchar(2)    –回车换行
  84.     declare @TAB char(1)

  85.     select @CRNW = convert(varchar(2), 0x0d0a)
  86.     select @TAB = convert(char(1), 0×09)

  87.     declare @dbname_dot varchar(35)
  88.     if ltrim(@dbname) is null
  89.         select @dbname = null,@dbname_dot = null
  90.     else
  91.         select @dbname = @dbname + '.',@dbname_dot = @dbname + '..'

  92.     declare @table_name varchar(30)
  93.     select @table_name = case when ltrim(@replace) is not null then @replace else @tblname end

  94.     declare @prefix_table varchar(2)
  95.     select @prefix_table = case when ltrim(@prxytx) is not null then 'r_' else null end

  96.     if charindex('T',@indextg) > 0 begin
  97.         if @droptg <> '0'
  98.             select @table_dll = "if exists(select 1 from "+@dbname_dot
  99.             +"sysobjects where name = '"+@prefix_table
  100.             +@table_name+"' and type = 'U')"
  101.             +@CRNW+@TAB+'drop table '+@dbname+@username + '.'
  102.             +@prefix_table
  103.             +@table_name+@CRNW
  104.             +case when @sysstat2 & 1024 = 1024
  105.                      then @TAB+'exec sp_dropobjectdef '+@table_name+@CRNW
  106.                 when ltrim(@prxytx) is not null
  107.                     then @TAB+'exec sp_dropobjectdef r_'+@table_name+@CRNW
  108.                 else null  
  109.             end
  110.             +'go'+@CRNW
  111.         else
  112.             select @table_dll = null
  113.      
  114.         if @sysstat2 & 1024 = 1024 begin
  115.             declare @OS_file varchar(255)
  116.             select @OS_file = char_value from sysattributes
  117.                     where class = 9 and attribute = 1 and
  118.                     object_cinfo = @tblname
  119.             if @@rowcount = 0 begin
  120.                 print '取代理表前缀失败%1!', @tblname
  121.                 goto err
  122.             end
  123.             select @table_dll = @table_dll+"exec sp_addobjectdef "
  124.             +@table_name
  125.             +", '"+@OS_file+"', 'table'"+@CRNW+
  126.             "create existing table " + @dbname+@username + "."
  127.             +@table_name + " ("
  128.         end
  129.         else if ltrim(@prxytx) is not null
  130.              select @table_dll = @table_dll+"exec sp_addobjectdef r_"
  131.             +@table_name+", '"+@prxytx
  132.             +@table_name+"', 'table'"+@CRNW
  133.             +"create existing table " + @dbname+@username + ".r_"
  134.             +@table_name + " ("
  135.          else
  136.             select @table_dll = @table_dll+'create table ' + @dbname+@username + '.'
  137.             +@table_name + ' ('
  138.      
  139.         –如果在sybsystemprocs数据库下提交,以下注释掉
  140.          
  141.         declare @tablna varchar(255)
  142.          –select @tablna = tablna from knp_tabl where tablcd = @tblname
  143.         –if @@rowcount = 0
  144.             select @tablna = null
  145.         if ltrim(@tablna) is not null
  146.             select @table_dll = @table_dll + '    –'+@tablna
  147.      
  148.         select @prechar = case when @prechar is not null then left(@prechar+space(4),4) else @prechar end
  149.         if @prechar <> ' begin
  150.             if @prechar is not null begin
  151.                 declare @temp_dll varchar(16384),@print_dll varchar(16384)
  152.                  select @temp_dll = @table_dll
  153.                 select @temp_dll = @prechar + @temp_dll
  154.                 while charindex(@CRNW,@temp_dll) > 0 and char_length(@temp_dll) <> charindex(@CRNW,@temp_dll)+1 begin
  155.                     select @print_dll = @print_dll + left(@temp_dll,charindex(@CRNW,@temp_dll) – 1) + @CRNW+@prechar
  156.                     select @temp_dll = substring(@temp_dll,charindex(@CRNW,@temp_dll)+char_length(@CRNW),char_length(@temp_dll))
  157.                 end
  158.                  select @print_dll = @print_dll + @temp_dll
  159.                 print '%1!',@print_dll
  160.             end
  161.             else
  162.                 print '%1!',@table_dll
  163.         end
  164.          
  165.         select @table_dll = @table_dll + @CRNW
  166.      
  167.          if ltrim(@table_seg) is null begin
  168.             select @table_seg = s.name
  169.                 from sysobjects o, syssegments s, sysindexes i
  170.                     where o.id = object_id(@tblname)
  171.                         and i.id = o.id
  172.                          and i.indid < 2
  173.                         and i.segment = s.segment
  174.             if @@rowcount = 0 begin  
  175.                 print '表%1!所在的段不存在',@tblname
  176.                 goto err
  177.             end
  178.         end
  179.     end

  180.     –确定表是否有完整性约束
  181.     declare @have_con char(1)
  182.     if exists (select 1 from sysindexes where id = @obj_id and status2 & 2 = 2 )
  183.         and (ltrim(@prxytx) is null or @sysstat2 & 1024 = 1024)
  184.         select @have_con = '1'
  185.     else
  186.          select @have_con = '0'


  187.     if charindex('T',@indextg) > 0 begin
  188.         declare @col_int int
  189.         select @col_int = count(*) from syscolumns
  190.             where id = @obj_id
  191.      
  192.         declare cur_col cursor for
  193.             select b.name, b.usertype, c.name , b.length, b.prec, b.scale, b.cdefault,
  194.                     convert(bit,b.status&8) as Nulls,
  195.                     convert(bit,b.status&128) as Ident
  196.                 from sysobjects a, syscolumns b, systypes c
  197.                  where a.name = @tblname and a.type = 'U'
  198.                     and  a.id = b.id
  199.                     and b.usertype = c.usertype
  200.                 order by b.colid
  201.      
  202.         open cur_col
  203.         fetch cur_col into @colname, @usertype, @typename, @length, @prec, @scale, @def_id, @nulls, @ident
  204.         while @@sqlstatus = 0
  205.         begin
  206.             –系统定义的数据类型
  207.             if  @usertype < 100
  208.             begin
  209.      
  210.                 if rtrim(@typename) in ('char','varchar','nchar','nvarchar')
  211.                     select @typename = @typename + '('+ convert(varchar,@length) +')'
  212.                 else if @typename in ('numeric','decimal')
  213.                     select @typename = @typename + '(' + convert(varchar,@prec) +  ',' + convert(varchar,@scale) + ')'
  214.                 else if @typename in ('float','double')
  215.                     select @typename = @typename + '(' + convert(varchar,@prec) + ')'
  216.                 else if @typename in ('binary','varbinary')
  217.                      select @typename =  @typename + '(' + convert(varchar,@length) + ')'
  218.             end
  219.      
  220.             select @ide_text = case @ident when 1 then 'identity' else null end
  221.             select @nul_text = case @nulls when 1 then '    null'  else 'not null' end
  222.      
  223.             if @def_id > 0
  224.             begin
  225.                 select @def_text = ltrim(rtrim(b.text))
  226.                     from sysobjects a, syscomments b
  227.                         where a.id = @def_id and a.id = b.id
  228.                  if @@rowcount <> 1
  229.                 begin
  230.                     print '取default失败%1!', @def_id
  231.                     goto err
  232.                 end
  233.                 while charindex(@TAB,@def_text) > 0
  234.                     select @def_text = stuff(@def_text,charindex(@TAB,@def_text),char_length(@TAB),' ')
  235.                 while charindex('  ',@def_text) > 0
  236.                     select @def_text = stuff(@def_text,charindex('  ',@def_text),char_length('  '),' ')
  237.                 select @def_text = rtrim(ltrim(@def_text))
  238.      
  239.             end
  240.             else
  241.                 select @def_text = null
  242.      
  243.             declare @thiscol varchar(500)
  244.             select @thiscol =
  245.                     case when char_length(@colname) <= 10 then left(@colname+space(10),10) else @colname end  
  246.                     + ' ' + case when char_length(@typename) <= 15 then left(@typename+space(15),15) else @typename end
  247.                     + ' ' + @def_text
  248.                     + ' ' + @ide_text
  249.                     + ' ' + @nul_text
  250.      
  251.             if @i = @col_int and (@have_con = '0' or charindex('P',@indextg) <= 0)
  252.                 select @thiscol  = @thiscol +  '  '
  253.             else
  254.                 select @thiscol  = @thiscol + ' ,'
  255.      
  256.             –如果在sybsystemprocs数据库下提交,以下注释掉
  257.             declare @colmna varchar(255)
  258.             select @colmna = null
  259.             –select @colmna = colmna from knp_colm where tablcd = @tblname and colmcd = @colname
  260.      
  261.             if ltrim(@colmna) is not null
  262.                 select @thiscol = @thiscol + '    –'+@colmna
  263.      
  264.             if @prechar <> '
  265.                 print '%1!%2!',@prechar, @thiscol
  266.      
  267.             select @table_dll = @table_dll + @thiscol + @CRNW
  268.      
  269.             select @i = @i + 1
  270.             fetch cur_col into @colname, @usertype, @typename, @length, @prec, @scale, @def_id, @nulls, @ident
  271.         end
  272.     end

  273.     if @have_con = '1' and charindex('P',@indextg) > 0
  274.     begin

  275.         select @cns_name = name, @status = status, @indid = indid
  276.             from sysindexes where id = @obj_id and status2 & 2 = 2

  277.         –print 'exist constraint… status = %1!', @status

  278.         if @indid = 1  
  279.             select @non_clu = 'clustered'
  280.         else if @indid > 1
  281.         begin
  282.             if  @status & 16 = 16
  283.                 select @non_clu = 'clustered'
  284.             else
  285.                 select @non_clu = 'nonclustered'
  286.         end

  287.         if @status & 2048 = 2048
  288.             select @uni_pri = 'primary key'
  289.         else
  290.             select @uni_pri = 'unique'

  291.         select @cns_text = 'constraint ' + @cns_name + ' ' + @uni_pri + ' ' + @non_clu

  292.         select   @i = 1, @keys = ''
  293.         select @thiskey = index_col(@tblname, @indid, @i)
  294.         while @thiskey <> null
  295.         begin
  296.             if @i > 1
  297.             begin
  298.                 select @keys = @keys + ", "
  299.             end

  300.             if ltrim(@keys) is null
  301.                 select @keys = @thiskey
  302.             else
  303.                 select @keys = @keys + @thiskey

  304.             select @sorder = index_colorder(@tblname, @indid, @i)
  305.             if (@sorder = "DESC")
  306.                  select @keys = @keys + " " + @sorder

  307.             select @i = @i + 1
  308.             select @thiskey = index_col(@tblname, @indid, @i)
  309.         end

  310.         select @cns_text = @cns_text + ' (' + @keys + ')'

  311.         if ltrim(@table_seg) is null begin
  312.             select @table_seg = s.name
  313.                 from sysobjects o, syssegments s, sysindexes i
  314.                     where o.id = object_id(@tblname)
  315.                         and i.id = o.id
  316.                         and i.indid < 2  
  317.                         and i.segment = s.segment
  318.             if @@rowcount = 0 begin
  319.                 print '表%1!所在的段不存在',@tblname
  320.                 goto err
  321.             end
  322.         end

  323.         if charindex('T',@indextg) <= 0
  324.              select @cns_text = 'alter table '+@dbname+@username + '.'+@table_name+' add '+@cns_text+ " on '" + @table_seg + "'"
  325.         if @prechar <> '
  326.             print '%1!%2!',@prechar,@cns_text

  327.         select @table_dll = @table_dll + @cns_text

  328.     end

  329.     if charindex('T',@indextg) > 0 begin
  330.         if @prechar <> '
  331.             print '%1!%2!',@prechar, ') '
  332.      
  333.         select @table_dll = left(@table_dll,char_length(@table_dll)-1) +  @CRNW + ')'
  334.      
  335.         –表锁计划
  336.         if @sysstat2 & 8192 = 8192
  337.             select @lock_scheme = 'lock allpages'
  338.         else if @sysstat2 & 16384 =  16384
  339.             select @lock_scheme = 'lock datapages'
  340.         else if @sysstat2 & 32768 = 32768
  341.             select @lock_scheme = 'lock datarows'
  342.         select @table_dll = @table_dll + @CRNW + @lock_scheme
  343.      
  344.         if @prechar <> '
  345.             print '%1!%2!',@prechar, @lock_scheme
  346.      
  347.         select @table_seg = "on '"+ @table_seg+"'"
  348.         select @table_dll = @table_dll + @CRNW + @table_seg + @CRNW+'go'+@CRNW
  349.      
  350.         if @prechar <> ' begin
  351.             print '%1!%2!',@prechar, @table_seg
  352.             print '%1!go',@prechar
  353.         end
  354.     end

  355.     if ltrim(@prxytx)  is not null or @sysstat2 & 1024 = 1024
  356.         goto ok

  357.     if charindex('T',@indextg) > 0 begin
  358.         declare @part_num int,@partition varchar(255)
  359.         select @part_num = count(*)
  360.             from syspartitions
  361.             where id = object_id(@tblname)
  362.         if @part_num <> 0 begin
  363.             select @partition = 'alter table '+ @username + '.' + @table_name + ' partition '+convert(varchar,@part_num)
  364.             select @table_dll = @table_dll + @CRNW + @partition
  365.             if @prechar <> '
  366.                 print '%1!%2!',@prechar, @partition
  367.         end
  368.     end

  369.     –select @table_dll as table_dll
  370.     ————————————————————————————-
  371.     –检查其他索引
  372.     declare @idx_seg  varchar(32)
  373.     if charindex('I',@indextg) > 0 or charindex('J',@indextg) > 0 begin
  374.         if exists  (select 1 from sysindexes where id = @obj_id and indid <> 0 and  
  375.             (status2 & 2 <> 2 or charindex('P',@indextg) <= 0 and charindex('J',@indextg) <= 0))

  376.         begin
  377.             declare cur_idx cursor for
  378.                 select name, indid, status from sysindexes
  379.                     where id = @obj_id and indid <> 0 and  
  380.             (status2 & 2 <> 2 or charindex('P',@indextg) <= 0 and charindex('J',@indextg) <= 0)
  381. –                  (status2 & 2 <> 2 or charindex('P',@indextg) <= 0)
  382.             open cur_idx
  383.             fetch cur_idx into @idx_name, @indid, @status
  384.             while @@sqlstatus = 0  
  385.             begin
  386.      
  387.                 if @indid = 1
  388.                     select @non_clu = 'clustered'
  389.                 else if @indid > 1
  390.                 begin
  391.                     if  @status & 16 = 16
  392.                         select @non_clu = 'clustered'
  393.                     else
  394.                         select @non_clu = 'nonclustered'
  395.                 end
  396.      
  397.                 if @status & 2 = 2
  398.                     select @non_uni = 'unique '
  399.                 else
  400.                      select @non_uni = null
  401.      
  402.                 select @i = 1,@keys = ''
  403.                 select @thiskey = index_col(@tblname, @indid, @i)
  404.                 while @thiskey <> null
  405.                 begin
  406.                     if @i > 1
  407.                       begin
  408.                         select @keys = @keys + ", "
  409.                     end
  410.      
  411.                     if ltrim(@keys) is null
  412.                         select @keys = @thiskey
  413.                     else
  414.                          select @keys = @keys + @thiskey
  415.      
  416.                     select @sorder = index_colorder(@tblname, @indid, @i)
  417.                     if @sorder = "DESC"
  418.                         select @keys = @keys + " " + @sorder
  419.      
  420.                     select @i = @i + 1
  421.                     select @thiskey = index_col(@tblname, @indid, @i)
  422.                 end
  423.      
复制代码

作者: andkylee   发布时间: 2010-09-15

接上面。。。。
  1.                 if ltrim(@index_seg) is null begin  
  2.                     select @idx_seg = s.name
  3.                         from syssegments s, sysindexes i
  4.                             where s.segment = i.segment
  5.                                 and i.id = object_id(@tblname)
  6.                                 and i.indid = @indid
  7.                     if @@rowcount = 0 begin
  8.                          print '索引%1!所在的段不存在',@idx_name  
  9.                         goto err
  10.                     end
  11.                 end
  12.                 else
  13.                     select @idx_seg = @index_seg
  14.      
  15.                 if ltrim(@keys) is not null begin
  16.                     declare @thisidx varchar(500)
  17.                     select @thisidx = 'create ' + @non_uni
  18.                         + @non_clu + ' index ' + @idx_name + ' on ' + @dbname + @username
  19.                         + '.' + @table_name + "(" + @keys + ") on '" +@idx_seg+"'"
  20.      
  21.                     select @index_dll = @index_dll + @thisidx + @CRNW
  22.                     if @prechar <> '
  23.                         print '%1!%2!',@prechar, @thisidx
  24.                 end  
  25.      
  26.                 fetch cur_idx into @idx_name, @indid, @status
  27.             end
  28.      
  29.             if ltrim(@index_dll) is not null begin
  30.                 if @droptg <> '0' begin
  31.                     select @index_dll = @index_dll + 'go' + @CRNW
  32.                     if @prechar <> '
  33.                         print '%1!go',@prechar
  34.                 end
  35.             end
  36.      
  37.             select @table_dll = @table_dll + @CRNW + @index_dll
  38.         end
  39.     end
  40. ok:
  41.     set nocount off
  42.     return 0
  43. err:
  44.     set nocount off
  45.     return -1
  46. end
  47. go
复制代码

作者: andkylee   发布时间: 2010-09-15

相关阅读 更多