sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo encontrar una cadena dentro de una base de datos completa?

Esto funcionará:

DECLARE @MyValue NVarChar(4000) = 'something';

SELECT S.name SchemaName, T.name TableName
INTO #T
FROM sys.schemas S INNER JOIN
     sys.tables T ON S.schema_id = T.schema_id;

WHILE (EXISTS (SELECT * FROM #T)) BEGIN
  DECLARE @SQL NVarChar(4000) = 'SELECT * FROM $$TableName WHERE (0 = 1) ';
  DECLARE @TableName NVarChar(1000) = (
    SELECT TOP 1 SchemaName + '.' + TableName FROM #T
  );
  SELECT @SQL = REPLACE(@SQL, '$$TableName', @TableName);

  DECLARE @Cols NVarChar(4000) = '';

  SELECT
    @Cols = COALESCE(@Cols + 'OR CONVERT(NVarChar(4000), ', '') + C.name + ') = CONVERT(NVarChar(4000), ''$$MyValue'') '
  FROM sys.columns C
  WHERE C.object_id = OBJECT_ID(@TableName);

  SELECT @Cols = REPLACE(@Cols, '$$MyValue', @MyValue);
  SELECT @SQL = @SQL + @Cols;

  EXECUTE(@SQL);

  DELETE FROM #T
  WHERE SchemaName + '.' + TableName = @TableName;
END;

DROP TABLE #T;

Sin embargo, un par de advertencias. En primer lugar, es increíblemente lento y no está optimizado . Todos los valores se están convirtiendo a nvarchar simplemente para que puedan compararse sin error. Puede tener problemas con valores como datetime no convertir como se esperaba y, por lo tanto, no coincidir cuando debería ser (falsos negativos).

El WHERE (0 = 1) está ahí para construir el OR cláusula más fácil. Si no hay coincidencias, no recuperará ninguna fila.