我对SQL完全不熟悉并且没有经验,所以请耐心等待这个问题。
我需要知道是否可以在SQL数据库中搜索特定的单词,如果可以的话?
我们目前正在进行品牌重塑项目,我需要查看我们的CMS(内容管理系统)数据库,以获取对电子邮件地址的所有引用。我需要搜索的是:
.co.uk
下面是相关数据库的屏幕截图,其中包含所有包含的表格,我只是无法让我了解SQL,而且我对谷歌试图找到答案感到不满。
我需要搜索此数据库中的所有内容,但我不知道内容所包含的表格,视图,列名等等,因为它们全部分布在所有内容中。
我还需要搜索其他表格,但希望能够提供一些答案,我可以修改这些表格进行搜索。
答案 0 :(得分: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列(如果您有Unicode文本列,则可能需要将其更改为包含NVARCHAR - 只需将系统类型ID的测试从167更改为231)然后执行每个列的搜索。当您从管理工作室切换到消息窗格运行此命令以查看命中时,只需忽略结果。
如果您的数据库是任何类型的大小,那将会很慢......但是那是预期的吗?
答案 1 :(得分:1)
DB并不真正意味着这种模糊的搜索描述,你应该有一些定义或模型或要求规范来描述这样的值可能存在的位置。
但是,当然,您可以通过使用动态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中搜索所有用户创建的表及其模式,这些模式具有足够长度的(n)char /(n)varchar / xml列,并逐个搜索每个表,直到at找到至少一个匹配,然后它移动到列表中的下一个匹配。匹配被定义为任何字符串或XML转换为字符串,其中包含文本&#34; .co.uk&#34;和#34; @&#34; -sign在那里的某个地方。
它将在消息选项卡上显示脚本的进度(已找到多少可搜索的TABLE.COLUMN组合以及该列表中当前正在运行哪一个,以及当前时间戳低至秒)。准备好后,它将显示包含至少一个匹配项的所有表和列名称。
因此,从该列表中,您必须手动搜索表格和列,以确切地找到有多少匹配类型,以及您实际想要做什么。
编辑:我再次忽略了使用sysobjects的系统名称,但如果需要我会稍后修改。