光标正在变成一个永无止境的循环

时间:2013-09-02 16:56:37

标签: sql-server-2008 tsql stored-procedures cursor

我想创建一个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

3 个答案:

答案 0 :(得分: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')

答案 1 :(得分: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

同意其他评论是光标是正确的方法,但这是对所述问题的答案。

答案 2 :(得分: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'