2010-09-15 23 views
2

我掃描了類似的問題,但他們似乎指的是其他數據庫和/或外部語言。如何通過SQL提取Sybase(12.5)表DDL?

我期待通過SQL以編程方式提取表的DDL,有結果的「足夠好」的重新導入和重建表。

DBArtisan可產生我在尋找確切的結果,但我有我需要使用的幾十桌的動態列表,並且希望的是程序化的解決方案。

我想DBArtisan中必須做調用API不知何故。他們只是對systables進行翻譯,或者是否存在一個我缺少的系統安裝存儲過程(類似於產生存儲過程的文本)?

+0

發現這是不是一個真正的編程問題 - 你需要找到你的數據庫實現適當的轉儲命令。例如在mysql中,它將是'mysqldump --add-drop-database --add-drop-table --databases '。 – Ether 2010-09-15 19:04:34

回答

2

IIRC有一個名爲DBSchema的工具(peppler.org/downloads/dbschema-2_4_2.zip是我能找到的最好的URL) - 萬一URL沒有響鈴,Mike Peppller是sybperl。如果您更願意推出自己的代碼,則可以對該腳本的代碼進行逆向工程。

就SQL而言,表信息位於sysobjects表中,列信息位於Sybase中的syscolumns

您還可以使用存儲的特效:http://www.razorsql.com/articles/sybase_admin_queries.html

+0

非常好,非常感謝。是的,看起來正確的解決方案是dbschema本身或在其中找到。 – 2010-09-16 14:38:22

+0

@邁克爾 - 很高興幫助。如果這是有用的,請隨時加價或接受:)) – DVK 2010-09-22 19:17:08

1

是的,但更多的比表名和列。 你需要約束,索引,鍵,默認值,分區,權限...... 顯着地面上的資源多麼的薄爲Sybase代碼,將做到這一點 (sp_help將不涵蓋這一切 - 測試,使用的東西像DBArtisan中提取DDL工具,你會看到那是多麼的全面!)

+0

一個完全合理的關注,但在我的情況下,我只需要最低公分母結構。 – 2012-03-08 17:45:49

4

最好的解決辦法是將包裝成一個不錯的存儲過程,但你應該從下面的代碼的想法。只需更換:

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 

讓我知道如果它幫助。

(學分去ROCKY這一個;-)

+0

啊,非常好,我喜歡它 – Moudiz 2014-08-28 12:57:50

0

ASE船舶與DDL腳本生成工具 - ddlgen

該實用程序可以用來爲整個數據庫創建腳本的備份,表,等等。Sybase幫助網站提供了示例命令。

在Windows下,utilty可以在%SYBASE%/ ASE-15_0/bin中