【问题标题】:Cursor is becoming an never ending loop光标正在成为一个永无止境的循环
【发布时间】:2013-09-02 16:56:37
【问题描述】:

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

【问题讨论】:

  • 是否有理由使用光标进行此操作?
  • @Lamak 你能告诉我我还能做什么。在我的 information_schema.columns 中,我有 3 个表,每个表都有 4 列,所以我使用了游标
  • @Lamak 我以 3 张桌子为例。实际上,我的项目中有很多表,大约有 200 个表。这是为了在使用 SSIS 的报告中显示,并且客户端特定于他们需要使用存储过程而不是任何其他作为性能改进的一部分。
  • 我怎么能猜到你的意思是作为一个例子?无论哪种方式,它就像从视图中插入行而不进行过滤一样简单(不过,我还是不明白为什么)
  • 好吧,这似乎并没有提供良好的性能,特别是因为您可以完全避免使用游标。你仍然可以在那里使用没有光标的 sp。

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


【解决方案1】:

我真的不明白为什么需要将这些信息存储在表中,因为它已经在系统视图中可用(如果您仍然需要存储这些数据,为什么要使用游标?)。如果,就像您的评论所说,您需要存储 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
    

    并同意其他 cmets on is a cursor 是正确的方法,但这是对上述问题的回答。

    【讨论】:

    • 那这不是答案吗?
    【解决方案3】:

    我认为从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'
    

    【讨论】:

      猜你喜欢
      • 2014-04-17
      • 2016-06-04
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-14
      相关资源
      最近更新 更多