web-dev-qa-db-ja.com

すべての列名を指定せずにすべての列に同様に適用しますか?

私は、各テーブルに膨大な数の列を持つ、なじみのないデータベースを使用している立場にいます。探しているデータはわかっていますが、どの列にあるかわかりません。likeを使用して、必要な正確なデータを見つける必要があります(このタスクを繰り返す必要があります)データの複数のセットの場合)。

デカルト選択のように適用する方法はありますか?

以下は私が少し良くしたいことを説明するはずです(それは構文的にばかげていますが)。

select 
    *
from    
    a_table
where   
    * like '%x%'

編集

レポートでCartesion Selectを使用するつもりはないことに注意してください。ここでの目的は、クエリに挿入する必要がある関連する列を特定し、データベースに慣れるのに役立つことです。

22
Michael A

一般に、それは合理的な方法では不可能です(DBメタデータを掘り下げることなく)。ただし、列の名前がわかっている場合は、次のようなトリックを使用できます。

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機能を使用します。上のクエリはパフォーマンスキラーであるためです。

18
Oleg Dok

同様の議論 ここ があります。

直接的な方法はなく、次の方法で行う必要があります。

SELECT Name, Age, Description, Field1, Field2
FROM MyTable
WHERE Name LIKE 'Something%' OR Description LIKE 'Something%' OR Field1 LIKE 'Something%' OR Field2 LIKE 'Something%'

そのフォーラムに投稿されたソリューションの1つはこれです。これは動的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テーブルには、データを検索するフィールドが1つしかないため、実際にこの例をもう少し提供すると思いました。

これは、todoデータベースのタスクテーブルです。 enter image description here

フレーズen:の検索(データが一致するハイライトされたセル)

EXEC TABLEVIEWSEARCH2 'task','en'

enter image description here

7
Animesh

いいえ、これはSQLでは不可能です。私はあなたのシナリオのユースケースを見ることができますが、それも悪い習慣と見なされます。あなたの最善の策は、すべての列名のリストを取得し、各列にLikeを含む個別のクエリを実行するか、それをすべて組み合わせた1つの大きなクエリを実行することによって、お気に入りの言語でスクリプトを作成することです。

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
Walter Heck

このようなものを試すことができますが、テーブルが本当に大きい場合、テーブル全体の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

3
Mikael Eriksson

ありがとうナンダ:)

ここに私のスリムなスクリプトがあります:

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-カーソル-データベースメタデータ

2
tristan3fish
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'
0
asalam345