Sql 在所有列上应用like而不指定所有列名?
我发现自己处于这样一个位置:我正在处理一个陌生的数据库,每个表都有大量的列。我知道我在寻找什么样的数据,但我不知道它位于哪个列中,需要像使用一样使用,以便找到我需要的确切数据(并且必须对多组数据重复此任务) 有没有一种方法可以像在笛卡尔选择上一样应用 下面应该解释一下我想做得更好一点的事情(尽管这在语法上很荒谬): 编辑:Sql 在所有列上应用like而不指定所有列名?,sql,sql-server,sql-server-2008,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2008,Sql Server 2005,Tsql,我发现自己处于这样一个位置:我正在处理一个陌生的数据库,每个表都有大量的列。我知道我在寻找什么样的数据,但我不知道它位于哪个列中,需要像使用一样使用,以便找到我需要的确切数据(并且必须对多组数据重复此任务) 有没有一种方法可以像在笛卡尔选择上一样应用 下面应该解释一下我想做得更好一点的事情(尽管这在语法上很荒谬): 编辑: 请注意,我不打算在任何报告中使用cartesion select—这里的目的是帮助我确定需要放入查询中的相关列,并帮助我熟悉数据库。不,这在SQL中是不可能的。虽然我可以在您
请注意,我不打算在任何报告中使用cartesion select—这里的目的是帮助我确定需要放入查询中的相关列,并帮助我熟悉数据库。不,这在SQL中是不可能的。虽然我可以在您的场景中看到用例,但这也会被认为是不好的做法。最好是使用您最喜欢的语言编写脚本,方法是检索所有列名的列表,然后对每列执行一个单独的查询(每个列都有一个like),或者执行一个组合所有列名的大型查询:
select
*
from
a
where
a.column_1 like '%blah%' or
a.column_2 like '%blah%';
或者,单独查询:
select
*
from
a
where
a.column_1 like '%blah%'
select
*
from
a
where
a.column_2 like '%blah%'
通常情况下-如果不深入挖掘数据库元数据(),这是不可能的,但是如果您知道列的名称,您可以使用如下技巧:
select
YourTable.*
FROM YourTable
JOIN
(
select
id,
ISNULL(column1,'')+ISNULL(Column2,'')+...+ISNULL(ColumnN,'') concatenated
FROM YourTable
) T ON T.Id = YourTable.Id
where t.concatenated like '%x%'
或
如果搜索单词,请使用FTS功能,因为上面的查询是性能杀手也有类似的讨论 没有直接的方法,你必须这样做:
SELECT Name, Age, Description, Field1, Field2
FROM MyTable
WHERE Name LIKE 'Something%' OR Description LIKE 'Something%' OR Field1 LIKE 'Something%' OR Field2 LIKE 'Something%'
该论坛发布的一个解决方案是,它使用动态SQL:
CREATE PROCEDURE TABLEVIEWSEARCH @TABLENAME VARCHAR(60),@SEARCHSTRING VARCHAR(50)
-- EXEC TABLEVIEWSEARCH 'GMACT','demo'
-- EXEC TABLEVIEWSEARCH 'TABLEORVIEW','TEST'
AS
SET NOCOUNT ON
DECLARE @SQL VARCHAR(500),
@COLUMNNAME VARCHAR(60)
CREATE TABLE #RESULTS(TBLNAME VARCHAR(60),COLNAME VARCHAR(60),SQL VARCHAR(600))
SELECT
SYSOBJECTS.NAME AS TBLNAME,
SYSCOLUMNS.NAME AS COLNAME,
TYPE_NAME(SYSCOLUMNS.XTYPE) AS DATATYPE
INTO #TMPCOLLECTION
FROM SYSOBJECTS
INNER JOIN SYSCOLUMNS ON SYSOBJECTS.ID=SYSCOLUMNS.ID
WHERE SYSOBJECTS.NAME = @TABLENAME
AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR')
ORDER BY TBLNAME,COLNAME
DECLARE C1 CURSOR FOR
SELECT COLNAME FROM #TMPCOLLECTION ORDER BY COLNAME
OPEN C1
FETCH NEXT FROM C1 INTO @COLUMNNAME
WHILE @@FETCH_STATUS <> -1
BEGIN
--SET @SQL = 'SELECT ''' + @TABLENAME + ''' AS TABLENAME,''' + @COLUMNNAME + ''' AS COLUMNNAME,* FROM ' + @TABLENAME + ' WHERE ' + @COLUMNNAME + ' LIKE ''%' + @SEARCHSTRING + '%'''
SET @SQL = 'IF EXISTS(SELECT * FROM [' + @TABLENAME + '] WHERE [' + @COLUMNNAME + '] LIKE ''%' + @SEARCHSTRING + '%'') INSERT INTO #RESULTS(TBLNAME,COLNAME,SQL) VALUES(''' + @TABLENAME + ''',''' + @COLUMNNAME + ''','' SELECT * FROM [' + @TABLENAME + '] WHERE [' + @COLUMNNAME + '] LIKE ''''%' + @SEARCHSTRING + '%'''''') ;'
PRINT @SQL
EXEC (@SQL)
FETCH NEXT FROM C1 INTO @COLUMNNAME
END
CLOSE C1
DEALLOCATE C1
SELECT * FROM #RESULTS
GO
CREATE PROCEDURE TABLEVIEWSEARCH2 @TABLENAME VARCHAR(60),@SEARCHSTRING VARCHAR(50)
-- EXEC TABLEVIEWSEARCH2 'GMACT','SOURCE'
-- EXEC TABLEVIEWSEARCH2 'TABLEORVIEW','TEST'
AS
BEGIN
SET NOCOUNT ON
DECLARE @FINALSQL VARCHAR(MAX),
@COLUMNNAMES VARCHAR(MAX)
SET @FINALSQL = 'SELECT * FROM [' + @TABLENAME + '] WHERE 1 = 2 '
SELECT
@FINALSQL = @FINALSQL + ' OR [' + SYSCOLUMNS.NAME + '] LIKE ''%' + @SEARCHSTRING + '%'' '
FROM SYSCOLUMNS
WHERE OBJECT_NAME(id) = @TABLENAME
AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR')
ORDER BY COLID
PRINT @FINALSQL
EXEC(@FINALSQL)
END --PROC
我想我会提供更多的例子,因为上面的Emp表只有一个字段用于搜索数据 这是todo数据库中的任务表: 搜索短语
en
:(突出显示数据匹配的单元格)
EXEC TABLEVIEWSEARCH2'task','en'
您可以尝试类似的方法,但如果您的表太大,您可能会遇到一些问题,因为它将创建整个表的XML,然后查询XML以查找搜索字符串。输出是找到字符串的列名
;with C(TableXML) as
(
select *
from YourTable
for xml path('T'), type
)
select distinct T.X.value('local-name(.)', 'sysname') as ColumnName
from C
cross apply C.TableXML.nodes('/T/*') as T(X)
where T.X.value('.', 'varchar(max)') like '%x%'
谢谢南达:)
以下是我精简后的脚本:
use a_database
declare
@TableName as nvarchar(50) = 'a_table',
@FilterContition as nvarchar(50) = 'like ''%x%''',
@ColumnName as nvarchar(100),
@ColumnCursor as cursor,
@Sql as nvarchar(4000)
set @ColumnCursor = cursor for
select distinct c.name
from sys.objects as o
inner join sys.columns as c
on o.object_id = c.object_id
where o.name = @TableName
and type_name(c.user_type_id) in ('VARCHAR','NVARCHAR','CHAR','NCHAR')
open @ColumnCursor
fetch next from @ColumnCursor into @ColumnName
set @Sql = 'select * from ' + @TableName + ' where ' + @ColumnName + ' ' + @FilterContition
while @@fetch_status = 0
begin
fetch next from @ColumnCursor into @ColumnName
set @Sql = @Sql + ' and ' + @ColumnName + ' ' + @FilterContition
end
close @ColumnCursor
deallocate @ColumnCursor
exec(@Sql)
它使用:
-动态sql
-光标
-数据库元数据
Create PROCEDURE dbo.sp_FindStringInTable @stringToFind VARCHAR(100), @table sysname
AS
BEGIN TRY
DECLARE @sqlCommand varchar(max) = 'SELECT * FROM [' + @table + '] WHERE '
SELECT @sqlCommand = @sqlCommand + '[' + COLUMN_NAME + '] LIKE ''' + @stringToFind + ''' OR '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table
AND DATA_TYPE IN ('char','nchar','ntext','nvarchar','text','varchar')
SET @sqlCommand = left(@sqlCommand,len(@sqlCommand)-3)
EXEC (@sqlCommand)
PRINT @sqlCommand
END TRY
BEGIN CATCH
PRINT 'There was an error. Check to make sure object exists.'
PRINT error_message()
END CATCH
--那就用这个打电话
EXEC sp_FindStringInTable 'yoursearchitem', 'tablename'
一个简单的方法:
1.从INFORMATION\u SCHEMA.COLUMNS中选择COLUMN\u NAME
其中TABLE_NAME='your_TABLE'
Excel是你的朋友 性能在这里不是问题,因为我是dev数据库的唯一用户,这是一项一次性任务,感谢您的指导,如果是这样的话-然后是动态查询-您甚至不必知道列名,或者我的变量请让我了解一下您在这里做什么,但现在我知道了,我喜欢这个解决方案。谢谢!这是一个有趣的问题。我的背景是bash命令,所以我考虑通过(1)grep和(2)awk获取数据。通过这种方式,您可以grep很多(甚至太多),然后使用其他grep或awk语句进行过滤。我很惊讶SQL没有内置的“grep”功能。
Create PROCEDURE dbo.sp_FindStringInTable @stringToFind VARCHAR(100), @table sysname
AS
BEGIN TRY
DECLARE @sqlCommand varchar(max) = 'SELECT * FROM [' + @table + '] WHERE '
SELECT @sqlCommand = @sqlCommand + '[' + COLUMN_NAME + '] LIKE ''' + @stringToFind + ''' OR '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table
AND DATA_TYPE IN ('char','nchar','ntext','nvarchar','text','varchar')
SET @sqlCommand = left(@sqlCommand,len(@sqlCommand)-3)
EXEC (@sqlCommand)
PRINT @sqlCommand
END TRY
BEGIN CATCH
PRINT 'There was an error. Check to make sure object exists.'
PRINT error_message()
END CATCH
EXEC sp_FindStringInTable 'yoursearchitem', 'tablename'