Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL数据库中搜索特定单词_Sql_Sql Server_Tsql - Fatal编程技术网

在SQL数据库中搜索特定单词

在SQL数据库中搜索特定单词,sql,sql-server,tsql,Sql,Sql Server,Tsql,我是SQL的新手,没有SQL方面的经验,所以请接受我的提问 我需要知道是否可以在SQL数据库中搜索特定单词,如果可以,如何搜索 我们目前正在经历一个品牌重塑项目,我需要在我们的CMS内容管理系统数据库中查找所有电子邮件地址的参考。我只需要搜索以下内容: .co.uk 下面是一个有问题的数据库的截图,其中包含了所有的表,我只是不能理解SQL,我对Google试图找到答案一点也不高兴 我需要搜索这个数据库中的所有内容,但我不知道内容所在的表、视图、列名等,因为它们都分布在这些表、视图、列名中 我还需

我是SQL的新手,没有SQL方面的经验,所以请接受我的提问

我需要知道是否可以在SQL数据库中搜索特定单词,如果可以,如何搜索

我们目前正在经历一个品牌重塑项目,我需要在我们的CMS内容管理系统数据库中查找所有电子邮件地址的参考。我只需要搜索以下内容:

.co.uk

下面是一个有问题的数据库的截图,其中包含了所有的表,我只是不能理解SQL,我对Google试图找到答案一点也不高兴

我需要搜索这个数据库中的所有内容,但我不知道内容所在的表、视图、列名等,因为它们都分布在这些表、视图、列名中


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

我创建了一个似乎对我有用的快速查询:

--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列,如果您有Unicode文本列,则可能需要将其包括NVARCHAR—只需将系统类型id的测试从167更改为231,然后对每个列执行搜索。当您从ManagementStudio运行此命令时,请切换到消息窗格以查看点击,而忽略结果


如果您的数据库有任何大小,它将很慢。。。但是这是可以预料到的吗?

数据库并不是真正用于这种模糊的搜索描述,您应该有一些定义、模型或需求规范来描述这样的值可能存在的地方

但当然,您可以选择一种非常慢的方法,通过使用动态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
它会在数据库中搜索所有用户创建的表及其模式,这些表具有足够长度的nchar/nvarchar/xml列,然后逐个搜索每个表,直到找到至少一个匹配项,然后移动到列表中的下一个。匹配定义为任何字符串或XML转换为字符串,其中包含text.co.uk和@符号

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

因此,从该列表中,您必须手动搜索表和列,以准确地找到有多少个匹配项以及哪些类型的匹配项,以及您实际想要做什么


编辑:我再次忽略了对sysobjects使用sysnames,但如果需要,我将稍后进行修改。

您可以尝试SQL Search,这是Redgate提供的一个免费工具:@NickyvV我已经下载了它,但它说我搜索的每个词都没有匹配项,即使是“and”这个词