Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Pesquisar colunas dinamicamente para determinada tabela

  1. Você precisa pesquisar apenas colunas que realmente contenham strings, não todas as colunas em uma tabela (que pode incluir números inteiros, datas, GUIDs etc.).
  2. Você não precisa de uma tabela #temp (e certamente não precisa de uma tabela ##temp).
  3. Você precisa usar SQL dinâmico (embora eu não tenha certeza se isso faz parte do seu currículo até agora).
  4. Acho benéfico seguir alguns convenções simples , todos os quais você violou:
    • use PROCEDURE não PROC - não é um "prock", é um "procedimento armazenado".
    • use dbo. (ou esquema alternativo) prefixo ao fazer referência a qualquer objeto .
    • prepare o corpo do procedimento em BEGIN /END .
    • use as vogais livremente. Você está economizando tantas teclas, não importa o tempo, dizendo @tblname em vez de @tablename ou @table_name ? Não estou lutando por uma convenção específica, mas salvar caracteres em detrimento da legibilidade perdeu o charme nos anos 70.
    • não use o sp_ prefixo para procedimentos armazenados - esse prefixo tem um significado especial no SQL Server. Nomeie o procedimento para o que ele faz. Não precisa de prefixo, assim como sabemos que são tabelas mesmo sem um tbl prefixo. Se você realmente precisar de um prefixo, use outro como usp_ ou proc_ mas, pessoalmente, acho que esse prefixo não fornece nenhuma informação que você ainda não tenha.
    • como as tabelas são armazenadas usando Unicode (e algumas de suas colunas também), seus parâmetros devem ser NVARCHAR , não VARCHAR . E os identificadores são limitados a 128 caracteres, portanto, não há motivo para suportar> 257 caracteres para @tablename .
    • terminar instruções com ponto e vírgula .
    • use as visualizações do catálogo em vez de INFORMATION_SCHEMA - embora o último seja o que seu professor possa ter ensinado e possa esperar.
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

Quando você está feliz que está gerando o SELECT consulta que você está procurando, comente o PRINT e descomente o EXEC .