2013-09-02 7 views
0

Я хочу создать SP для генерации метаданных для всех таблиц с помощью курсоров в SQL. Ниже приведен код, который я пробовал. но он становится бесконечным циклом и теми же данными повторяется. Заранее спасибо.Курсор становится бесконечным циклом

--SELECT * FROM information_schema.columns 

ALTER PROCEDURE p1 
AS 

    SET NOCOUNT ON; 

    DECLARE @id INT 
     , @tablename VARCHAR(100) 
     , @columnname VARCHAR(100) 
     , @datatype VARCHAR(100) 
     , @isnullable VARCHAR(100) 

    BEGIN 

     DECLARE CURSOR_1 CURSOR FOR 
     SELECT TABLE_NAME 
      , COLUMN_NAME 
      , DATA_TYPE 
      , IS_NULLABLE 
     FROM INFORMATION_SCHEMA.COLUMNS 
     WHERE TABLE_NAME = 'Employee' -- group BY table_name 

     OPEN CURSOR_1 

     FETCH NEXT FROM CURSOR_1 INTO 
      @tablename, 
      @columnname, 
      @datatype, 
      @isnullable 

     WHILE @@fetch_status = 0 
     BEGIN 
      INSERT INTO table_schema_detail (TABLE_NAME, COLUMN_NAME, DATA_TYPE, isnullable) 
      VALUES (@tablename, @columnname, @datatype, @isnullable) 
     END 

     FETCH NEXT FROM CURSOR_1 INTO 
      @tablename, 
      @columnname, 
      @datatype, 
      @isnullable 

     CLOSE CURSOR_1 
     DEALLOCATE CURSOR_1 

     SET NOCOUNT OFF; 

    END 
GO 
+2

Есть ли причина для этого с помощью курсора? – Lamak

+0

@ Lamak не могли бы вы рассказать мне, что я могу сделать другим способом. в моей inform_schema.columns у меня есть 3 таблицы, и каждая таблица имеет по 4 столбца каждый, поэтому я использовал курсоры – user2646320

+0

@Lamak В качестве примера я привел 3 таблицы. на самом деле у меня много таблиц в моем проекте говорят около 200 таблиц. и это предназначено для показа в отчете с использованием SSIS, и клиент определен, что им необходимо использовать Хранимую процедуру, чем любой другой, в рамках повышения производительности. – user2646320

ответ

3

Я не понимаю, почему вы должны хранить эту информацию на столе, так как он уже доступен на системных представлений (и, если вам все еще нужно хранить эти данные, почему вы используете курсор?). Если, как ваш комментарий говорит, что вам нужно для сохранения данных из 3 таблиц, то вы можете просто сделать:

INSERT INTO table_schema_detail(table_name,column_name,data_type,isnullable) 
SELECT table_name, column_name, data_type, is_nullable 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_name IN ('Employee','OtherTable1','OtherTable2') 

Но опять же, я не вижу смысла. По крайней мере, вы могли бы хранить дату, когда это было сделано:

INSERT INTO table_schema_detail(table_name,column_name,data_type,isnullable,DateInserted) 
SELECT table_name, column_name, data_type, is_nullable, GETDATE() 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_name IN ('Employee','OtherTable1','OtherTable2') 
2

посмотреть, где у вас есть, что конец заявления

insert INTO table_schema_detail(table_name,column_name,data_type,isnullable) VALUES(@tablename,@columnname,@datatype,@isnullable) 
end 

Подозреваемый никогда не попадает в эту линию

FETCH NEXT FROM CURSOR_1 into 

И согласен с другие комментарии - это правильный подход, но это ответ на поставленный вопрос.

+0

Ошибка была неверно поставлена ​​END statment. Спасибо всем .. – user2646320

+0

Тогда как это не ответ? – Paparazzi

1

Я думаю, получить мета-данные из sys.columns более предпочтительным (в вашем случае, курсор не обязательно):

INSERT INTO dbo.table_schema_detail 
(
     TABLE_NAME 
    , COLUMN_NAME 
    , DATA_TYPE 
    , IS_NULLABLE 
) 
SELECT 
     SCHEMA_NAME(o.[schema_id]) + '.' + o.name 
    , c.name 
    , TYPE_NAME(c.system_type_id) 
    , c.is_nullable 
FROM sys.columns c 
JOIN sys.objects o ON c.[object_id] = o.[object_id] 
WHERE SCHEMA_NAME(o.[schema_id]) + '.' + o.name = 'dbo.Employee' 
    AND o.[type] = 'U' 
Смежные вопросы