Применить как и ко всем столбцам без указания всех имен столбцов?
Я нашел себя в положении, когда я работаю с незнакомой базой данных, которая имеет огромное количество столбцов для каждой таблицы. У меня есть представление о том, какие данные я ищу, но я не знаю, в каком столбце он находится, и нужно использовать like
, чтобы найти точные данные, которые мне нужны (и повторять эту задачу для нескольких наборов данных).
Есть ли способ применить как над декартовым выбором?
Следующее должно объяснить, что я хотел бы сделать немного лучше (хотя это синтаксически смешно):
select
*
from
a_table
where
* like '%x%'
изменить:
Обратите внимание, что я не собираюсь использовать выборка в любом из отчетов - здесь я хотел бы помочь мне определить соответствующие столбцы, которые мне нужно будет вводить в мои запросы, и помочь мне получить знакомство с базой данных.
Ответы
Ответ 1
В общем случае - это невозможно в разумных пределах (без копания в метаданных БД), но если вы знаете имена столбцов, вы можете использовать трюк, подобный этому:
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, потому что верхний запрос - это убийца производительности
Ответ 2
Существует аналогичное обсуждение здесь.
Нет прямого пути, и вы должны сделать это следующим образом:
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
Я тестировал это в таблице сотрудников, содержащей следующие данные:
![enter image description here]()
Запуск следующего утверждения
EXEC TABLEVIEWSEARCH2 'employee','2'
привело к:
2 1 eng2
4 2 dev2
7 3 sup2
9 4 qa2
Я думал, что я приведу еще один пример этого в действии, поскольку в приведенной выше таблице Emp есть только одно поле, где он искал данные.
Это таблица задач из базы данных todo:
![enter image description here]()
Поиск фразы en
: (выделенные ячейки, в которых сопоставляются данные)
EXEC TABLEVIEWSEARCH2 'task','en'
![enter image description here]()
Ответ 3
Нет, это невозможно в SQL. Это будет считаться плохой практикой, хотя я вижу пример использования в вашем сценарии. Лучше всего сделать это на script на своем любимом языке, получив список всех имен столбцов, а затем выполнив либо отдельный запрос с похожим для каждого столбца, либо один большой запрос, который объединяет все:
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%'
Ответ 4
Вы можете попробовать что-то подобное, но если ваша таблица действительно большая, у вас могут быть проблемы, потому что она создаст 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%'
http://data.stackexchange.com/stackoverflow/query/58934/new
Ответ 5
Спасибо Нанде:)
вот мой slimmed down script:
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
- курсор
- метаданные базы данных
Ответ 6
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'
Ответ 7
один простой способ:
1. выберите COLUMN_NAME из INFORMATION_SCHEMA.COLUMNS
где TABLE_NAME = 'your_table'
- Копировать Вставить результат в лист Excel Cell B1
- тип isnull (в ячейке A1
- type, '') + в ячейке C1
- type = A1 & B1 & C1 в ячейке D1
- Перетащите ячейки A1 и C1 и D1 вниз
-
Копировать столбцы D в SQL
-
Добавить select * from your_table где (в начале
- Удалить + в конце
- Добавить), как "% x%" в конце
- выполнить
Excel - ваш друг!