คำสั่ง WHERE บนชนิดข้อมูล "ข้อความ" ของเซิร์ฟเวอร์ SQL


91

โดยที่ [CastleType] ถูกตั้งค่าเป็นชนิดข้อมูล "text" ใน SQL Server และแบบสอบถามคือ:

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

ฉันได้รับข้อผิดพลาด:

ชนิดข้อมูลTEXTและVARCHARเข้ากันไม่ได้ในตัวดำเนินการเท่ากับ

ฉันไม่สามารถสืบค้นข้อมูลประเภทนี้ด้วย WHERE clause ได้หรือไม่?


9
ใช้VARCHAR(MAX)แทนTEXT- ประเภทข้อมูลนั้นเลิกใช้งาน
marc_s

คำตอบ:


101

คุณสามารถใช้LIKEแทน=. หากไม่มีสัญลักษณ์แทนใด ๆ ก็จะมีผลเช่นเดียวกัน

DECLARE @Village TABLE
        (CastleType TEXT)

INSERT INTO @Village
VALUES
  (
    'foo'
  )

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

textเลิกใช้แล้ว การเปลี่ยนvarchar(max)เป็นจะทำงานได้ง่ายขึ้น

ข้อมูลมีแนวโน้มที่จะมีขนาดใหญ่เพียงใด? หากคุณกำลังจะทำการเปรียบเทียบความเท่าเทียมกันคุณควรจัดทำดัชนีคอลัมน์นี้ สิ่งนี้เป็นไปไม่ได้หากคุณประกาศคอลัมน์เป็นอะไรก็ได้ที่กว้างกว่า 900 ไบต์แม้ว่าคุณจะสามารถเพิ่มคอลัมน์ที่คำนวณแล้วchecksumหรือhashคอลัมน์ที่สามารถใช้เพื่อเร่งความเร็วของแบบสอบถามประเภทนี้ได้


22

โปรดลองทำตามนี้

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

นอกจากนี้ยังมีประโยชน์ในการดูข้อมูลในฟิลด์ TEXT ได้โดยตรงหากคุณใช้เครื่องมือบางอย่างเช่น Toad สำหรับ Sql Server ที่ป้องกันฟิลด์ประเภท BLOB ที่จะเห็นในการดำเนินการครั้งแรก คุณสามารถคลิกช่องเพื่อบอกให้คางคกแสดงเขตข้อมูลได้ตลอดเวลา แต่เป็นขั้นตอนสองขั้นตอน
Roger

โปรดทราบว่าสิ่งนี้อาจทำให้แบบสอบถามของคุณไม่สามารถเปลี่ยนได้
Heinzi

13

คุณไม่สามารถเปรียบเทียบกับtextกับ=ผู้ประกอบการ แต่แทนที่จะต้องใช้หนึ่งในฟังก์ชั่นการเปรียบเทียบที่ระบุไว้ที่นี่ สังเกตช่องคำเตือนขนาดใหญ่ที่ด้านบนของหน้าด้วยซึ่งเป็นสิ่งสำคัญ


5

หากคุณไม่สามารถเปลี่ยนประเภทข้อมูลบนตารางเพื่อใช้ varchar (สูงสุด) ได้ให้เปลี่ยนแบบสอบถามของคุณเป็น:

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

2

นั่นไม่ใช่สิ่งที่ข้อความแสดงข้อผิดพลาดระบุ มันบอกว่าคุณไม่สามารถใช้ตัว=ดำเนินการได้ LIKE 'foo'ลองยกตัวอย่างเช่น


Col IN ('foo', 'bar')โดยพื้นฐานแล้วจะเหมือนกับCol = 'foo' or Col = 'bar'และจะมีปัญหาเดียวกัน
Martin Smith

@Martin: ขอบคุณสำหรับไฮไลต์ฉันไม่รู้เกี่ยวกับเรื่องนี้ ฉันจะแก้ไขให้
Will Marcouiller

0

อีกทางเลือกหนึ่งคือ:

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

ฉันสงสัยว่าlike 'foo'อาจให้ค่าประมาณคาร์ดินาลลิตี้ได้ดีกว่าวิธีนี้ แต่ไม่แน่ใจ 100%
Martin Smith

@Martin: เนื่องจากคุณไม่สามารถสร้างดัชนีคอลัมน์ TEXT ได้ฉันคิดว่าคุณจะต้องสแกนแบบเต็มตารางในทั้งสองกรณี
Joe Stefanelli

ฉันเห็นด้วย แต่จะยังคงใช้สถิติในคอลัมน์เพื่อหาค่าประมาณของแถวที่จะส่งคืนซึ่งอาจส่งผลต่อการตัดสินใจเข้าร่วมเป็นต้น
Martin Smith

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.