Mệnh đề WHERE trên kiểu dữ liệu "Văn bản" của Máy chủ SQL


91

Trong đó [CastleType] được đặt làm kiểu dữ liệu "văn bản" trong SQL Server và truy vấn là:

SELECT *
FROM   [Village]
WHERE  [CastleType] = 'foo' 

Tôi gặp lỗi:

Các kiểu dữ liệu TEXTVARCHAR không tương thích trong toán tử bằng.

Tôi có thể không truy vấn kiểu dữ liệu này bằng mệnh đề WHERE được không?


9
Sử dụng VARCHAR(MAX)thay vì TEXT- kiểu dữ liệu đó không được dùng nữa
marc_s

Câu trả lời:


101

Bạn có thể sử dụng LIKEthay thế =. Không có bất kỳ ký tự đại diện nào, điều này sẽ có tác dụng tương tự.

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

SELECT *
FROM   @Village
WHERE  [CastleType] LIKE 'foo' 

textkhông được dùng nữa. Thay đổi thành varchar(max)sẽ dễ làm việc hơn.

Ngoài ra, dữ liệu có thể lớn đến mức nào? Nếu bạn đang thực hiện so sánh bình đẳng, lý tưởng là bạn sẽ muốn lập chỉ mục cột này. Điều này không thể thực hiện được nếu bạn khai báo cột là bất kỳ thứ gì rộng hơn 900 byte mặc dù bạn có thể thêm một cột được tính toán checksumhoặc hashcó thể được sử dụng để tăng tốc loại truy vấn này.


21

Hãy thử cái này

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR, CastleType) = 'foo'

Điều này cũng hữu ích để có thể xem trực tiếp dữ liệu trong trường TEXT nếu bạn đang sử dụng một số công cụ như Toad for Sql Server bảo vệ các trường kiểu BLOB sẽ được nhìn thấy ở lần thực thi đầu tiên. Bạn luôn có thể nhấp vào trường để yêu cầu Toad hiển thị trường, nhưng đó là một quy trình hai bước.
Roger

Lưu ý rằng điều này có thể sẽ làm cho truy vấn của bạn không thể phân loại được .
Heinzi

13

Bạn không thể so sánh textvới =toán tử, nhưng thay vào đó phải sử dụng một trong các hàm so sánh được liệt kê ở đây . Cũng cần lưu ý hộp cảnh báo lớn ở đầu trang, điều này rất quan trọng.


5

Nếu bạn không thể thay đổi kiểu dữ liệu trên bảng để sử dụng varchar (max), thì hãy thay đổi truy vấn của bạn thành sau:

SELECT *
FROM   [Village]
WHERE  CONVERT(VARCHAR(MAX), [CastleType]) = 'foo'

2

Đó không phải là những gì thông báo lỗi nói. Nó nói rằng bạn không thể sử dụng =toán tử. Hãy thử làm ví dụ LIKE 'foo'.


Col IN ('foo', 'bar')về cơ bản giống như Col = 'foo' or Col = 'bar'và sẽ có cùng một vấn đề.
Martin Smith

@Martin: Cảm ơn vì điểm nổi bật, tôi không biết về nó. Tôi sẽ sửa nó sau đó.
Will Marcouiller

0

Một tùy chọn khác sẽ là:

SELECT * FROM [Village] WHERE PATINDEX('foo', [CastleType]) <> 0

Tôi nghi ngờ rằng điều đó like 'foo'có thể đưa ra các ước tính về số lượng tốt hơn so với cách tiếp cận này nhưng không chắc chắn 100%.
Martin Smith

@Martin: Vì bạn không thể lập chỉ mục cột TEXT, tôi nghĩ rằng bạn sẽ phải quét toàn bộ bảng trong cả hai trường hợp.
Joe Stefanelli

Tôi đồng ý nhưng nó sẽ vẫn sử dụng số liệu thống kê trên cột để có được ước tính về các hàng sẽ được trả lại, điều này có thể ảnh hưởng đến quyết định tham gia, v.v.
Martin Smith

0

Điều này hoạt động trong MSSQL và MySQL:

SELECT *
FROM   Village
WHERE  CastleType LIKE '%foo%'; 

1
OP đang sử dụng MSSQL không phải MySQL.
Deckard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.