2013-09-02 3 views
0

Je veux créer un SP pour générer les métadonnées pour toutes les tables en utilisant des curseurs dans SQL. Voici le code que j'ai essayé. mais il devient une boucle sans fin et les mêmes données sont répétées. Merci d'avance.Le curseur devient une boucle sans fin

--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

Y at-il une raison de faire cela avec un curseur? – Lamak

+0

@Lamak pourriez-vous me s'il vous plaît quelle est l'autre façon que je pourrais faire. dans mon information_schema.columns j'ai 3 tables et et chaque table a 4 colonnes chacune et j'ai donc utilisé des curseurs – user2646320

+0

@Lamak j'ai dit 3 tables comme un exemple. En fait, j'ai beaucoup de tables dans mon projet disent environ 200 tables. et ceci pour montrer dans un rapport using SSIS et le client est spécifique qu'ils ont besoin en employant la procédure stockée que n'importe quelle autre partie de l'amélioration de la performance. – user2646320

Répondre

3

Je ne comprends pas vraiment pourquoi vous avez besoin de stocker ces informations sur une table, car il est déjà disponible sur les vues du système (et si vous avez encore besoin de stocker ces données, pourquoi vous utilisez un curseur?). Si, comme votre commentaire dit, vous avez besoin de stocker des données à partir de 3 tables, vous pouvez simplement faire:

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') 

Mais encore une fois, je ne vois pas le point. vous pouvez au moins stocker la date à laquelle cela a été fait:

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

regard où vous avez cette déclaration de fin

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

Suspect il ne fait jamais à cette ligne

FETCH NEXT FROM CURSOR_1 into 

Et d'accord avec d'autres commentaires sur est un curseur la bonne approche, mais c'est une réponse à la question comme indiqué.

+0

L'erreur était la déclaration END mal placée. Merci à tous .. – user2646320

+0

Alors, comment est-ce pas une réponse? – Paparazzi

1

Je pense obtenir méta-données de sys.columns plus préférable (dans votre cas, le curseur n'est pas nécessaire):

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'