wake-up-neo.net

Wie über alle Spalten anwenden, ohne alle Spaltennamen anzugeben.

Ich befand mich in einer Position, in der ich eine unbekannte Datenbank mit einer großen Anzahl von Spalten zu jeder Tabelle arbeite. Ich habe eine Vorstellung davon, nach welchen Daten ich suche, aber ich weiß nicht, in welcher Spalte sie sich befindet, und muss like verwenden, um die genauen Daten zu finden, die ich benötige (und diese Aufgabe für mehrere Datensätze wiederholen muss ).

Gibt es eine Möglichkeit, sich wie über eine kartesische Auswahl zu bewerben?

Das Folgende sollte erklären, was ich etwas besser machen möchte (auch wenn es syntaktisch lächerlich ist):

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

edit

Beachten Sie, dass ich nicht beabsichtige, in einem Bericht eine Cartesion-Auswahl zu verwenden. Hiermit möchte ich die relevanten Spalten ermitteln, die ich in meine Abfragen einfügen müsste, und mir helfen, mit der Datenbank vertraut zu werden.

19
Michael A

Im Allgemeinen ist dies nicht sinnvoll möglich ( ohne in DB-Metadaten zu suchen ), aber wenn Sie die Namen von Spalten kennen, können Sie einen Trick wie folgt verwenden:

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%'

ODER

wenn Sie nach Wörtern suchen - verwenden Sie die FTS-Funktionen, da die obere Abfrage ein Leistungskiller ist

15
Oleg Dok

Es gibt eine ähnliche Diskussion hier

Es gibt keinen direkten Weg und Sie müssen es auf diese Weise tun:

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

Eine der Lösungen, die in diesem Forum veröffentlicht wurden, war folgende: Dies verwendet dynamisches 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

Ich habe dies an einer Mitarbeitertabelle getestet, die folgende Daten enthält:

enter image description here

Führen Sie die folgende Anweisung aus 

EXEC TABLEVIEWSEARCH2 'employee','2'

führte zu:

2   1   eng2
4   2   dev2
7   3   sup2
9   4   qa2

Ich dachte, ich würde in der Tat ein weiteres Beispiel dafür liefern, da die Emp-Tabelle oben nur ein Feld enthält, in dem die Daten durchsucht wurden.

Dies ist eine Aufgabentabelle aus einer ToDo-Datenbank: enter image description here

Suche nach der Phrase en: (markierte Zellen, bei denen die Daten übereinstimmen)

EXEC TABLEVIEWSEARCH2 'task','en'

enter image description here

7
Animesh

Nein, das ist mit SQL nicht möglich. Es wäre auch eine schlechte Praxis, obwohl ich den Anwendungsfall in Ihrem Szenario sehen kann. Am besten verwenden Sie ein Skript in Ihrer bevorzugten Sprache, indem Sie eine Liste aller Spaltennamen abrufen und dann entweder eine separate Abfrage mit einem "Like" für jede Spalte oder eine einzelne große Abfrage ausführen, die alle kombiniert:

select
    *
from
    a
where
    a.column_1 like '%blah%' or 
    a.column_2 like '%blah%';

oder separate Abfragen:

select
    *
from 
    a 
where 
    a.column_1 like '%blah%'

select
    *
from 
    a 
where 
    a.column_2 like '%blah%'
4
Walter Heck

Sie können so etwas versuchen, aber wenn Ihre Tabelle wirklich groß ist, haben Sie möglicherweise Probleme, da sie eine XML-Tabelle Ihrer gesamten Tabelle erstellen und dann die XML-Abfrage nach der Suchzeichenfolge abfragen. Die Ausgabe ist der Spaltenname, in dem die Zeichenfolge gefunden wird.

;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

Danke Nanda :)

hier ist mein abgespecktes Skript:

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)

es verwendet: - dynamisches SQL - einen Cursor - Datenbank-Metadaten

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 

- Dann rufen Sie das an

EXEC sp_FindStringInTable 'yoursearchitem', 'tablename'
0
asalam345