T-SQL

2012-10-10 16 views
13

ile bazı alt dizinler için bir DB'deki tüm metin alanlarını aramak için Yüzlerce tablo ve birkaç bin sütunla birlikte büyük bir şema sahibiyim. Belirli bir IP adresinin bu veritabanında çeşitli yerlerde saklandığını biliyordum, ancak hangi tabloların veya sütunların depolandığından emin değilim. Temel olarak, her yerde bunu bulmaya çalışıyorum. IP adresi DB'de saklanır, böylece tüm bu yerlerde yeni bir değere güncelleyebilirim.T-SQL

İşte bir T-SQL deyimindeki ilk çatlağım tabloyu ve sütun adını yazdıracak ve bu değer, veritabanındaki 10.15.13 alt dizinine sahip her bir metin sütunundaki değeri.

Şimdi, bu tür işler. Sorun şu ki, Management Studio'da çalıştırdığımda, sp_executesql çağrısı hiçbir şey döndürmeyen her sorgudaki tüm boş sonuçları gerçekten döndürecektir (yani sütunun bu alt dize ile herhangi bir kaydı yoktur) ve sonuç penceresini doldurur. Max'e, sonra da herhangi bir şeyin basılmış olup olmadığını göremiyorum.

Bu sorguyu yazmanın daha iyi bir yolu var mı? Ya da bunu farklı bir şekilde çalıştırabilirim, böylece yalnızca bu alt dizinin bulunduğu Tabloları ve Sütunları göstersin?

DECLARE 
    @SchemaName VARCHAR(50), 
    @TableName VARCHAR(50), 
    @ColumnName VARCHAR(50); 
BEGIN 
    DECLARE textColumns CURSOR FOR 
    SELECT s.Name, tab.Name, c.Name 
    FROM Sys.Columns c, Sys.Types t, Sys.Tables tab, Sys.Schemas s 
    WHERE s.schema_id = tab.schema_id AND tab.object_id = c.object_id AND c.user_type_id = t.user_type_id 
    AND t.Name in ('TEXT','NTEXT','VARCHAR','CHAR','NVARCHAR','NCHAR'); 

    OPEN textColumns 

    FETCH NEXT FROM textColumns 
    INTO @SchemaName, @TableName, @ColumnName 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     DECLARE @sql NVARCHAR(MAX), 
       @ParamDef NVARCHAR(MAX), 
       @result NVARCHAR(MAX);    
     SET @sql = N'SELECT ' + @ColumnName + ' FROM ' + @SchemaName + '.' + @TableName + ' WHERE ' + @ColumnName + ' LIKE ''%10.15.13%'''; 
     SET @ParamDef = N'@resultOut NVARCHAR(MAX) OUTPUT'; 

     EXEC sp_executesql @sql, @ParamDef, @resultOut = @result OUTPUT; 

     PRINT 'Column = ' + @TableName + '.' + @ColumnName + ', Value = ' + @result; 
     FETCH NEXT FROM textColumns 
     INTO @SchemaName, @TableName, @ColumnName  
    END 
    CLOSE textColumns; 
    DEALLOCATE textColumns; 
END 
Ben alt dize bulundu ki tablo/sütun ve bu sütundaki tam değerini gösterir yerde de böyle sonuçlar şey görmek istiyorum

...

Column = SomeTable.SomeTextColumn, Value = 'https://10.15.13.210/foo' 
Column = SomeTable.SomeOtherColumn, Value = '10.15.13.210' 

vs.

+0

Kapanışınız. Bu örnekle sizinkiyle karşılaştırın: [SQL Server tablosundaki tüm sütunlarda dize değeri arama ve bulma] (http://www.mssqltips.com/sqlservertip/1522/searching-and-finding-a-string-value-in -all-sütunlar-in-a-sql-sunucu-tablo /) – Jeremy

+0

Başar Teşekkürler! Aslında bu çözümü bağlantıdan kullanmamıştım çünkü bir kerede tek bir tabloyu aramak içindir, ancak bir veritabanındaki tüm tabloları aramak için tam bir çözümün başka bir bağlantısı vardı; tam olarak ihtiyacım olan şey. http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm Lütfen bunu bir cevap olarak gönderin ve doğru olarak işaretleyeceğim! – Jim

+0

Cevabın yanı sıra, kuşak için atıfta bulunduğunuz bağlantıyı da ekledim. Teşekkürler! – Jeremy

cevap

24

Kapa çeneni. How to search all columns of all tables in a database for a keyword?

DÜZENLEME:: link Hiç kötü giderse olur ne olmaz, burada çözümdür Yukarıdaki bağlantı tek bir tablo arama içindir

Ancak burada tüm tabloları içeren başka link Searching and finding a string value in all columns in a SQL Server table: Bu örnekte kendinizinkileri karşılaştırın söz konusu bağlantıdan ...

CREATE PROC SearchAllTables 
(
    @SearchStr nvarchar(100) 
) 
AS 
BEGIN 

    -- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved. 
    -- Purpose: To search all columns of all tables for a given search string 
    -- Written by: Narayana Vyas Kondreddi 
    -- Site: http://vyaskn.tripod.com 
    -- Tested on: SQL Server 7.0 and SQL Server 2000 
    -- Date modified: 28th July 2002 22:50 GMT 


    CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

    SET NOCOUNT ON 

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
    SET @TableName = '' 
    SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

    WHILE @TableName IS NOT NULL 
    BEGIN 
     SET @ColumnName = '' 
     SET @TableName = 
     (
      SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
      FROM INFORMATION_SCHEMA.TABLES 
      WHERE  TABLE_TYPE = 'BASE TABLE' 
       AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
       AND OBJECTPROPERTY(
         OBJECT_ID(
          QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
          ), 'IsMSShipped' 
           ) = 0 
     ) 

     WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
     BEGIN 
      SET @ColumnName = 
      (
       SELECT MIN(QUOTENAME(COLUMN_NAME)) 
       FROM INFORMATION_SCHEMA.COLUMNS 
       WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
        AND TABLE_NAME = PARSENAME(@TableName, 1) 
        AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') 
        AND QUOTENAME(COLUMN_NAME) > @ColumnName 
      ) 

      IF @ColumnName IS NOT NULL 
      BEGIN 
       INSERT INTO #Results 
       EXEC 
       (
        'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
        FROM ' + @TableName + ' (NOLOCK) ' + 
        ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
       ) 
      END 
     END 
    END 

    SELECT ColumnName, ColumnValue FROM #Results 
END 


EXEC SearchAllTables '<yourSubstringHere>' 

Not: yorum kod parçacığının anlaşılacağı gibi, SQL Server'ın eski sürümlerini kullanılarak test edilmiştir. Bu SQL Server çalışmayabilir 2012.

+0

-1 SQL Server aşağıdaki hatayı alıyorum 2012 "Msg 217, Level 16, State 1, Procedure SearchAllTables, Hat 54 Maksimum saklı yordam, işlev, tetikleyici veya görünüm yuvalama seviyesi aşıldı (sınır 32)." – codemonkeh

+0

codemonkeh, her uygulamadan sonra, YA çalıştırılmadan önce açılan StoredProcedure ve geçici tablo ifadeleri eklemek için emin olun. – Munawar

+0

aşıldı 2012 SQL Server "Msg 217, Level 16, State 1, Procedure SearchAllTables, Hat 54 Maksimum saklı yordam, işlev, tetikleyici veya görünüm yuvalanma düzeyine aşağıdaki hatayı (sınır 32) olsun. Aynı hata – Jahangeer

0

O

alter PROC SearchAllTables 
(
    @SearchStr nvarchar(100) 
) 
AS 
BEGIN 



    CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

    SET NOCOUNT ON 

    DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
    SET @TableName = '' 
    SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

    WHILE @TableName IS NOT NULL 
    BEGIN 
     SET @ColumnName = '' 
     SET @TableName = 
     (
      SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
      FROM INFORMATION_SCHEMA.TABLES 
      WHERE  TABLE_TYPE = 'BASE TABLE' 
       AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
       AND OBJECTPROPERTY(
         OBJECT_ID(
          QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
          ), 'IsMSShipped' 
           ) = 0 
     ) 

     WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
     BEGIN 
      SET @ColumnName = 
      (
       SELECT MIN(QUOTENAME(COLUMN_NAME)) 
       FROM INFORMATION_SCHEMA.COLUMNS 
       WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
        AND TABLE_NAME = PARSENAME(@TableName, 1) 
        AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') 
        AND QUOTENAME(COLUMN_NAME) > @ColumnName 
      ) 

      IF @ColumnName IS NOT NULL 
      BEGIN 
       INSERT INTO #Results 
       EXEC 
       (
        'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
        FROM ' + @TableName + ' (NOLOCK) ' + 
        ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
       ) 
      END 
     END 
    END 

    SELECT ColumnName, ColumnValue FROM #Results 
END 
o seçilmiş cevabı parlak

3

yardımcı Umut aşan size limit hatası vermeyecektir bu deneyin, ama ne zaman bulundu Bunu tekrar tekrar kullanarak sonuçlar hatalıydı, bu yüzden doğru sonuçlarla yeniden çalıştırılabilmesi için bazı temizlemeyi ekledim:

IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'SearchAllTables') 
    DROP PROC SearchAllTables 
GO 

CREATE PROC SearchAllTables 
(
    @SearchStr nvarchar(100) 
) 
AS 
BEGIN 

    -- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved. 
    -- Purpose: To search all columns of all tables for a given search string 
    -- Written by: Narayana Vyas Kondreddi 
    -- Slightly modified by: Natalie Ford, 6/10/15 
    -- Site: http://vyaskn.tripod.com 
    -- Tested on: SQL Server 7.0 and SQL Server 2000 
    -- Date modified: 28th July 2002 22:50 GMT 

    CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

    SET NOCOUNT ON 

    TRUNCATE Table #Results 

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
    SET @TableName = '' 
    SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

    WHILE @TableName IS NOT NULL 
    BEGIN 
     SET @ColumnName = '' 
     SET @TableName = 
     (
      SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
      FROM INFORMATION_SCHEMA.TABLES 
      WHERE  TABLE_TYPE = 'BASE TABLE' 
       AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
       AND OBJECTPROPERTY(
         OBJECT_ID(
          QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
          ), 'IsMSShipped' 
           ) = 0 
     ) 

     WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
     BEGIN 
      SET @ColumnName = 
      (
       SELECT MIN(QUOTENAME(COLUMN_NAME)) 
       FROM INFORMATION_SCHEMA.COLUMNS 
       WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
        AND TABLE_NAME = PARSENAME(@TableName, 1) 
        AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') 
        AND QUOTENAME(COLUMN_NAME) > @ColumnName 
      ) 

      IF @ColumnName IS NOT NULL 
      BEGIN 
       INSERT INTO #Results 
       EXEC 
       (
        'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
        FROM ' + @TableName + ' (NOLOCK) ' + 
        ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
       ) 
      END 
     END 
    END 

    SELECT ColumnName, ColumnValue FROM #Results 

    DROP TABLE #Results 
END