7

Tôi đang tìm mẫu để thực hiện tìm kiếm động trên nhiều bảng.Cần mẫu để tìm kiếm động của nhiều bảng sql

Tôi không có quyền kiểm soát cấu trúc bảng cơ sở dữ liệu cũ (và được thiết kế kém).

Xem xét kịch bản tương tự như tìm kiếm tiếp tục mà người dùng có thể muốn thực hiện tìm kiếm đối với bất kỳ dữ liệu nào trong bản lý lịch và lấy lại danh sách hồ sơ phù hợp với tiêu chí tìm kiếm của họ. Bất kỳ trường nào cũng có thể được tìm kiếm bất kỳ lúc nào và kết hợp với một hoặc nhiều trường khác.

Truy vấn sql thực tế được tạo tự động tùy thuộc vào trường nào được tìm kiếm. Hầu hết các giải pháp tôi đã tìm thấy liên quan đến phức tạp nếu khối, nhưng tôi không thể không nghĩ rằng phải có một giải pháp thanh lịch hơn vì đây phải là một vấn đề giải quyết ngay bây giờ.


Vâng, vì vậy tôi đã bắt đầu xuống đường dẫn xây dựng động sql trong mã. Dường như có thiện cảm. Nếu tôi thực sự cố gắng hỗ trợ khả năng được yêu cầu để truy vấn bất kỳ sự kết hợp nào của bất kỳ trường nào trong bất kỳ bảng nào, đây sẽ là một tập hợp MASSIVE nếu các câu lệnh if. rùng


Tôi tin rằng tôi đọc mà liên hiệp chỉ hoạt động nếu dữ liệu của bạn không chứa NULLs. Đúng không? Nếu vậy, không đi, kể từ khi tôi có giá trị NULL trên tất cả các nơi.

Trả lời

5

Theo như tôi hiểu (và tôi cũng là một người đã viết chống lại một cơ sở dữ liệu di sản khủng khiếp), không có điều nào như mệnh đề WHERE động. Nó chưa được giải quyết.

Cá nhân, tôi muốn tạo các tìm kiếm động trong mã. Làm cho thử nghiệm thuận tiện. Lưu ý, khi bạn tạo các truy vấn sql trong mã, không liên kết trong đầu vào của người dùng. Sử dụng @variables của bạn!

Cách thay thế duy nhất là sử dụng toán tử COALESCE. Giả sử bạn có bảng sau:

Users 
----------- 
Name nvarchar(20) 
Nickname nvarchar(10) 

và bạn muốn tìm kiếm tùy chọn cho tên hoặc biệt hiệu. Truy vấn sau sẽ làm điều này:

SELECT Name, Nickname 
FROM Users 
WHERE 
    Name = COALESCE(@name, Name) AND 
    Nickname = COALESCE(@nick, Nickname) 

Nếu bạn không muốn tìm kiếm thứ gì đó, chỉ cần bỏ qua một giá trị rỗng. Ví dụ, đi qua trong "brian" cho @name và null cho kết quả @nick trong truy vấn sau đây đang được đánh giá:

SELECT Name, Nickname 
FROM Users 
WHERE 
    Name = 'brian' AND 
    Nickname = Nickname 

Nhà điều hành liên hiệp biến null vào một đánh giá bản sắc, mà luôn luôn là đúng và không ảnh hưởng đến mệnh đề where.

1

Tìm kiếm và chuẩn hóa có thể có tỷ lệ chênh lệch với nhau. Vì vậy, có lẽ điều đầu tiên sẽ là để có được một số loại "xem" cho thấy tất cả các lĩnh vực có thể được tìm kiếm như là một hàng duy nhất với một khóa duy nhất giúp bạn tiếp tục. sau đó bạn có thể ném một cái gì đó như Lucene trước đó để cung cấp cho bạn một chỉ mục văn bản đầy đủ của những hàng đó, cách hoạt động là, bạn yêu cầu nó cho "x" trong khung nhìn này và nó trả về cho bạn khóa. Đó là một giải pháp tuyệt vời và được đề xuất bởi chính joel trên podcast trong vòng 2 tháng đầu tiên IIRC.

1

Những gì bạn cần là một cái gì đó như SphinxSearch (cho MySQL) hoặc Apache Lucene.

Như bạn nói trong ví dụ của bạn cho phép hình dung một Resume sẽ gồm nhiều lĩnh vực:

  • List item
  • Tên,
  • Adreess,
  • Giáo dục (điều này có thể là một bảng trên của riêng nó) hoặc
  • Trải nghiệm làm việc (điều này có thể phát triển thành bảng riêng của nó, mỗi hàng đại diện cho một công việc trước đó)

Vì vậy, tìm kiếm một từ trong tất cả các trường đó với WHERE nhanh chóng trở thành một truy vấn rất dài với một số JOINS.

Thay vào đó bạn có thể thay đổi khung tham chiếu của mình và nghĩ về toàn bộ lý lịch là tài liệu đơn lẻ và bạn chỉ muốn tìm kiếm tài liệu đã nói.

Đây là nơi các công cụ như Tìm kiếm nhân sư làm. Họ tạo ra một chỉ mục TEXT đầy đủ của 'tài liệu' của bạn và sau đó bạn có thể truy vấn nhân sư và nó sẽ cung cấp cho bạn trở lại nơi trong cơ sở dữ liệu mà bản ghi đã được tìm thấy.

Kết quả tìm kiếm thực sự tốt.

Đừng lo lắng về công cụ này không phải là một phần của RDBMS của bạn, nó sẽ giúp bạn tiết kiệm rất nhiều đau đầu khi sử dụng mô hình thích hợp "Tài liệu" so với "TABLES" không chính xác cho ứng dụng này.