Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Rechercher dynamiquement des colonnes pour une table donnée

  1. Vous devez rechercher uniquement les colonnes qui contiennent réellement des chaînes, et non toutes les colonnes d'un tableau (qui peuvent inclure des entiers, des dates, des GUID, etc.).
  2. Vous ne devriez pas du tout avoir besoin d'une table #temp (et certainement pas d'une table ##temp).
  3. Vous devez utiliser SQL dynamique (bien que je ne sois pas sûr que cela ait fait partie de votre programme jusqu'à présent).
  4. Je trouve avantageux de suivre quelques conventions simples , que vous avez toutes violées :
    • utiliser PROCEDURE pas PROC - ce n'est pas une "proc", c'est une "procédure stockée".
    • utiliser dbo. (ou autre schéma) préfixe lors du référencement d'un objet .
    • enveloppez votre corps de procédure dans BEGIN /END .
    • utilisez les voyelles généreusement. Économisez-vous autant de frappes, peu importe le temps, en disant @tblname au lieu de @tablename ou @table_name ? Je ne me bats pas pour une convention en particulier mais la sauvegarde des caractères au détriment de la lisibilité a perdu son charme dans les années 70.
    • n'utilisez pas le sp_ préfixe pour les procédures stockées - ce préfixe a une signification particulière dans SQL Server. Nommez la procédure pour ce qu'elle fait. Il n'a pas besoin de préfixe, tout comme nous savons que ce sont des tables même sans tbl préfixe. Si vous avez vraiment besoin d'un préfixe ici, utilisez-en un autre comme usp_ ou proc_ mais personnellement, je ne pense pas que ce préfixe vous donne des informations que vous n'avez pas déjà.
    • puisque les tables sont stockées en Unicode (et certaines de vos colonnes peuvent l'être aussi), vos paramètres doivent être NVARCHAR , pas VARCHAR . Et les identifiants sont limités à 128 caractères, il n'y a donc aucune raison de prendre en charge> 257 caractères pour @tablename .
    • terminer les déclarations avec des points-virgules .
    • utiliser les vues de catalogue au lieu de INFORMATION_SCHEMA - bien que ce dernier soit ce que votre professeur a pu enseigner et auquel il pourrait s'attendre.
CREATE PROCEDURE dbo.SearchTable
    @tablename NVARCHAR(257),
    @term      NVARCHAR(4000)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @sql NVARCHAR(MAX);

    SET @sql = N'SELECT * FROM ' + @tablename + ' WHERE 1 = 0'; 

    SELECT @sql = @sql + ' 
      OR ' + c.name + ' LIKE ''%' + REPLACE(@term, '''', '''''') + '%'''
    FROM 
      sys.all_columns AS c
    INNER JOIN 
      sys.types AS t
      ON c.system_type_id = t.system_type_id
      AND c.user_type_id = t.user_type_id
    WHERE 
      c.[object_id] = OBJECT_ID(@tablename)
      AND t.name IN (N'sysname', N'char', N'nchar', 
        N'varchar', N'nvarchar', N'text', N'ntext');

    PRINT @sql;

    -- EXEC sp_executesql @sql;
END
GO

Lorsque vous êtes satisfait qu'il affiche le SELECT requête que vous recherchez, commentez le PRINT et décommentez le EXEC .