代码之家  ›  专栏  ›  技术社区  ›  Michael Wilson

如何通过SQL提取Sybase(12.5)表DDL?

  •  2
  • Michael Wilson  · 技术社区  · 14 年前

    我希望通过SQL以编程方式提取表DDL,结果“足够好”,可以重新导入和重构表。

    我想DBArtisan必须以某种方式调用API。他们是在攻击systables还是在系统中安装了一个存储过程(类似于生成存储过程文本的存储过程)?

    4 回复  |  直到 14 年前
        1
  •  3
  •   DVK    14 年前

    IIRC有一个工具叫做DBSchema(peppler.org/downloads/dbschema-2_4_2 .zip是我能找到的最好的URL)-如果这个URL不起任何作用,Mike Peppler是sybperl的作者。如果您喜欢自己滚动,那么您可以对该脚本的代码进行反向工程。

    就SQL而言,表信息是 sysobjects syscolumns

    您还可以使用存储过程: http://www.razorsql.com/articles/sybase_admin_queries.html

        2
  •  5
  •   B0rG    13 年前

       SELECT @OnlyTableName = 'my_table_name'
    

    使用您的表名并执行代码,您应该在代码结尾处获得#rtn表中的所有DDL语句:

       DECLARE @TableName               varchar(50)
       DECLARE @ObjectID                int
       DECLARE @IndexID                 int
       DECLARE @IndexStatus             int
       DECLARE @IndexName               varchar(30)
       DECLARE @msg                     varchar(255)
       DECLARE @OnlyTableName           varchar(50)
       DECLARE @LastColumnId            int
       DECLARE @i                       int
    
    
       SELECT @OnlyTableName = 'my_table_name'
    
    
       CREATE TABLE #columns (
          column_name char(30)    NULL,
          type_name   char(30)    NULL,
          length      char(10)    NULL,
          iden_flag   char(10)    NULL,
          null_flag   char(20)    NULL,
          flag        char(1)     NULL
       )
    
       CREATE TABLE #rtn (
          msg   varchar(255)   NULL
       )
    
    
    
       SELECT @TableName = name,
              @ObjectID  = id
         FROM sysobjects
        WHERE type = 'U'
          AND name = @OnlyTableName
        ORDER BY name
    
       SELECT @LastColumnId = MAX(colid) FROM syscolumns WHERE id = @ObjectID
    
       INSERT #columns
       SELECT col.name,
              typ.name,
              CASE WHEN typ.name in ('decimal','numeric') THEN '(' +
    convert(varchar, col.prec) + ',' + convert(varchar, col.scale) + ')'
                   WHEN typ.name like '%char%'THEN
    '('+CONVERT(varchar,col.length)+')'
                   ELSE '' END,
              CASE WHEN col.status = 0x80 THEN 'IDENTITY' ELSE '' END,
              CASE WHEN convert(bit, (col.status & 8)) = 0 THEN "NOT NULL"
    ELSE "NULL" END + CASE WHEN col.colid = @LastColumnId THEN ')' ELSE
    ',' END,
              NULL
         FROM syscolumns col, systypes typ
        WHERE col.id = @ObjectID
          AND col.usertype = typ.usertype
        ORDER BY col.colid
    
    
       INSERT #rtn
       SELECT "CREATE TABLE " + @TableName + " ("
       UNION ALL
       SELECT '    '+
                        column_name + replicate(' ',30- len(column_name)) +
                        type_name + length + replicate(' ',20 -
    len(type_name+length)) +
                        iden_flag + replicate(' ',10 - len(iden_flag))+
                        null_flag
            FROM #columns
    
       SELECT name, indid, status, 'N' as flag INTO #indexes
       FROM sysindexes WHERE id = @ObjectID
    
       SET ROWCOUNT 1
       WHILE 1=1
       BEGIN
          SELECT @IndexName = name, @IndexID = indid, @IndexStatus =
    status FROM #indexes WHERE flag = 'N'
          IF @@ROWCOUNT = 0
             BREAK
    
          SELECT @i = 1
          SELECT @msg = ''
          WHILE 1=1
          BEGIN
             IF index_col(@TableName, @IndexID, @i) IS NULL
                BREAK
    
             SELECT @msg = @msg + index_col(@TableName, @IndexID, @i) +
    CASE WHEN index_col(@TableName, @IndexID, @i+1) IS NOT NULL THEN ','
    END
             SELECT @i = @i+1
          END
    
          IF @IndexStatus & 2048 = 2048 --PRIMARY KEY
             INSERT #rtn
             SELECT "ALTER TABLE " + @TableName +
                    " ADD CONSTRAINT " + @IndexName +
                    " primary key "+
                    CASE WHEN @IndexID != 1 THEN 'nonclustered ' END +
    '('+ @msg +')'
          ELSE
             IF (@IndexStatus & 2048 = 0 AND @IndexID NOT IN (0, 255))
    --NOT PRIMARY KEY
                INSERT #rtn
                SELECT 'CREATE '+
                CASE WHEN @IndexStatus & 2 = 2 THEN 'UNIQUE ' ELSE '' END +
                CASE WHEN @IndexID = 1 THEN 'CLUSTERED ' ELSE 'NONCLUSTERED ' END +
                'INDEX ' + @IndexName + ' ON ' + @TableName + ' ('+ @msg +')'
    
          UPDATE #indexes SET flag = 'Y' WHERE indid = @IndexID
    
       END
       SET ROWCOUNT 0
    
       SELECT * FROM #rtn
    
       DROP TABLE #columns
       DROP TABLE #rtn
    

    (这一项的学分归洛奇所有;-)

        3
  •  1
  •   hasski    14 年前

    是的,但不仅仅是表名和列。 值得注意的是,sybase代码的底层资源是如此之少

        4
  •  0
  •   Arun Christopher    11 年前

    ASE附带DDL脚本生成器实用程序- ddlgen

    该实用工具可用于为整个数据库、表等创建脚本备份。Sybase帮助站点中提供了示例命令。