Как извлечь DDL таблицы Sybase (12.5) через SQL? - PullRequest
2 голосов
/ 15 сентября 2010

Я просканировал похожие вопросы, но они, похоже, относятся к другим базам данных и / или внешним языкам.

Я планирую программно извлечь таблицу DDL с помощью SQL, и этого результата достаточно, чтобы повторно импортировать и реконструировать таблицу.

DBArtisan дает точный результат, который я ищу, но у меня есть динамический список из нескольких десятков таблиц, с которыми мне нужно работать, и я надеялся на программное решение.

Я полагаю, что DBArtisan должен каким-то образом вызывать API. Они просто копируют systables или есть установленный системный хранимый процесс (похожий на тот, который выдает хранимый текст процесса), который мне не хватает?

Ответы [ 4 ]

4 голосов
/ 16 марта 2011

Лучшим решением было бы обернуть это в хорошую хранимую процедуру, но вы должны получить представление из кода ниже.Просто замените:

   SELECT @OnlyTableName = 'my_table_name'

именем вашей таблицы и выполните код, вы должны получить все DDL-операторы в таблице #rtn в конце этого кода:

   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 для этого; -)

2 голосов
/ 16 сентября 2010

IIRC есть инструмент под названием DBSchema (peppler.org/downloads/dbschema-2_4_2.zip - лучший URL, который мне удалось найти) - если URL не звонит в колокола, Майк Пепплер является автором sybperl , Скорее всего, вы сможете выполнить обратный инжиниринг кода для этого скрипта, если вы предпочитаете свернуть свой собственный.

Что касается SQL, информация о таблице находится в таблице sysobjects, а информация о столбце - в syscolumns в Sybase.

Вы также можете использовать сохраненные процы: http://www.razorsql.com/articles/sybase_admin_queries.html

1 голос
/ 17 января 2011

Да, но это больше, чем имена таблиц и столбцы. Вам нужны ограничения, индексы, ключи, значения по умолчанию, разделы, разрешения ...... Примечательно, насколько тонкими на местах являются ресурсы для кода Sybase, который это сделает (sp_help не покрывает все это - для тестирования используйте что-то вроде инструмента DBArtisan Extract DDL, и вы увидите, насколько всеобъемлющим является THAt!)

0 голосов
/ 17 апреля 2013

ASE поставляется с утилитой DDL Script Generator - ddlgen

Утилита может использоваться для создания резервной копии сценариев для всей базы данных, таблиц и т. Д. Примеры команд приведены на справочном сайте Sybase.

Под Windows утилиту можно найти по адресу% sybase% / ASE-15_0 / bin

...