web-dev-qa-db-fra.com

SQL Server SELECT où toute colonne contient «x»

En utilisant SQL Server 2008, disons que j'ai une table appelée testing avec 80 colonnes et que je veux trouver une valeur appelée foo.

Je peux faire:

SELECT * 
FROM testing 
WHERE COLNAME = 'foo'

Est-il possible que je puisse interroger les 80 colonnes et retourner tous les résultats où foo est contenu dans l'une des 80 colonnes?

Merci d'avance.

20
nsilva

Première méthode (testée) Commencez par obtenir la liste des colonnes dans une variable de chaîne séparée par des virgules, puis vous pouvez rechercher 'foo' en utilisant cette variable en utilisant IN

Vérifiez la procédure stockée ci-dessous qui obtient d'abord les colonnes, puis recherche la chaîne:

DECLARE @TABLE_NAME VARCHAR(128)
DECLARE @SCHEMA_NAME VARCHAR(128)

-----------------------------------------------------------------------

-- Set up the name of the table here :
SET @TABLE_NAME = 'testing'
-- Set up the name of the schema here, or just leave set to 'dbo' :
SET @SCHEMA_NAME = 'dbo'

-----------------------------------------------------------------------

DECLARE @vvc_ColumnName VARCHAR(128)
DECLARE @vvc_ColumnList VARCHAR(MAX)

IF @SCHEMA_NAME =''
  BEGIN
  PRINT 'Error : No schema defined!'
  RETURN
  END

IF NOT EXISTS (SELECT * FROM sys.tables T JOIN sys.schemas S
      ON T.schema_id=S.schema_id
      WHERE T.Name=@TABLE_NAME AND S.name=@SCHEMA_NAME)
  BEGIN
  PRINT 'Error : The table '''+@TABLE_NAME+''' in schema '''+
      @SCHEMA_NAME+''' does not exist in this database!' 
  RETURN
 END

DECLARE TableCursor CURSOR FAST_FORWARD FOR
SELECT   CASE WHEN PATINDEX('% %',C.name) > 0 
     THEN '['+ C.name +']' 
     ELSE C.name 
     END
FROM     sys.columns C
JOIN     sys.tables T
ON       C.object_id  = T.object_id
JOIN     sys.schemas S
ON       S.schema_id  = T.schema_id
WHERE    T.name    = @TABLE_NAME
AND      S.name    = @SCHEMA_NAME
ORDER BY column_id


SET @vvc_ColumnList=''

OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @vvc_ColumnName

WHILE @@FETCH_STATUS=0
  BEGIN
   SET @vvc_ColumnList = @vvc_ColumnList + @vvc_ColumnName

    -- get the details of the next column
   FETCH NEXT FROM TableCursor INTO @vvc_ColumnName

  -- add a comma if we are not at the end of the row
   IF @@FETCH_STATUS=0
    SET @vvc_ColumnList = @vvc_ColumnList + ','
   END

 CLOSE TableCursor
 DEALLOCATE TableCursor

-- Now search for `foo`


SELECT *
FROM testing 
WHERE 'foo' in (@vvc_ColumnList );

2ème méthode Dans le serveur SQL, vous pouvez obtenir l'ID d'objet de la table, puis en utilisant cet ID d'objet, vous pouvez récupérer les colonnes. Dans ce cas, ce sera comme ci-dessous:

Étape 1: Obtenez d'abord l'ID d'objet de la table

select * from sys.tables order by name    

Étape 2: Maintenant, récupérez les colonnes de votre table et recherchez-y:

 select * from testing where 'foo' in (select name from sys.columns  where  object_id =1977058079)

Remarque: object_id est ce que vous obtenez à la première étape pour votre table pertinente

7
ubaid ashraf

Vous pouvez utiliser in:

SELECT *
FROM testing 
WHERE 'foo' in (col1, col2, col3, . . . );
25
Gordon Linoff

Vous pouvez utiliser dans et vous pouvez obtenir les noms de colonne dynamiquement et les passer à la clause IN en créant une chaîne sql et en l'exécutant à l'aide de execute sp_executesql.

declare @sql nvarchar(2100)
declare @cols nvarchar(2000)
declare @toSearch nvarchar(200)
declare @tableName nvarchar(200)
set @tableName = 'tbltemp'
set @toSearch = '5' 
set @cols =(
 SELECT LEFT(column_name, LEN(column_name) - 1)
FROM (
    SELECT column_name + ', '
    FROM INFORMATION_SCHEMA.COLUMNS where table_name = @tableName
    FOR XML PATH ('')
  ) c (column_name )
)
set @sql = 'select * from tbltemp where '''+ @toSearch + '''  in (' + @cols + ')';  
execute sp_executesql @sql
0
Adil

J'ai pris l'idée de la réponse d'Ubaid Ashraf, mais je l'ai fait fonctionner. Modifiez simplement MyTableName ici:

SELECT STUFF((
    SELECT ', ' + c.name 
    FROM sys.columns  c
    JOIN sys.types AS t ON c.user_type_id=t.user_type_id
    WHERE t.name != 'int'  AND t.name != 'bit' AND t.name !='date' AND t.name !='datetime'
        AND object_id =(SELECT object_id FROM sys.tables WHERE name='MyTableName')
    FOR XML PATH('')),1,2,'')

Vous pouvez l'ajuster à vos besoins et ajouter ou supprimer des conditions dans la colonne where (la partie 't.name! =' Int 'AND t.name! =' Bit 'etc.), par ex. ajoutez 't.name! =' uniqueidentifier '' pour éviter d'obtenir Conversion failed when converting the varchar value 'myvalue' to data type int type d'erreurs ..

Puis copier coller le résultat dans cette requête (sinon cela n'a pas fonctionné):

SELECT * from MyTableName where 'foo' in (COPY PASTE PREVIOUS QUERY RESULT INTO HERE)
0
BornToCode

Je pense que c'est l'une des meilleures façons de le faire

SELECT * FROM sys.columns  a
inner join 
(
SELECT object_id
FROM sys.tables 
where 
type='U'--user table
and name like 'testing' 
) b on a.object_id=b.object_id
WHERE a.name like '%foo%'
0
yaritaft