web-dev-qa-db-fra.com

Comment rechercher la base de données du serveur SQL pour la chaîne?

Je sais que c'est possible, mais je ne sais pas comment.

Je dois rechercher dans la base de données Microsoft SQL toutes les mentions de chaîne spécifique . Par exemple: je souhaite rechercher dans toutes les tables, vues, fonctions, procédures stockées, ... la chaîne "tblEmployes". (Pas de données dans les tables)

Une des raisons pour lesquelles j'ai besoin de cela, je voudrais supprimer quelques tables de données supplémentaires créées, mais je crains qu'elles ne soient utilisées quelque part dans les procédures ou les fonctions.

Toute aide est appréciée.

90
bobetko

cela recherchera chaque colonne de chaque table dans une base de données spécifique. créer le proc stocké sur la base de données dans laquelle vous voulez chercher.

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/the-ten-most-asked-sql-server-questions--1#2 :

CREATE PROCEDURE FindMyData_String
    @DataToFind NVARCHAR(4000),
    @ExactMatch BIT = 0
AS
SET NOCOUNT ON

DECLARE @Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)

    INSERT  INTO @Temp(TableName,SchemaName, ColumnName, DataType)
    SELECT  C.Table_Name,C.TABLE_SCHEMA, C.Column_Name, C.Data_Type
    FROM    Information_Schema.Columns AS C
            INNER Join Information_Schema.Tables AS T
                ON C.Table_Name = T.Table_Name
        AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
    WHERE   Table_Type = 'Base Table'
            And Data_Type In ('ntext','text','nvarchar','nchar','varchar','char')


DECLARE @i INT
DECLARE @MAX INT
DECLARE @TableName sysname
DECLARE @ColumnName sysname
DECLARE @SchemaName sysname
DECLARE @SQL NVARCHAR(4000)
DECLARE @PARAMETERS NVARCHAR(4000)
DECLARE @DataExists BIT
DECLARE @SQLTemplate NVARCHAR(4000)

SELECT  @SQLTemplate = CASE WHEN @ExactMatch = 1
                            THEN 'If Exists(Select *
                                          From   ReplaceTableName
                                          Where  Convert(nVarChar(4000), [ReplaceColumnName])
                                                       = ''' + @DataToFind + '''
                                          )
                                     Set @DataExists = 1
                                 Else
                                     Set @DataExists = 0'
                            ELSE 'If Exists(Select *
                                          From   ReplaceTableName
                                          Where  Convert(nVarChar(4000), [ReplaceColumnName])
                                                       Like ''%' + @DataToFind + '%''
                                          )
                                     Set @DataExists = 1
                                 Else
                                     Set @DataExists = 0'
                            END,
        @PARAMETERS = '@DataExists Bit OUTPUT',
        @i = 1

SELECT @i = 1, @MAX = MAX(RowId)
FROM   @Temp

WHILE @i <= @MAX
    BEGIN
        SELECT  @SQL = REPLACE(REPLACE(@SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
        FROM    @Temp
        WHERE   RowId = @i


        PRINT @SQL
        EXEC SP_EXECUTESQL @SQL, @PARAMETERS, @DataExists = @DataExists OUTPUT

        IF @DataExists =1
            UPDATE @Temp SET DataFound = 1 WHERE RowId = @i

        SET @i = @i + 1
    END

SELECT  SchemaName,TableName, ColumnName
FROM    @Temp
WHERE   DataFound = 1
GO

pour l'exécuter, faites ceci:

exec FindMyData_string 'google', 0

fonctionne étonnamment bien !!!

Si vous avez besoin de rechercher des objets de base de données (tables, colonnes, déclencheurs, par exemple), jetez un coup d'œil à l'outil FREE Red-Gate appelé Recherche SQL qui fait cela - il recherche dans toute votre base pour tout type de chaîne.

enter image description here

enter image description here

C'est un excellent outil indispensable pour tout développeur de base de données ou d'administrateur de base de données - ai-je déjà mentionné qu'il est absolument GRATUIT à utiliser pour tout type d'utilisation?

56
marc_s

Vous pouvez également essayer ApexSQL Search - c’est un ajout gratuit de SSMS similaire à SQL Search. 

Si vous voulez vraiment utiliser uniquement SQL, vous voudrez peut-être essayer ce script

select 
S.name as [Schema], 
o.name as [Object], 
o.type_desc as [Object_Type], 
C.text as [Object_Definition]
from sys.all_objects O inner join sys.schemas S on O.schema_id = S.schema_id
inner join sys.syscomments C on O.object_id = C.id
where S.schema_id not in (3,4) -- avoid searching in sys and INFORMATION_SCHEMA schemas
and C.text like '%ICE_%'
order by [Schema]
45
George Ober

Pour obtenir une table par nom sur le serveur SQL:

SELECT *
FROM sys.Tables
WHERE name LIKE '%Employees%'

pour rechercher une procédure stockée par son nom:

SELECT name
FROM sys.objects
WHERE name = 'spName'

pour obtenir toutes les procédures stockées liées à une table:

----Option 1
SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '%tablename%'
----Option 2
SELECT DISTINCT o.name, o.xtype
FROM syscomments c
INNER JOIN sysobjects o ON c.id=o.id
WHERE c.TEXT LIKE '%tablename%'
16
TheBoyan

Vous pouvez exporter votre base de données (si petite) sur votre disque dur/bureau, puis effectuez simplement une recherche de chaîne via l'éditeur de texte.

14
Ivan Ivković

Cette procédure de recherche de code et la fonction mais pas la recherche dans la table :)

SELECT name FROM   sys.all_objects WHERE  Object_definition(object_id) LIKE '%text%' ORDER BY name
5
aykut aydoğan

vous pourriez;

  1. Scriptez la base de données dans un fichier unique et recherchez le fichier pour tblEmployees à l'aide d'un éditeur de texte Dans Outils de gestion SQL Server (SSMS), cliquez avec le bouton droit de la souris sur la base de données et choisissez Générer des scripts. 
  2. Utilisez "View Dependancies" de SSMS en faisant un clic droit sur tblEmployees pour voir quels autres objets en dépendent.
  3. Utilisez un outil tiers gratuit tel que RedGate SQLSearch pour rechercher tous les objets de base de données par nom et contenu par mot-clé. 
3
ajayel

Ceci recherchera une chaîne sur chaque base de données:

declare @search_term varchar(max)
set @search_term = 'something'

select @search_term = 'use ? SET QUOTED_IDENTIFIER ON
select
    ''[''+db_name()+''].[''+c.name+''].[''+b.name+'']'' as [object],
    b.type_desc as [type],
    d.obj_def.value(''.'',''varchar(max)'') as [definition]
from (
    select distinct
        a.id
    from sys.syscomments a
    where a.[text] like ''%'+@search_term+'%''
) a
inner join sys.all_objects b
    on b.[object_id] = a.id
inner join sys.schemas c
    on c.[schema_id] = b.[schema_id]
cross apply (
    select
        [text()] = a1.[text]
    from sys.syscomments a1
    where a1.id = a.id
    order by a1.colid
    for xml path(''''), type
) d(obj_def)
where c.schema_id not in (3,4) -- avoid searching in sys and INFORMATION_SCHEMA schemas
    and db_id() not in (1,2,3,4) -- avoid sys databases'

if object_id('tempdb..#textsearch') is not null drop table #textsearch
create table #textsearch
(
    [object] varchar(300),
    [type] varchar(300),
    [definition] varchar(max)
)

insert #textsearch
exec sp_MSforeachdb @search_term

select *
from #textsearch
order by [object]
2
kinzleb

Ancienne question, je le sais, mais voici ma version… .__ Je l’ai nommée «Aiguille dans la botte de foin» pour des raisons évidentes.

Il recherche une valeur spécifique dans chaque ligne et chaque colonne, pas pour les noms de colonne, etc.

Exécuter la recherche (remplacer les valeurs pour les deux premières variables du cours):

DECLARE @SEARCH_DB VARCHAR(100)='REPLACE_WITH_YOUR_DB_NAME'
DECLARE @SEARCH_VALUE_LIKE NVARCHAR(100)=N'%REPLACE_WITH_SEARCH_STRING%'

SET NOCOUNT ON;  
DECLARE col_cur CURSOR FOR
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM information_schema.columns WHERE TABLE_CATALOG=@SEARCH_DB AND DATA_TYPE NOT IN ('timestamp', 'datetime');

DECLARE @TOTAL int = (SELECT COUNT(*)
FROM information_schema.columns WHERE TABLE_CATALOG=@SEARCH_DB AND DATA_TYPE NOT IN ('timestamp', 'datetime'));


DECLARE @TABLE_CATALOG nvarchar(500), @TABLE_SCHEMA nvarchar(500), @TABLE_NAME nvarchar(500), @COLUMN_NAME nvarchar(500), @DATA_TYPE nvarchar(500);
DECLARE @SQL nvarchar(4000)='';

PRINT '-------- BEGIN SEARCH --------';  
OPEN col_cur;

FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE;

BEGIN TRY DROP TABLE ##RESULTS; END TRY BEGIN CATCH END CATCH
CREATE TABLE ##RESULTS( TABLE_CATALOG nvarchar(500), TABLE_SCHEMA nvarchar(500), TABLE_NAME nvarchar(500), COLUMN_NAME nvarchar(500), DATA_TYPE nvarchar(500), RECORDS int)  
DECLARE @SHOULD_CAST bit=0
DECLARE @i int =0
DECLARE @progress_sum bigint=0

WHILE @@FETCH_STATUS = 0  
BEGIN
    -- PRINT '' + CAST(@i as varchar(100)) +' of ' + CAST(@TOTAL as varchar(100)) + '  ' + @TABLE_CATALOG+'.'+@TABLE_SCHEMA+'.'+@TABLE_NAME+': '+@COLUMN_NAME+' ('+@DATA_TYPE+')';

    SET @SHOULD_CAST = (SELECT CASE @DATA_TYPE 
                                WHEN 'varchar' THEN 0
                                WHEN 'nvarchar' THEN 0
                                WHEN 'char' THEN 0
                                ELSE 1 END)

    SET @SQL='SELECT '''+@TABLE_CATALOG+''' catalog_name, '''+@TABLE_SCHEMA+''' schema_name, '''+@TABLE_NAME+''' table_name, '''+@COLUMN_NAME+''' column_name, '''+@DATA_TYPE+''' data_type, ' + 
            +' COUNT(['+@COLUMN_NAME+']) records '+
            +' FROM '+@TABLE_CATALOG+'.'+@TABLE_SCHEMA+'.'+@TABLE_NAME +
            +' WHERE ' + CASE WHEN @SHOULD_CAST=1 THEN 'CAST(['+@COLUMN_NAME + '] as NVARCHAR(max)) ' ELSE ' ['+@COLUMN_NAME + '] ' END 
            +' LIKE '''+ @SEARCH_VALUE_LIKE + ''' '

    -- PRINT @SQL;

    IF @i % 100 = 0
        BEGIN
            SET @progress_sum = (SELECT SUM(RECORDS) FROM ##RESULTS)
            PRINT CAST (@i as varchar(100)) +' of ' + CAST(@TOTAL as varchar(100)) +': '+ CAST (@progress_sum as varchar(100))
        END

    INSERT INTO ##RESULTS (TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, RECORDS)
    EXEC(@SQL)

    FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE;
    SET @i=@i+1
    -- IF @i > 1000
    --  BREAK
END   
CLOSE col_cur;  
DEALLOCATE col_cur;

SELECT * FROM ##RESULTS WHERE RECORDS>0;

Ensuite, pour afficher les résultats, même en cours d’exécution, depuis une autre fenêtre, exécutez:

DECLARE @SEARCH_VALUE_LIKE NVARCHAR(100)=N'%@FLEX@%'
SELECT * FROM ##RESULTS WHERE RECORDS>0;

SET NOCOUNT ON;  
DECLARE col_cur CURSOR FOR
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM ##RESULTS WHERE RECORDS>0;

DECLARE @TABLE_CATALOG nvarchar(500), @TABLE_SCHEMA nvarchar(500), @TABLE_NAME nvarchar(500), @COLUMN_NAME nvarchar(500), @DATA_TYPE nvarchar(500);
DECLARE @SQL nvarchar(4000)='';

OPEN col_cur;

FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE;
DECLARE @i int =0
DECLARE @SHOULD_CAST bit=0

WHILE @@FETCH_STATUS = 0  
BEGIN
    SET @SHOULD_CAST = (SELECT CASE @DATA_TYPE 
                                WHEN 'varchar' THEN 0
                                WHEN 'nvarchar' THEN 0
                                WHEN 'char' THEN 0
                                ELSE 1 END)

    SET @SQL='SELECT '''+@TABLE_CATALOG+''' catalog_name, '''+@TABLE_SCHEMA+''' schema_name, '''+@TABLE_NAME+''' table_name, '''+@COLUMN_NAME+''' column_name, '''+@DATA_TYPE+''' data_type, ' + 
            +' ['+@COLUMN_NAME+']'+
            +', * '
            +' FROM '+@TABLE_CATALOG+'.'+@TABLE_SCHEMA+'.'+@TABLE_NAME +
            +' WHERE ' + CASE WHEN @SHOULD_CAST=1 THEN 'CAST(['+@COLUMN_NAME + '] as NVARCHAR(max)) ' ELSE ' ['+@COLUMN_NAME + '] ' END 
            +' LIKE '''+ @SEARCH_VALUE_LIKE + ''' '

    PRINT @SQL;

    EXEC(@SQL)

    FETCH NEXT FROM col_cur INTO @TABLE_CATALOG, @TABLE_SCHEMA, @TABLE_NAME, @COLUMN_NAME, @DATA_TYPE;
    SET @i=@i+1
    -- IF @i > 10
    --  BREAK
END   
CLOSE col_cur;  
DEALLOCATE col_cur;

Quelques mentions à ce sujet:

  • il utilise des curseurs au lieu d'une boucle bloquante
  • il peut imprimer des progrès (décommenter si nécessaire)
  • il peut sortir après quelques tentatives (décommentez le SI à la fin)
  • il affiche tous les enregistrements
  • vous pouvez l'ajuster au besoin

LIMITATIONS DE RESPONSABILITÉ:

  • NE PAS l'exécuter dans des environnements de production! 
  • C'est lent. Si d’autres services/utilisateurs accèdent à la base de données, s’IL VOUS PLAÎT ajoutez "WITH (NOLOCK)" après chaque nom de table dans toutes les sélections, en particulier celles de sélection dynamique.
  • Il ne valide pas/ne protège pas contre toutes sortes d'options d'injection SQL.
  • Si votre base de données est énorme, préparez-vous à dormir, assurez-vous que la requête ne sera pas supprimée après quelques minutes.
  • Il renvoie certaines valeurs à string, notamment ints/bigints/smallints/tinyints. Si vous n'en avez pas besoin, placez-les dans les mêmes listes d'exclusion avec les horodatages en haut du script.

J'espère que cela t'aides.

2
user682385

A eu accès à une base de données, mais pas à la table dans laquelle ma requête était stockée.

Inspiré par la réponse de @marc_s, j’ai jeté un œil à HeidiSQL , qui est un programme Windows pouvant traiter MySQL, MSSQL et PostgreSQL. 

Trouvé qu'il peut également rechercher une chaîne dans une base de données.

 Click Search, then Find text on Server

 Search tool open. Make sure the DB is selected

Il va rechercher chaque table et vous donner combien de fois dans trouvé la chaîne par table!

1
Ari

La recherche d'objets de base de données SQL est possible avec SQL Server Management Studio avec les méthodes suivantes, avec la recherche d'objet SSMS: détails de l'explorateur d'objets ou scripts S-SQL, comme expliqué ci-après: 

0
Orhan Celik

Ici, comment chercher dans la base de données dans Swift avec la bibliothèque FMDB D'abord, cliquez sur ce lien et ajoutez-le à votre projet FMDB Quand vous l'avez fait, voici comment vous le faites, par exemple vous avez une table appelée Personne et vous avez firstName et secondName et vous voulez trouver des données par prénom Voici un code pour cela

    func loadDataByfirstName(firstName : String, completion: @escaping CompletionHandler){
    if isDatabaseOpened {
        let query = "select * from Person where firstName like '\(firstName)'"
        do {
            let results = try database.executeQuery(query, values: [firstName])
            while results.next() {
                let firstName = results.string(forColumn: "firstName") ?? ""
                let lastName = results.string(forColumn: "lastName") ?? ""
                let newPerson = Person(firstName: firstName, lastName: lastName)
                self.persons.append(newPerson)
            }
            completion(true)
        }catch let err {
            completion(false)
            print(err.localizedDescription)
        }
        database.close()
    } 
}

Ensuite, dans votre ViewController, vous écrivez ceci afin de personnaliser le détail de personne que vous recherchez.

  override func viewWillAppear(_ animated: Bool) {
     super.viewWillAppear(animated)
      SQLManager.instance.openDatabase { (success) in
        if success {
            SQLManager.instance.loadDataByfirstName(firstName: "Hardi") { (success) in
                if success {
                    // you have your data Here 
                }
            }
        }
    }  
}
0
hardiBSalih

Voici le même script que celui soumis par l'utilisateur l -'''''''--------- '' '' '' '' '' ', mais corrigé pour fonctionner sur un SQL sensible à la casse exemple, et avec quelques autres améliorations mineures. 

DROP PROCEDURE IF EXISTS dbo.spFind_Text_In_Database
GO

CREATE PROCEDURE dbo.spFind_Text_In_Database
    @strText_To_Find NVARCHAR(4000),
    @bitExact_Match BIT = 0
AS
SET NOCOUNT ON

DECLARE @Temp TABLE(RowId INT IDENTITY(1,1), SchemaName sysname, TableName sysname, ColumnName SysName, DataType VARCHAR(100), DataFound BIT)

    INSERT  INTO @Temp(TableName,SchemaName, ColumnName, DataType)
    SELECT  C.TABLE_NAME, C.TABLE_SCHEMA, C.COLUMN_NAME, C.DATA_TYPE
    FROM    INFORMATION_SCHEMA.COLUMNS AS C
            INNER Join INFORMATION_SCHEMA.TABLES AS T
                ON C.TABLE_NAME = T.TABLE_NAME
        AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
    WHERE   TABLE_TYPE = 'BASE TABLE'
            And DATA_TYPE In ('ntext','text','nvarchar','nchar','varchar','char')


DECLARE @i INT
DECLARE @MAX INT
DECLARE @TableName sysname
DECLARE @ColumnName sysname
DECLARE @SchemaName sysname
DECLARE @SQL NVARCHAR(4000)
DECLARE @PARAMETERS NVARCHAR(4000)
DECLARE @DataExists BIT
DECLARE @SQLTemplate NVARCHAR(4000)

SELECT  @SQLTemplate = CASE WHEN @bitExact_Match = 1
                            THEN 'If Exists(Select *
                                          From   ReplaceTableName
                                          Where  Convert(nVarChar(4000), [ReplaceColumnName])
                                                       = ''' + @strText_To_Find + '''
                                          )
                                     Set @DataExists = 1
                                 Else
                                     Set @DataExists = 0'
                            ELSE 'If Exists(Select *
                                          From   ReplaceTableName
                                          Where  Convert(nVarChar(4000), [ReplaceColumnName])
                                                       Like ''%' + @strText_To_Find + '%''
                                          )
                                     Set @DataExists = 1
                                 Else
                                     Set @DataExists = 0'
                            END,
        @PARAMETERS = '@DataExists Bit OUTPUT',
        @i = 1

SELECT @i = 1, @MAX = MAX(RowId)
FROM   @Temp

WHILE @i <= @MAX
    BEGIN
        SELECT  @SQL = REPLACE(REPLACE(@SQLTemplate, 'ReplaceTableName', QUOTENAME(SchemaName) + '.' + QUOTENAME(TableName)), 'ReplaceColumnName', ColumnName)
        FROM    @Temp
        WHERE   RowId = @i


        PRINT @SQL
        EXEC sp_executesql @SQL, @PARAMETERS, @DataExists = @DataExists OUTPUT

        IF @DataExists =1
            UPDATE @Temp SET DataFound = 1 WHERE RowId = @i

        SET @i = @i + 1
    END

SELECT  SchemaName,TableName, ColumnName
FROM    @Temp
WHERE   DataFound = 1
GO
0
Mike

Le contenu de toutes les procédures, vues et fonctions stockées est stocké dans le champ texte de la table sysComments . Le nom de tous les objets est stocké dans la table sysObjects et les colonnes dans sysColumns

Avec ces informations, vous pouvez utiliser ce code pour rechercher dans le contenu des vues, des procédures stockées et des fonctions pour le mot spécifié:

Select b.name from syscomments a 
inner join sysobjects b on a.id = b.id
where text like '%tblEmployes%' 

Cette requête vous donnera les objets qui contiennent le mot "tblEmployes".

Pour rechercher par le nom d'objets, vous pouvez utiliser ce code:

Select name from sysobjects 
where name like  '%tblEmployes%'

et enfin pour trouver les objets ayant au moins une colonne contenant le mot "tblEmployes" vous pouvez utiliser ce code:

Select b.name from syscolumns a inner join sysobjects b on a.id = b.id
where a.name like  '%tblEmployes%'

Vous pouvez combiner ces 3 requêtes avec union:

Select distinct b.name from syscomments a
inner join sysobjects b on a.id = b.id
where text like '%tblEmployes%' 
union
Select distinct name from sysobjects 
where name like  '%tblEmployes%'
union 
Select distinct b.name from syscolumns a inner join sysobjects b on a.id = b.id
where a.name like  '%tblEmployes%'

Avec cette requête, vous avez tous les objets contenant le mot "tblEmployes" dans le contenu ou le nom ou sous forme de colonne.

0
Mehdi akbari