2013-08-30 58 views
6

Tôi biết rằng tôi có thể tìm kiếm cụm từ trong một cột trong bảng bằng t-sql bằng cách sử dụng like %termToFind%. Và tôi biết tôi có thể nhận tất cả các cột trong một bảng với điều này:làm cách nào để chọn các bản ghi giống như một số chuỗi cho bất kỳ cột nào trong một bảng?

SELECT * 
FROM MyDataBaseName.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = N'MyTableName` 

Làm cách nào để tôi có thể thực hiện giống như bao gồm trên mỗi cột trong bảng? Tôi có một cái bàn rất lớn nên tôi không thể chỉ viết ra LIKE cho mỗi cột.

+3

Nếu bạn nghĩ rằng bạn có thể làm những việc như thế này rất nhiều trong tương lai, thì bạn nên xem xét cơ sở Tìm kiếm toàn văn bản của SQL Server. Cách tiếp cận XML của @ RomanPekar sẽ hoạt động, nhưng nó không thể thực sự sử dụng các chỉ mục, vì vậy sẽ không nhanh chóng. Đó là tốt nếu bạn chỉ làm điều này một lần trong một thời gian, nhưng nếu bạn cần điều này cho các truy vấn người dùng trực tuyến, máy chủ của bạn sẽ bị sa lầy xuống khá nhanh chóng. – RBarryYoung

+0

@RBarryBạn rất đúng –

Trả lời

10

Như thường lệ, tôi sẽ đề xuất xml cho điều này (tôi sẽ đề xuất JSON nếu SQL Server có hỗ trợ gốc cho nó :)). Bạn có thể cố gắng sử dụng truy vấn này, mặc dù nó có thể thực hiện không quá tốt trên số lượng lớn hàng:

;with cte as (
    select 
     *, 
     (select t.* for xml raw('data'), type) as data 
    from test as t 
) 
select * 
from cte 
where data.exist('data/@*[local-name() != "id" and contains(., sql:variable("@search"))]') = 1 

thấy sql fiddle demo ví dụ chi tiết hơn.

quan trọng lưu ý bởi Alexander Fedorenko trong ý kiến: nó nên được hiểu rằng contains chức năng là trường hợp nhạy cảm và sử dụng XQuery mặc định Unicode điểm mã collation cho chuỗi so sánh.

More cách tổng quát sẽ sử dụng giải pháp SQL động:

declare @search nvarchar(max) 
declare @stmt nvarchar(max) 

select @stmt = isnull(@stmt + ' or ', '') + quotename(name) + ' like @search' 
from sys.columns as c 
where c.[object_id] = object_id('dbo.test') 
-- 
-- also possible 
-- 
-- select @stmt = isnull(@stmt + ' or ', '') + quotename(column_name) + ' like @search' 
-- from INFORMATION_SCHEMA.COLUMNS 
-- where TABLE_NAME = 'test' 

select @stmt = 'select * from test where ' + @stmt 

exec sp_executesql 
    @stmt = @stmt, 
    @params = N'@search nvarchar(max)', 
    @search = @search 

sql fiddle demo

+1

+1 - câu trả lời thú vị. – Devart

+0

@Devart cảm ơn, thêm giải pháp SQL động –

+0

IMHO: 'sys.columns' không chứa các tham gia ẩn so với' INFORMATION_SCHEMA.COLUMNS': 'SELECT c.name FROM sys.columns c WHERE OBJECT_ID ('dbo.test') = c. [object_id] ' – Devart

1

Tôi muốn sử dụng SQL động ở đây.

Tín dụng đầy đủ - câu trả lời này ban đầu được đăng bởi người dùng khác và đã bị xóa. Tôi nghĩ đó là một câu trả lời hay nên tôi sẽ thêm lại nó.

DECLARE @sql NVARCHAR(MAX); 
DECLARE @table NVARCHAR(50); 
DECLARE @term NVARCHAR(50); 

SET @term = '%term to find%'; 
SET @table = 'TableName'; 
SET @sql = 'SELECT * FROM ' + @table + ' WHERE ' 

SELECT @sql = @sql + COALESCE('CAST('+ column_name 
    + ' as NVARCHAR(MAX)) like N''' + @term + ''' OR ', '') 
FROM INFORMATION_SCHEMA.COLUMNS WHERE [TABLE_NAME] = @table 

SET @sql = @sql + ' 1 = 0' 
SELECT @sql 
EXEC sp_executesql @sql 

Câu trả lời XML là sạch hơn (tôi thích SQL động chỉ khi cần thiết) nhưng lợi ích của việc này là nó sẽ sử dụng bất kỳ chỉ số mà bạn có trong bảng của bạn, và không có chi phí trong xây dựng XML CTE cho truy vấn.

+0

điều này có thể là chủ đề của tiêm sql - đó là lý do tại sao tôi đã sử dụng sp_executesql với các tham số –

0

Trong trường hợp ai đó đang tìm kiếm giải pháp PostgreSQL:

SELECT * FROM table_name WHERE position('your_value' IN (table_name.*)::text)>0 

sẽ chọn tất cả các hồ sơ mà có 'your_value' trong bất kỳ cột. Không thử với bất kỳ cơ sở dữ liệu nào khác.

Thật không may điều này hoạt động như kết hợp tất cả các cột vào chuỗi văn bản và sau đó tìm kiếm một giá trị trong chuỗi đó, vì vậy tôi không biết cách làm cho nó khớp với "toàn bộ ô". Nó sẽ luôn khớp nếu bất kỳ phần nào của bất kỳ ô nào khớp với 'your_value'.

Các vấn đề liên quan