2015-02-25 15 views
12

Sử dụng SQL Server 2008, giả sử tôi có một bảng có tên là testing với 80 cột và tôi muốn tìm giá trị được gọi là foo.CHỌN SQL Server nơi bất kỳ cột nào chứa 'x'

tôi có thể làm:

SELECT * 
FROM testing 
WHERE COLNAME = 'foo' 

Có thể tôi có thể truy vấn tất cả 80 cột và trả lại tất cả các kết quả nơi foo được chứa trong bất kỳ của 80 cột?

Xin cảm ơn trước.

+0

Có thể. Bạn có thể thêm các cột allo bằng 'hoặc' trong câu lệnh where của bạn. 'SELECT * FROM testing nơi COLNAME = 'foo' hoặc COLNAME2 = 'foo' hoặc ....' – Jens

+0

nó có thể hữu ích http://vyaskn.tripod.com/search_all_columns_in_all_tables.htm – Sachin

Trả lời

5

Phương pháp đầu tiên (Tested) Đầu tiên get danh sách các cột trong biến chuỗi phân cách bằng dấu phẩy và sau đó bạn có thể tìm kiếm 'foo' sử dụng biến bằng cách sử dụng IN

Kiểm tra thủ tục lưu trữ dưới đây mà đầu tiên được cột và sau đó tìm kiếm chuỗi:

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 [email protected]_NAME AND [email protected]_NAME) 
    BEGIN 
    PRINT 'Error : The table '''[email protected]_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); 

Phương pháp thứ hai Trong máy chủ sql, bạn có thể lấy id đối tượng của bảng, sau đó sử dụng id đối tượng đó bạn có thể tìm nạp cột. Trong trường hợp đó nó sẽ được như sau:

Bước 1: Đầu tiên get Object Id của bảng

select * from sys.tables order by name  

Bước 2: Bây giờ có được cột của bảng của bạn và tìm kiếm trong đó:

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

Lưu ý: object_id là những gì bạn nhận được trong bước đầu tiên cho bạn bảng có liên quan

+0

Tôi đã thử nghiệm nó và nó hoạt động, chỉ cần cho nó chạy @nsilva –

+2

Xin chào, tôi vừa thử, tôi đã thực hiện thử nghiệm SELECT * FROM để tìm một giá trị mà tôi muốn quay lại kiểm tra, nhưng chạy tập lệnh vừa trở về không có gì. Tôi đã thay đổi tên bảng, và SELECT ở phía dưới để phù hợp với cơ sở dữ liệu tôi đang kiểm tra, không có gì khác tôi cần phải thay đổi phải không? – nsilva

+0

bạn chỉ cần ghi nhớ rằng tên schemna trong trường hợp này dbo và tên bảng được đưa ra một cách chính xác. Tôi đang đưa ra bảng và schemna lúc bắt đầu thủ tục. Hoặc bạn có thể thử phương pháp thứ 2 –

20

Bạn có thể sử dụng in:

SELECT * 
FROM testing 
WHERE 'foo' in (col1, col2, col3, . . .); 
+0

Cảm ơn, có thể không định nghĩa mọi tên cột dọc? @Gordon Linoff – nsilva

+1

@nsilva. . . Có, nhưng bạn sẽ không muốn làm điều đó. Một phương pháp tôi có thể nghĩ đến sẽ liên quan đến một thủ thuật XML khá phức tạp.Bạn có thể lấy danh sách các cột từ 'information_schema.columns' nếu bạn không thích gõ chúng. –

+0

Có @Gordon! 'CHỌN * TỪ INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =' testing ';' - sẽ cung cấp cho bạn tất cả các giá trị bảng cùng nhau. –

0

Y Bạn có thể sử dụng và bạn có thể lấy tên cột tự động và chuyển chúng đến mệnh đề IN bằng cách tạo chuỗi sql và thực thi nó bằng cách sử dụng 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

Điều này không hoạt động nếu bạn có các cột int trong bảng của mình. – BornToCode

0

Tôi lấy ý tưởng từ câu trả lời của Ashraf, nhưng đã làm cho nó thực sự hiệu quả. Chỉ cần thay đổi MyTableName đây:

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,'') 

(Bạn có thể tinh chỉnh nó cho nhu cầu của bạn để tránh bị Conversion failed when converting the varchar value 'myvalue' to data type int lỗi, vv)

Sau đó copy dán kết quả vào truy vấn này (nếu không nó đã không làm việc) :

SELECT * from MyTableName where 'foo' in (COPY PASTE PREVIOUS QUERY RESULT INTO HERE) 
Các vấn đề liên quan