Удалить все таблицы курсором (получить имена таблиц) в SQL Server - PullRequest
0 голосов
/ 31 марта 2019

У меня есть таблица метаданных со столбцом stg_table.Это имя таблицы базы данных STAGE в схеме dbo.Я хочу удалить таблицы, если существует курсор, когда столбец insert_type имеет значение «select».

Пример метаданных: https://imgur.com/a/TfyIWpv

И мой код курсора:

declare kursor cursor for 
     select * 
     from METADATA.dbo.META_SOURCESTAGE;

declare @insert_type varchar(15), 
        @stg_table varchar(30), 
        @src varchar(80), 
        @SQL varchar(254);

open kursor

fetch next from kursor into @insert_type, @stg_table, @src;

while @@FETCH_STATUS = 0
begin
    if @insert_type = 'select'
        begin
        select @SQL = 'IF OBJECT_ID('+@stg_table+') IS NOT NULL DROP TABLE '+@stg_table
    exec(@SQL)

    fetch next from kursor into @insert_type, @stg_table, @src;
    end
    if @insert_type = 'bulk'
        execute ('truncate table ' + @stg_table);

    print @stg_table;

    fetch next from kursor into @insert_type, @stg_table, @src;
end

close kursor;
deallocate kursor;

Я хочу удалить все существующие таблицы из STAGE.dbo. * Созданным курсоромв таблице METADATA.

Я получаю сообщение об ошибке:

Сообщение 4104, Уровень 16, Состояние 1, Строка 2
Составной идентификатор "STAGE.dbo.STG_KLIENT"не может быть связан.STAGE.dbo.STG_MELDUNEK

Сообщение 4104, уровень 16, состояние 1, строка 2
Не удалось связать идентификатор из нескольких частей "STAGE.dbo.STG_MIEJSCOWOSC".
STAGE.dbo.STG_PRACOWNIK

@ EDIT Изменен код - добавлено начало / конец, но ошибка все та же.

1 Ответ

0 голосов
/ 01 апреля 2019

Он жалуется на невозможность связать в вызове OBJECT_ID, ваш код приводит к чему-то вроде:

IF OBJECT_ID(STAGE.dbo.STG_KLIENT) IS NOT NULL DROP TABLE STAGE.dbo.STG_KLIENT

Часть DROP TABLE в порядке, но вам нужно указать имя таблицы в кавычкахв вашем вызове OBJECT_ID, поскольку он ожидает ввода (N)VARCHAR, поэтому используйте:

select @sql = 'IF OBJECT_ID('''+@stg_table+''') IS NOT NULL DROP TABLE '+@stg_table
--                           ^^            ^^

Кроме того, ваш код немного повсюду.Он пропустит некоторые таблицы, потому что то, что вы делаете:

  1. Выборка из курсора (1-й результат, давайте предположим, что выбран тип)
  2. Проверьте, если @insert_type = 'select',true, поэтому давайте войдем в блок
    • удалить таблицу, если она существует
    • извлечь из курсора (2-й результат, давайте снова предположим, что выбран тип
    • оставьте, если блок
  3. Проверить, если @insert_type = 'insert', false, не обрезать
  4. напечатать имя таблицы
  5. извлечь следующий из курсора -> 3-й результат, вы просто ничего не сделалисо вторым результатом, где вы должны были его опустить.

Вот немного улучшенная версия:

while @@FETCH_STATUS = 0
begin
    if @insert_type = 'select'
    begin
       select @sql = 'IF OBJECT_ID('''+@stg_table+''') IS NOT NULL DROP TABLE '+@stg_table
    end
    else if @insert_type = 'insert'
    begin
       select @sql = 'TRUNCATE TABLE ' + @stg_table
    end

    print @sql -- "debugging"

    -- only do those once if you can, so you don't get lost in how the code branches
    exec sp_executesql @sql
    fetch next from kursor into @insert_type, @stg_table, @src;
end

Кроме того, вам не нужен курсор для этого.просто сгенерируйте большой запрос и выполните его один раз.

DECLARE @sql NVARCHAR(MAX) = ''
SELECT @sql += CONCAT(CASE
                        WHEN meta.insert_table = 'select'
                         AND OBJECT_ID(meta.stg_table) IS NOT NULL
                        THEN CONCAT('DROP TABLE ', meta.stg_table)

                        WHEN meta.insert_table = 'insert'
                        THEN CONCAT('TRUNCATE TABLE', meta.stg_table)
                      END,
                      ';', CHAR(13), CHAR(10)) -- add newline for easier reading
  FROM METADATA.dbo.META_SOURCESTAGE meta

PRINT @sql
EXEC sp_executesql @sql

Это должно сработать, и хотя я не проверял его, надеюсь, вы поняли идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...