是否有可能找到包含字符串的行?假设我不知道哪些列包含字符串
Is it possible that I could find a row contains a string? Assume that I do not know which columns contain a string
我知道有几种方法可以找到哪一行的列包含字符串,例如使用 [列名] 正则表达式 ' ' 或 [列名] 如 ' '
虽然目前我需要一些帮助,但我有一个包含多个列的 table,所有列都是 varchar 或 text,但我不确定哪一列包含特定字符串。只是说我想从 table 中搜索“xxx”。几个不同的列可能包含或不包含此字符串。有没有办法找到包含此字符串的列?
我有一个想法,解决方案可能是
select * from [table name] where [column1] regexp 'xxx' or
[column2] regexp 'xxx' or ...... [column39] regexp 'xxx' or .....
[colum60] regexp 'xxx' or ... or [column 80] regexp 'xxx';
我不想要这样的查询。还有其他有效的方法吗?
举一个更好的例子,假设我们正在搜索属于博客的table。
我们有标题,URL,内容,关键词,标签,评论等等。现在我们就说,如果任何博客文章与"database-normalization"相关,这个词可能会出现在标题,URL或内容或任何地方,我不想像[=一样一一写12=]
where title regexp 'database-normalization' or content regexp 'database-normalization' or url regexp 'database-normalization'......
当有数百列时,我需要写一百,或者在这种情况下有没有有效的方法来代替写百或语句?比如使用 if-else 或 collections 或其他一些来构建查询。
您可以通过多种方式进行分析。如果从SQL中的A开始,可以使用"LIKE A%%","REGEX" LibrarY进行多次检查。
如果你提前知道这些专栏,你提出的可能是最有效的方法(如果有点冗长的话)。
否则,您可以从 INFORMATION_SCHEMA.COLUMNS 中获取列名称并基于该名称构建动态 SQL。
一种方法是使用CASE
检查mysql和return列中LOCATE
的子字符串是否存在,但你必须检查每一列table 如下:
CREATE TABLE test(col1 VARCHAR(1000), col2 VARCHAR(1000), col3 VARCHAR(1000))
INSERT INTO test VALUES
('while currently what I need some help is I have a table with 10 columns',
'contains a certain string. Just say that I want to search a table',
'contains a certain string demo.webstater.com')
SELECT (CASE WHEN LOCATE('demo.webstater.com', col1, 1) > 0 THEN 'col1'
WHEN LOCATE('demo.webstater.com', col2, 1) > 0 THEN 'col2'
WHEN LOCATE('demo.webstater.com', col3, 1) > 0 THEN 'col3'
END) whichColumn
FROM test
输出:
whichColumn
col3
他的问题不是用like子句查询特定的列。他一直要求动态地跨列应用相同的模式。
示例: Table 有 3 列 - 名字、姓氏、地址和模式匹配是 "starts with A" 那么结果查询应该是:
Select * 来自客户,其中名字如“A%”或姓氏如“A%”或地址如 'A%'
如果您想在业务层构建查询,这可以通过反射和 EF 轻松完成。
如果你有动力在数据库中做,那么你可以通过动态构建查询然后通过 sp_executesql 执行来实现。
如果你想要一个纯动态的方式,你可以试试这个。我已经在 sql-server
上尝试了很长时间,希望它能对您有所帮助。
#TMP_TABLE -- a temporary table
- PK, IDENTITY
- TABLE_NAME
- COLUMN_NAME
- IS_EXIST
INSERT INTO #TMP_TABLE (TABLE_NAME,COLUMN_NAME)
SELECT C.TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.TABLE_NAME = <your-table> AND C.DATA_TYPE = 'varchar'; -- you can modify it to handle multiple table at once.
-- boundaries
SET @MINID = (SELECT ISNULL(MIN(<PK>),0) FROM #TMP_TABLE );
SET @MAXID = (SELECT ISNULL(MAX(<PK>),0) FROM #TMP_TABLE );
WHILE ((@MINID<=@MAXID) AND (@MINID<>0))
BEGIN
SELECT @TABLE_NAME = TABLE_NAME,@COLUMN_NAME = COLUMN_NAME
FROM #TMP_TABLE
WHERE <PK> = @MINID;
SET @sqlString = ' UPDATE #TMP_TABLE
SET IS_EXIST = 1
WHERE EXIST (SELECT 1 FROM '+ @TABLE_NAME+' WHERE '+ @COLUMN_NAME +' = ''demo.webstater.com'') AND <PK> = '+ @MINID;
EXEC(@sql) ;
SET @MINID = (SELECT MIN(<PK>) FROM #TMP_TABLE WHERE <PK> > @MINID );
END
SELECT * FROM #TMP_TABLE WHERE IS_EXIST = 1 ; -- will give you matched results.
试试这个(只需传递表名和要查找的字符串)-:
create proc usp_findString
@tablename varchar(500),
@string varchar(max)
as
Begin
Declare @sql2 varchar(max),@sql nvarchar(max)
SELECT @sql2=
STUFF((SELECT ', case when '+QUOTENAME(NAME)+'='''+@string+''' then 1 else 0 end as '+NAME
FROM (select a.name from sys.columns a join sys.tables b on a.[object_id]=b.[object_id] where b.name=@tablename) T1
--WHERE T1.ID=T2.ID
FOR XML PATH('')),1,1,'')
--print @string
set @sql='select '+@sql2+' from '+@tablename
print @sql
EXEC sp_executesql @sql
End
SQL 服务器 2014
我知道有几种方法可以找到哪一行的列包含字符串,例如使用 [列名] 正则表达式 ' ' 或 [列名] 如 ' '
虽然目前我需要一些帮助,但我有一个包含多个列的 table,所有列都是 varchar 或 text,但我不确定哪一列包含特定字符串。只是说我想从 table 中搜索“xxx”。几个不同的列可能包含或不包含此字符串。有没有办法找到包含此字符串的列?
我有一个想法,解决方案可能是
select * from [table name] where [column1] regexp 'xxx' or
[column2] regexp 'xxx' or ...... [column39] regexp 'xxx' or .....
[colum60] regexp 'xxx' or ... or [column 80] regexp 'xxx';
我不想要这样的查询。还有其他有效的方法吗?
举一个更好的例子,假设我们正在搜索属于博客的table。
我们有标题,URL,内容,关键词,标签,评论等等。现在我们就说,如果任何博客文章与"database-normalization"相关,这个词可能会出现在标题,URL或内容或任何地方,我不想像[=一样一一写12=]
where title regexp 'database-normalization' or content regexp 'database-normalization' or url regexp 'database-normalization'......
当有数百列时,我需要写一百,或者在这种情况下有没有有效的方法来代替写百或语句?比如使用 if-else 或 collections 或其他一些来构建查询。
您可以通过多种方式进行分析。如果从SQL中的A开始,可以使用"LIKE A%%","REGEX" LibrarY进行多次检查。
如果你提前知道这些专栏,你提出的可能是最有效的方法(如果有点冗长的话)。
否则,您可以从 INFORMATION_SCHEMA.COLUMNS 中获取列名称并基于该名称构建动态 SQL。
一种方法是使用CASE
检查mysql和return列中LOCATE
的子字符串是否存在,但你必须检查每一列table 如下:
CREATE TABLE test(col1 VARCHAR(1000), col2 VARCHAR(1000), col3 VARCHAR(1000))
INSERT INTO test VALUES
('while currently what I need some help is I have a table with 10 columns',
'contains a certain string. Just say that I want to search a table',
'contains a certain string demo.webstater.com')
SELECT (CASE WHEN LOCATE('demo.webstater.com', col1, 1) > 0 THEN 'col1'
WHEN LOCATE('demo.webstater.com', col2, 1) > 0 THEN 'col2'
WHEN LOCATE('demo.webstater.com', col3, 1) > 0 THEN 'col3'
END) whichColumn
FROM test
输出:
whichColumn
col3
他的问题不是用like子句查询特定的列。他一直要求动态地跨列应用相同的模式。
示例: Table 有 3 列 - 名字、姓氏、地址和模式匹配是 "starts with A" 那么结果查询应该是: Select * 来自客户,其中名字如“A%”或姓氏如“A%”或地址如 'A%'
如果您想在业务层构建查询,这可以通过反射和 EF 轻松完成。
如果你有动力在数据库中做,那么你可以通过动态构建查询然后通过 sp_executesql 执行来实现。
如果你想要一个纯动态的方式,你可以试试这个。我已经在 sql-server
上尝试了很长时间,希望它能对您有所帮助。
#TMP_TABLE -- a temporary table
- PK, IDENTITY
- TABLE_NAME
- COLUMN_NAME
- IS_EXIST
INSERT INTO #TMP_TABLE (TABLE_NAME,COLUMN_NAME)
SELECT C.TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.TABLE_NAME = <your-table> AND C.DATA_TYPE = 'varchar'; -- you can modify it to handle multiple table at once.
-- boundaries
SET @MINID = (SELECT ISNULL(MIN(<PK>),0) FROM #TMP_TABLE );
SET @MAXID = (SELECT ISNULL(MAX(<PK>),0) FROM #TMP_TABLE );
WHILE ((@MINID<=@MAXID) AND (@MINID<>0))
BEGIN
SELECT @TABLE_NAME = TABLE_NAME,@COLUMN_NAME = COLUMN_NAME
FROM #TMP_TABLE
WHERE <PK> = @MINID;
SET @sqlString = ' UPDATE #TMP_TABLE
SET IS_EXIST = 1
WHERE EXIST (SELECT 1 FROM '+ @TABLE_NAME+' WHERE '+ @COLUMN_NAME +' = ''demo.webstater.com'') AND <PK> = '+ @MINID;
EXEC(@sql) ;
SET @MINID = (SELECT MIN(<PK>) FROM #TMP_TABLE WHERE <PK> > @MINID );
END
SELECT * FROM #TMP_TABLE WHERE IS_EXIST = 1 ; -- will give you matched results.
试试这个(只需传递表名和要查找的字符串)-:
create proc usp_findString
@tablename varchar(500),
@string varchar(max)
as
Begin
Declare @sql2 varchar(max),@sql nvarchar(max)
SELECT @sql2=
STUFF((SELECT ', case when '+QUOTENAME(NAME)+'='''+@string+''' then 1 else 0 end as '+NAME
FROM (select a.name from sys.columns a join sys.tables b on a.[object_id]=b.[object_id] where b.name=@tablename) T1
--WHERE T1.ID=T2.ID
FOR XML PATH('')),1,1,'')
--print @string
set @sql='select '+@sql2+' from '+@tablename
print @sql
EXEC sp_executesql @sql
End
SQL 服务器 2014