1
votes

comment trouver des tables qui ont des valeurs de colonne si je ne connais pas la table

Nous avons une application utilisée au travail qui a été créée par un tiers. Nous avons donc accès à l'interface utilisateur et non au code backend. Sur cette application, il y a une liste déroulante. J'ai accès à la base de données MSSQL sur laquelle cette application s'exécute.

J'ai besoin de savoir d'où cette liste déroulante tire ses informations mais je ne sais pas quelle table elle utilise (car je ne peux pas vérifier le code directement).

Y a-t-il une requête que je peux écrire pour rechercher dans toute la base de données des tables contenant des colonnes contenant une valeur spécifique?

Les valeurs de la liste déroulante sont:

  • WebsiteAPP
  • Application BOT
  • Marche
  • BotLead

0 commentaires

5 Réponses :


0
votes

Vous pouvez interroger sys.tables et sys.columns pour localiser une liste de table.column contenant des informations textuelles, puis à partir de cela générer un certain nombre de requêtes SQL sélectionnez [nom_colonne] dans [nom_table] où [nom_colonne] dans ('valeur1', 'valeur2')


0 commentaires

3
votes

Vous pouvez utiliser SQL Server Profiler ou Session d'événements étendus pour capturer les instructions exécutées par rapport à la base de données. Pour ce faire, le moyen le plus simple consiste à utiliser le Fonctionnalité SSMS XEvent Profiler (introduite dans Management Studio version 17.3). En gros, vous commencez à capturer les instructions exécutées, ouvrez l'application pour lui faire charger la liste, arrêtez le traçage et regardez les requêtes capturées pour déterminer la source des données.


2 commentaires

Le problème avec SQL Server Profiler est que des milliers de personnes utilisent quotidiennement l'application. localiser cette requête exacte sera une mission


Vous pouvez le faire sur une instance de test distincte ou dans la fenêtre de maintenance. Mais si vous ne pouvez pas, vous pouvez rechercher le contenu de toutes les colonnes de texte dans tous les tableaux. Il y a beaucoup de questions dans SO, par exemple celui-ci .



0
votes
USE AdventureWorks;
GO

SET NOCOUNT ON;

DECLARE @T TABLE (ColumnName SYSNAME, TableName SYSNAME);

DECLARE
    @SearchString VARCHAR(255) = 'Simon',
    @SQL NVARCHAR(MAX);

DECLARE CUR CURSOR LOCAL FAST_FORWARD FOR
SELECT
    'SELECT ' + 
        QUOTENAME(c.name) + ', ''' + 
        OBJECT_SCHEMA_NAME(c.object_id) + '.' + OBJECT_NAME(c.object_id) + 
    ''' FROM ' + QUOTENAME(OBJECT_SCHEMA_NAME(c.object_id)) + '.' + QUOTENAME(OBJECT_NAME(c.object_id)) + 
    ' WHERE ' + QUOTENAME(c.name) + ' = ''' + @SearchString + ''';'
FROM
    sys.columns c
INNER JOIN
    sys.types t
        ON c.user_type_id = t.user_type_id
WHERE
    c.collation_name IS NOT NULL
    AND t.name NOT IN ('text','ntext')
    AND OBJECTPROPERTY(c.object_id,'IsSystemTable') = 0
    AND OBJECTPROPERTY(c.object_id,'IsMSShipped') = 0
    AND OBJECTPROPERTY(c.object_id,'IsTable') = 1;

OPEN CUR;
FETCH CUR INTO @SQL;
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @SQL;

    INSERT INTO @T
    EXEC sp_executesql @SQL;

    FETCH CUR INTO @SQL;
END;
CLOSE CUR;
DEALLOCATE CUR;

SELECT DISTINCT
    *
FROM
    @T;

0 commentaires

1
votes

Vous pouvez essayer de générer et d'exécuter une instruction SQL dynamique, basée sur les informations contenues dans INFORMATION_SCHEMA.COLUMNS:

SELECT
    N'SELECT ' +
    N'''' + TABLE_NAME + N''' AS TableName, ' +
    N'''' + COLUMN_NAME + N''' AS ColumnName, ' +
    QUOTENAME(COLUMN_NAME) + 
    N' FROM ' + QUOTENAME(TABLE_NAME) +
    N' WHERE ' + QUOTENAME(COLUMN_NAME) + N' IN (''WebsiteAPP'', ''BOT App'', ''Walkin'', ''BotLead''); '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE 
    DATA_TYPE = ('varchar') OR 
    DATA_TYPE = ('nvarchar');

Ou simplement obtenir toutes les instructions SQL dans une table et les exécuter comme vous le souhaitez :

DECLARE @stm nvarchar(max)
SET @stm = N''

SELECT @stm = @stm +
    N'SELECT ' +
    N'''' + TABLE_NAME + N''' AS TableName, ' +
    N'''' + COLUMN_NAME + N''' AS ColumnName, ' +
    QUOTENAME(COLUMN_NAME) + 
    N' FROM ' + QUOTENAME(TABLE_NAME) +
    N' WHERE ' + QUOTENAME(COLUMN_NAME) + N' IN (''WebsiteAPP'', ''BOT App'', ''Walkin'', ''BotLead''); '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE 
    DATA_TYPE = ('varchar') OR 
    DATA_TYPE = ('nvarchar');

PRINT @stm
EXEC sp_executesql @stm


0 commentaires

0
votes

Vous pouvez obtenir ce que vous voulez avec la requête suivante, remplacez simplement MyDatabase par le nom de votre base de données (commentaires nécessaires dans le code):

-- define cursor to loop through all columns
declare crs cursor for
select object_name(object_id), name from MyDatabase.sys.columns
where collation_name is not null --here we add this constraint to check only varchar columns
declare @tableName varchar(1000), @columnName varchar(1000), @sql varchar(1000);

open crs
fetch next from crs into @tableName, @columnName
while @@FETCH_STATUS = 0
begin
    -- craete dynamic sql, which will check if all values exist in that column, if so, print table name
    set @sql = 'if exists(select * from MyDatabase..' + @tableName + ' where ' + @columnName + ' = ''Value1'') ' +
    -- to add more values, just modify this dynamic sql (add another exist(...))
        'and exists(select * from MyDatabase..' + @tableName + ' where ' + @columnName + ' = ''Value2'') '
        'and exists(select * from MyDatabase..' + @tableName + ' where ' + @columnName + ' = ''Value3'') print ''' + @tableName + ''';'
    exec (@sql)
    fetch next from crs into @tableName, @columnName
end
close crs
deallocate crs

REMARQUE : cela générera quelques erreurs, mais parmi elles, le nom de la table sera imprimé, il suffit de le rechercher :)


0 commentaires