2012-01-11 20 views
17

Mi sono trovato in una posizione in cui sto lavorando a un database sconosciuto con un numero elevato di colonne per ogni tabella. Ho un'idea di quali dati sto cercando ma non so in quale colonna risiede e ho bisogno di usare like per individuare i dati esatti di cui ho bisogno (e devo ripetere questa attività per più insiemi di dati).Si applica come su tutte le colonne senza specificare tutti i nomi di colonna?

C'è un modo per applicare, come nel corso di un cartesiano selezionare?

Il seguente dovrebbe spiegare che cosa mi piacerebbe fare un po 'meglio (anche se è sintatticamente ridicolo):

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

modificare:

Si noti che non sto intenzione di utilizzare una selezione di cartesion in qualsiasi rapporto - i suoi scopi qui sarebbero aiutarmi a identificare le colonne rilevanti che avrei bisogno di inserire nelle mie domande e ad aiutarmi ad acquisire familiarità con il database.

+1

Questa è una domanda interessante. Il mio background è con i comandi bash, quindi penso di ottenere dati da (1) grep e quindi (2) awk. In questo modo, si grep molto (anche troppo), e quindi filtrare con ulteriori istruzioni grep o awk. Sono rimasto sorpreso dal fatto che SQL non avesse funzionalità integrate di "grep". – philshem

risposta

13

in generale - la sua non è possibile in modo ragionevole (senza scavare nel DB metadati), ma se si conoscono i nomi delle colonne, si possono utilizzare trucco come questo:

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

O

se si cerca parole - utilizzare le funzionalità di FTS, perché la query in alto è un killer prestazioni

+1

Le prestazioni non sono un problema qui perché sono l'unico utente su un database dev e questo è un compito a parte, apprezzare l'head-up anche se – Codingo

+0

Se è così - allora o query dinamiche - e non si deve nemmeno sapere la colonna nomi, o la mia variante –

+1

Mi ci è voluto un po 'per capire cosa stai facendo qui, ma ora che lo faccio amo questa soluzione. Apprezzato! – Codingo

4

No, questo non è possibile con SQL. Sarebbe considerato una cattiva pratica, anche se posso vedere il caso d'uso nel tuo scenario. La cosa migliore è per lo script nella vostra lingua preferita per il recupero di un elenco di tutti i nomi di colonna e quindi l'esecuzione una query separata con un simile per ogni colonna o di una singola query di grandi dimensioni che combina tutto:

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

o , query separate:

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

select 
    * 
from 
    a 
where 
    a.column_2 like '%blah%' 
7

C'è una discussione simile here.

Non v'è alcun modo diretto e bisogna farlo in questo modo:

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

Una delle soluzioni postato in quella sede è stato questo, Questo utilizza SQL dinamico:

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 

I hanno testato questo su una tabella dipendente contenente i seguenti dati:

enter image description here

eseguendo l'istruzione seguente

EXEC TABLEVIEWSEARCH2 'employee','2'

stata:

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

ho pensato di fornire qualche altro esempio di questo in azione, dal momento che la tabella EMP ha un solo campo al di sopra dove stava cercando i dati.

Si tratta di una tabella di attività da un database todo: enter image description here

Alla ricerca della frase en: (celle evidenziate in cui abbinati dati)

EXEC TABLEVIEWSEARCH2 'task','en'

enter image description here

3

Si può provare qualcosa del genere ma se il tuo tavolo è veramente grande potresti avere qualche problema perché creerà un XML del tuo ente re tabella e quindi interrogare l'XML per la stringa di ricerca. L'output è il nome della colonna (s) in cui viene trovata la stringa.

;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

2

Grazie Nanda :)

ecco il mio snellita 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) 

utilizza: - SQL dinamico - un cursore - metadati del database

0
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 

--quindi chiamata da questo

EXEC sp_FindStringInTable 'yoursearchitem', 'tablename' 
-1

un modo semplice: 1. Selezionare COLUMN_NAME da INFORMATION_SCHEMA.COLONNE dove TABLE_NAME = 'your_table'

  1. Copia Incolla il risultato in un foglio di Excel cella B1
  2. tipo IsNull (nella cella A1
  3. tipo, '') + a cellulare C1
  4. tipo = A1 & B1 & C1 nella cella D1
  5. Trascinare cella A1 e C1 e D1 giù
  6. Copia Incolla Colonna D in SQL

  7. 012.
  8. Aggiungi select * from your_table dove (all'inizio

  9. Eliminare il + alla fine
  10. Add) come '% x%' alla fine
  11. eseguire

Excel è la vostra amico!

Problemi correlati