2014-10-09 118 views
1

我完全不熟悉SQL,没有经验,所以请耐心等待。搜索特定字的SQL数据库

我需要知道是否可以搜索SQL数据库中的某个特定单词,如果是这样的话?

我们目前正在进行品牌重塑项目,我需要在我们的CMS(内容管理系统)数据库中查看所有对电子邮件地址的引用。所有我需要寻找的是:

.co.uk

下面是所有的含表有问题的数据库的截图,我不能让我的周围SQL头,我有没有试图找到答案的Google的快乐。

enter image description here

我需要在这个数据库中搜索一切,但我不知道内容是什么坐镇表,视图,列名等的,因为它是跨越所有这些都蔓延。

还有其他我需要搜索的表格,但希望能提供一个答案,我可以修改它来搜索这些表格。

+0

你可以试试Red Search的免费工具SQL Search:http://www.red-gate.com/products/sql-development/sql-search/ – NickyvV 2014-10-09 08:13:29

+0

@NickyvV我已经下载了它,但它说没有匹配我搜索的每个单词甚至单词'和' – murday1983 2014-10-09 08:17:42

回答

1

DB's并非真正适合这种模糊的搜索描述,您应该有一些定义或模型或要求规范来描述可能存在的值。

但是,当然,你可以选择使用动态SQL来做一个非常慢的方法。

我做了这个正确的快,只是测试它速度快,但它应该工作:

SET NOCOUNT ON 

IF OBJECT_ID('tempdb..#SEARCHTABLE') IS NOT NULL 
    DROP TABLE #SEARCHTABLE 

IF OBJECT_ID('tempdb..#RESULTS') IS NOT NULL 
    DROP TABLE #RESULTS 

CREATE TABLE #SEARCHTABLE (ROWNUM INT IDENTITY(1,1), SEARCHCLAUSE VARCHAR(2000) COLLATE DATABASE_DEFAULT) 

INSERT INTO #SEARCHTABLE (SEARCHCLAUSE) 
SELECT 'SELECT TOP 1 '''+TAB.name+''', '''+C.name+''' 
FROM ['+S.name+'].['+TAB.name+'] 
WHERE ' 
    +CASE WHEN T.name <> 'xml' 
     THEN '['+C.name+'] LIKE ''%.co.uk%'' AND ['+C.name+'] LIKE ''%@%''' 
     ELSE 'CAST(['+C.name+'] AS VARCHAR(MAX)) LIKE ''%.co.uk%'' AND CAST(['+C.name+'] AS VARCHAR(MAX)) LIKE ''%@%''' 
     END AS SEARCHCLAUSE 
FROM sys.tables TAB 
JOIN sys.schemas S on S.schema_id = TAB.schema_id 
JOIN sys.columns C on C.object_id = TAB.object_id 
JOIN sys.types T on T.user_type_id = C.user_type_id 
WHERE TAB.type_desc = 'USER_TABLE' 
AND (T.name LIKE '%char%' OR 
    T.name LIKE '%xml%') 
AND CASE WHEN C.max_length = -1 THEN 10 ELSE C.max_length END >= 6 -- To only search through sufficiently long column 

CREATE TABLE #RESULTS (ROWNUM INT IDENTITY(1,1), TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT, COLNAME VARCHAR(256) COLLATE DATABASE_DEFAULT) 

DECLARE @ROWNUM_NOW INT, @ROWNUM_MAX INT, @SQLCMD VARCHAR(2000), @STATUSSTRING VARCHAR(256) 

SELECT @ROWNUM_NOW = MIN(ROWNUM), @ROWNUM_MAX = MAX(ROWNUM) FROM #SEARCHTABLE 

WHILE @ROWNUM_NOW <= @ROWNUM_MAX 
BEGIN 
    SELECT @SQLCMD = SEARCHCLAUSE FROM #SEARCHTABLE WHERE ROWNUM = @ROWNUM_NOW 

    INSERT INTO #RESULTS 
    EXEC(@SQLCMD) 

    SET @STATUSSTRING = CAST(@ROWNUM_NOW AS VARCHAR(25))+'/'+CAST(@ROWNUM_MAX AS VARCHAR(25))+', time: '+CONVERT(VARCHAR, GETDATE(), 120) 

    RAISERROR(@STATUSSTRING, 10, 1) WITH NOWAIT 

    SELECT @ROWNUM_NOW = @ROWNUM_NOW + 1 
END 

SET NOCOUNT ON 

SELECT 'This table and column contains strings ".co.uk" and a "@"' INFORMATION, TABLENAME, COLNAME FROM #RESULTS 

-- Uncomment to drop the created temp tables 
--IF OBJECT_ID('tempdb..#SEARCHTABLE') IS NOT NULL 
-- DROP TABLE #TABLECOLS 

--IF OBJECT_ID('tempdb..#RESULTS') IS NOT NULL 
-- DROP TABLE #RESULTS 

它做什么,它搜索DB与他们的模式,里面有所有用户创建的表(正) char /(n)varchar/xml列的长度足够长,并逐一搜索它们中的每一个,直到找到至少一个匹配项,然后移动到列表中的下一个匹配项。匹配被定义为任何字符串或XML转换为字符串,其中包含文本“.co.uk”和“@” - 标记中的某处。

它将在消息选项卡上显示脚本的进度(已找到多少个可搜索的TABLE.COLUMN组合以及当前正在运行该列表中的哪一个,以及当前时间戳为秒)。准备好后,它会显示包含至少一个匹配的所有表和列名称。

因此,从该列表中,您必须手动搜索表格和列,才能找到究竟有多少种类型的匹配,以及您实际想要做什么。

编辑:我再次忽略使用系统对象sysnames,但我会稍后修改,如果需要。

1

我扔一起快速查询,这似乎为我工作:

--Search for a word in the current database 
SET NOCOUNT ON; 

--First make a hit list of possible tables/ columns 
DECLARE @HitList TABLE (
    Id INT IDENTITY(1,1) PRIMARY KEY, 
    TableName VARCHAR(255), 
    SchemaName VARCHAR(255), 
    ColumnName VARCHAR(255)); 
INSERT INTO 
    @HitList (
     TableName, 
     SchemaName, 
     ColumnName) 
SELECT 
    t.name, 
    s.name, 
    c.name 
FROM 
    sys.tables t 
    INNER JOIN sys.columns c ON c.object_id = t.object_id 
    INNER JOIN sys.schemas s ON s.schema_id = t.schema_id 
WHERE 
    c.system_type_id = 167; 

--Construct Dynamic SQL 
DECLARE @Id INT = 1; 
DECLARE @Count INT; 
SELECT @Count = COUNT(*) FROM @HitList; 
DECLARE @DynamicSQL VARCHAR(1024); 
WHILE @Id <= @Count 
BEGIN 
    DECLARE @TableName VARCHAR(255); 
    DECLARE @SchemaName VARCHAR(255); 
    DECLARE @ColumnName VARCHAR(255); 
    SELECT @TableName = TableName FROM @HitList WHERE Id = @Id; 
    SELECT @SchemaName = SchemaName FROM @HitList WHERE Id = @Id; 
    SELECT @ColumnName = ColumnName FROM @HitList WHERE Id = @Id; 
    SELECT @DynamicSQL = 'SELECT * FROM [' + @SchemaName + '].[' + @TableName + '] WHERE [' + @ColumnName + '] LIKE ''%co.uk%'''; 
    --PRINT @DynamicSQL; 
    EXECUTE (@DynamicSQL); 
    IF @@ROWCOUNT != 0 
    BEGIN 
     PRINT 'We have a hit in ' + @TableName + '.' + @ColumnName + '!!'; 
    END; 
    SELECT @Id = @Id + 1; 
END; 

基本上,它使任何VARCHAR列的列表(您可能需要更改为包括NVARCHARs如果你有Unicode文本列 - 只需将系统类型ID的测试从167更改为231),然后执行搜索。当你从management studio切换到消息窗格来查看命中并忽略结果时。

如果你的数据库是任何类型的大小,这将是缓慢的......但那是预期的?