การย้ายจาก SQL 2005 [SQL_Latin1_General_CP1_CI_AS] เป็น 2008 - ฉันจะสูญเสียคุณสมบัติใด ๆ โดยใช้ 'ความเข้ากันได้ย้อนหลัง' หรือไม่


18

เรากำลังย้ายจาก SQL 2005 [อินสแตนซ์และฐานข้อมูลมีการเปรียบเทียบSQL_Latin1_General_CP1_CI_AS] เป็น SQL 2008 [ซึ่งเป็นค่าเริ่มต้นไปยังLatin1_General_CI_AS]

ฉันเสร็จสิ้นการติดตั้ง SQL 2008 R2 และใช้การLatin1_General_CI_ASเปรียบเทียบค่าเริ่มต้นแล้วโดยที่การคืนค่าฐานข้อมูลยังคงเปิดอยู่SQL_Latin1_General_CP1_CI_ASเปรียบเทียบกับการฟื้นฟูของฐานข้อมูลที่ยังคงอยู่ในปัญหาที่ยกเว้นเกิดขึ้น - ตาราง #temp ซึ่งใน Latin1_General_CI_ASขณะที่ฐานข้อมูลอยู่ SQL_Latin1_General_CP1_CI_ASและนี่คือที่ฉันอยู่ตอนนี้ - ฉันต้องการคำแนะนำเกี่ยวกับข้อผิดพลาดตอนนี้โปรด

ในการติดตั้ง SQL 2008 R2 ฉันมีตัวเลือกในการติดตั้งให้ใช้โดย'SQL Collation, used for backwards compatibility'ที่ฉันมีตัวเลือกให้เลือกการเรียงหน้าเดียวกันกับฐานข้อมูลปี 2005:SQL_Latin1_General_CP1_CI_AS2005:

  1. สิ่งนี้จะทำให้ฉันไม่มีปัญหากับ #temp tables แต่มีข้อผิดพลาดหรือไม่?

  2. ฉันจะสูญเสียฟังก์ชันการทำงานหรือคุณลักษณะใด ๆ โดยไม่ใช้การจัดเรียง "ปัจจุบัน" ของ SQL 2008 หรือไม่

  3. สิ่งที่เกี่ยวกับเมื่อเราย้าย (เช่นใน 2 ปี) จาก 2008 เป็น SQL 2012 ฉันจะมีปัญหาหรือไม่
  4. ในบางครั้งฉันจะถูกบังคับให้ไปไหม Latin1_General_CI_ASหรือไม่

  5. ฉันอ่านว่าสคริปต์ของ DBA บางส่วนทำตามแถวของฐานข้อมูลที่สมบูรณ์แล้วเรียกใช้สคริปต์แทรกลงในฐานข้อมูลด้วยการจัดเรียงใหม่ - ฉันกลัวมากและระวังสิ่งนี้ - คุณจะแนะนำให้ทำสิ่งนี้หรือไม่


2
หากคุณคิดว่าคุณอาจได้รับใน Hekaton ใน SQL Server 2014 นี่เป็นสิ่งอื่น ๆ ที่คุณอาจต้องการที่จะต้องพิจารณาการอ่าน
Aaron Bertrand

คำตอบ:


20

ก่อนอื่นขอโทษสำหรับคำตอบที่ยาวมาก ๆ เพราะฉันรู้สึกว่ายังมีความสับสนมากมายเมื่อผู้คนพูดถึงคำศัพท์เช่นการเรียงลำดับเรียงลำดับหน้ารหัส ฯลฯ

จากBOL :

collations ใน SQL Server ให้กฎการเรียงลำดับกรณีและคุณสมบัติความไวสำเนียงสำหรับข้อมูลของคุณ การจัดเรียงที่ใช้กับชนิดข้อมูลอักขระเช่น char และ varchar กำหนดรหัสหน้าและอักขระที่เกี่ยวข้องที่สามารถแสดงสำหรับชนิดข้อมูลนั้น ไม่ว่าคุณกำลังติดตั้งอินสแตนซ์ใหม่ของ SQL Server การกู้คืนการสำรองข้อมูลฐานข้อมูลหรือการเชื่อมต่อเซิร์ฟเวอร์กับฐานข้อมูลลูกค้าเป็นสิ่งสำคัญที่คุณต้องเข้าใจข้อกำหนดโลแคลลำดับการเรียงลำดับและความอ่อนไหวของข้อมูลที่คุณจะใช้ .

ซึ่งหมายความว่าการเรียงหน้ามีความสำคัญอย่างยิ่งเนื่องจากระบุกฎว่าสตริงอักขระของข้อมูลจะถูกจัดเรียงและเปรียบเทียบอย่างไร

หมายเหตุ: ข้อมูลเพิ่มเติมเกี่ยวกับCOLLATIONPROPERTY

ตอนนี้ให้เข้าใจความแตกต่างก่อน

ทำงานด้านล่าง T-SQL:

SELECT *
FROM::fn_helpcollations()
WHERE NAME IN (
        'SQL_Latin1_General_CP1_CI_AS'
        ,'Latin1_General_CI_AS'
        )
GO

SELECT 'SQL_Latin1_General_CP1_CI_AS' AS 'Collation'
    ,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage') AS 'CodePage'
    ,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'LCID') AS 'LCID'
    ,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'ComparisonStyle') AS 'ComparisonStyle'
    ,COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'Version') AS 'Version'

UNION ALL

SELECT 'Latin1_General_CI_AS' AS 'Collation'
    ,COLLATIONPROPERTY('Latin1_General_CI_AS', 'CodePage') AS 'CodePage'
    ,COLLATIONPROPERTY('Latin1_General_CI_AS', 'LCID') AS 'LCID'
    ,COLLATIONPROPERTY('Latin1_General_CI_AS', 'ComparisonStyle') AS 'ComparisonStyle'
    ,COLLATIONPROPERTY('Latin1_General_CI_AS', 'Version') AS 'Version'
GO

ผลลัพธ์จะเป็น:

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อดูผลลัพธ์ข้างต้นความแตกต่างเพียงอย่างเดียวคือเรียงลำดับระหว่างการเรียง 2 ครั้ง แต่นั่นไม่เป็นความจริงซึ่งคุณสามารถดูสาเหตุได้ดังนี้

ทดสอบ 1:

--Clean up previous query
IF OBJECT_ID('Table_Latin1_General_CI_AS') IS NOT NULL
    DROP TABLE Table_Latin1_General_CI_AS;

IF OBJECT_ID('Table_SQL_Latin1_General_CP1_CI_AS') IS NOT NULL
    DROP TABLE Table_SQL_Latin1_General_CP1_CI_AS;

-- Create a table using collation Latin1_General_CI_AS 
CREATE TABLE Table_Latin1_General_CI_AS (
    ID INT IDENTITY(1, 1)
    ,Comments VARCHAR(50) COLLATE Latin1_General_CI_AS
    )

-- add some data to it 
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_test1')

INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('Kin_Tester1')

-- Create second table using collation SQL_Latin1_General_CP1_CI_AS 
CREATE TABLE Table_SQL_Latin1_General_CP1_CI_AS (
    ID INT IDENTITY(1, 1)
    ,Comments VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS
    )

-- add some data to it 
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_test1')

INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('Kin_Tester1')

--Now try to join both tables
SELECT *
FROM Table_Latin1_General_CI_AS LG
INNER JOIN Table_SQL_Latin1_General_CP1_CI_AS SLG ON LG.Comments = SLG.Comments
GO

ผลการทดสอบ 1:

Msg 468, Level 16, State 9, Line 35
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the equal to operation.

จากผลลัพธ์ข้างต้นเราจะเห็นได้ว่าเราไม่สามารถเปรียบเทียบค่าโดยตรงกับคอลัมน์ที่มีการเปรียบเทียบที่แตกต่างกันคุณต้องใช้ COLLATEเพื่อเปรียบเทียบค่าคอลัมน์

ทดสอบ 2:

ความแตกต่างที่สำคัญคือประสิทธิภาพการทำงานเป็น Erland Sommarskog ชี้ให้เห็นในการสนทนานี้ใน MSDN

--Clean up previous query
IF OBJECT_ID('Table_Latin1_General_CI_AS') IS NOT NULL
    DROP TABLE Table_Latin1_General_CI_AS;

IF OBJECT_ID('Table_SQL_Latin1_General_CP1_CI_AS') IS NOT NULL
    DROP TABLE Table_SQL_Latin1_General_CP1_CI_AS;

-- Create a table using collation Latin1_General_CI_AS 
CREATE TABLE Table_Latin1_General_CI_AS (
    ID INT IDENTITY(1, 1)
    ,Comments VARCHAR(50) COLLATE Latin1_General_CI_AS
    )

-- add some data to it 
INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_test1')

INSERT INTO Table_Latin1_General_CI_AS (Comments)
VALUES ('kin_tester1')

-- Create second table using collation SQL_Latin1_General_CP1_CI_AS 
CREATE TABLE Table_SQL_Latin1_General_CP1_CI_AS (
    ID INT IDENTITY(1, 1)
    ,Comments VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS
    )

-- add some data to it 
INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_test1')

INSERT INTO Table_SQL_Latin1_General_CP1_CI_AS (Comments)
VALUES ('kin_tester1')

--- สร้างดัชนีในทั้งสองตาราง

CREATE INDEX IX_LG_Comments ON  Table_Latin1_General_CI_AS(Comments)
go
CREATE INDEX IX_SLG_Comments ON  Table_SQL_Latin1_General_CP1_CI_AS(Comments)

--- เรียกใช้แบบสอบถาม

DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments = 'kin_test1'
GO

--- สิ่งนี้จะมีการแปลงโดยนัย

ป้อนคำอธิบายรูปภาพที่นี่

--- เรียกใช้แบบสอบถาม

DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = 'kin_test1'
GO

--- สิ่งนี้จะไม่มีการแปลงโดยนัย

ป้อนคำอธิบายรูปภาพที่นี่

สาเหตุของการแปลงโดยนัยก็เพราะฉันมีฐานข้อมูลและการเปรียบเทียบเซิร์ฟเวอร์ของฉันทั้งสองเป็นSQL_Latin1_General_CP1_CI_ASและตารางTable_Latin1_General_CI_ASมีคอลัมน์ความคิดเห็นที่กำหนดเช่นเดียวVARCHAR(50)กับCOLLATE Latin1_General_CI_ASดังนั้นในระหว่างการค้นหา SQL Server จะต้องทำการแปลง IMPLICIT

ทดสอบ 3:

ด้วยการตั้งค่าเดียวกันตอนนี้เราจะเปรียบเทียบคอลัมน์ varchar กับค่า nvarchar เพื่อดูการเปลี่ยนแปลงในแผนการดำเนินการ

- เรียกใช้แบบสอบถาม

DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_Latin1_General_CI_AS WHERE Comments =  (SELECT N'kin_test1' COLLATE Latin1_General_CI_AS)
GO

ป้อนคำอธิบายรูปภาพที่นี่

- เรียกใช้แบบสอบถาม

DBCC FREEPROCCACHE
GO
SELECT Comments FROM Table_SQL_Latin1_General_CP1_CI_AS WHERE Comments = N'kin_test1'
GO

ป้อนคำอธิบายรูปภาพที่นี่

โปรดทราบว่าแบบสอบถามแรกสามารถทำดัชนีแสวงหา แต่ต้องทำการแปลงโดยนัยในขณะที่อันดับที่สองทำการสแกนดัชนีซึ่งพิสูจน์ว่าไม่มีประสิทธิภาพในแง่ของประสิทธิภาพเมื่อมันจะสแกนตารางขนาดใหญ่

สรุป:

  • จากการทดสอบทั้งหมดข้างต้นแสดงให้เห็นว่าการเปรียบเทียบที่ถูกต้องเป็นสิ่งสำคัญมากสำหรับอินสแตนซ์เซิร์ฟเวอร์ฐานข้อมูลของคุณ
  • SQL_Latin1_General_CP1_CI_AS คือการเปรียบเทียบ SQL กับกฎที่อนุญาตให้คุณเรียงลำดับข้อมูลสำหรับ unicode และ non-unicode นั้นแตกต่างกัน
  • การเปรียบเทียบ SQL จะไม่สามารถใช้ดัชนีเมื่อเปรียบเทียบข้อมูล unicode และ non-unicode ดังที่เห็นในการทดสอบข้างต้นว่าเมื่อเปรียบเทียบข้อมูล nvarchar กับข้อมูล varchar จะทำการสแกนดัชนีและไม่ค้นหา
  • Latin1_General_CI_AS คือการเปรียบเทียบ Windows ที่มีกฎที่อนุญาตให้คุณเรียงลำดับข้อมูลสำหรับ Unicode และ non-Unicode เหมือนกัน
  • การเปรียบเทียบ Windows ยังคงสามารถใช้ดัชนี (ดัชนีค้นหาในตัวอย่างข้างต้น) เมื่อเปรียบเทียบข้อมูล unicode และ non-unicode แต่คุณเห็นว่ามีประสิทธิภาพเล็กน้อย
  • ขอแนะนำให้อ่าน Erland Sommarskog คำตอบ + รายการเชื่อมต่อที่เขาชี้ไป

สิ่งนี้จะทำให้ฉันไม่มีปัญหากับ #temp tables แต่มีข้อผิดพลาดหรือไม่?

ดูคำตอบของฉันด้านบน

ฉันจะสูญเสียฟังก์ชันการทำงานหรือคุณลักษณะใด ๆ โดยไม่ใช้การจัดเรียง "ปัจจุบัน" ของ SQL 2008 หรือไม่

ทุกอย่างขึ้นอยู่กับฟังก์ชันการทำงาน / คุณสมบัติที่คุณอ้างอิง การเรียงคือการจัดเก็บและเรียงลำดับของข้อมูล

สิ่งที่เกี่ยวกับเมื่อเราย้าย (เช่นใน 2 ปี) จาก 2008 เป็น SQL 2012 ฉันจะมีปัญหาหรือไม่ ฉันจะต้องถูกบังคับให้ไปที่ Latin1_General_CI_AS หรือไม่?

ไม่สามารถรับรองได้! เนื่องจากสิ่งต่าง ๆ อาจเปลี่ยนแปลงไปและมันก็ดีเสมอที่จะสอดคล้องกับคำแนะนำของ Microsoft + คุณต้องเข้าใจข้อมูลและข้อผิดพลาดที่ฉันได้กล่าวถึงข้างต้น โปรดอ้างถึงสิ่งนี้และรายการเชื่อมต่อนี้ด้วย

ฉันอ่านว่าสคริปต์ของ DBA บางส่วนทำตามแถวของฐานข้อมูลที่สมบูรณ์แล้วเรียกใช้สคริปต์แทรกลงในฐานข้อมูลด้วยการจัดเรียงใหม่ - ฉันกลัวมากและระวังสิ่งนี้ - คุณจะแนะนำให้ทำสิ่งนี้หรือไม่

เมื่อคุณต้องการเปลี่ยนการจัดเรียงสคริปต์ดังกล่าวจะมีประโยชน์ ฉันพบว่าตัวเองกำลังเปลี่ยนการจัดเรียงฐานข้อมูลเพื่อจับคู่การจัดเรียงเซิร์ฟเวอร์หลายครั้งและฉันมีสคริปต์บางตัวที่ค่อนข้างเรียบร้อย แจ้งให้เราทราบหากคุณต้องการมัน

การอ้างอิง:


5

นอกเหนือจากสิ่งที่ @Kin มีรายละเอียดในคำตอบของเขาแล้วยังมีอีกสองสามสิ่งที่ต้องระวังเมื่อเปลี่ยนการจัดเรียงเริ่มต้นของเซิร์ฟเวอร์ (เช่นของ) การจัดเรียงเริ่มต้น (รายการที่อยู่เหนือเส้นแนวนอนนั้นเกี่ยวข้องโดยตรงกับการเปรียบเทียบสองครั้ง ด้านล่างบรรทัดแนวนอนเกี่ยวข้องกับทั่วไป):

  • หากการตั้งค่าเริ่มต้นของฐานข้อมูลของคุณไม่เปลี่ยนแปลงดังนั้นปัญหาประสิทธิภาพ "การแปลงโดยนัย" ที่อธิบายไว้ในคำตอบของ @ Kin ไม่น่าจะมีปัญหาเนื่องจากตัวอักษรสตริงและตัวแปรท้องถิ่นใช้ Collation เริ่มต้นของฐานข้อมูลไม่ใช่เซิร์ฟเวอร์ ผลกระทบเพียงอย่างเดียวสำหรับสถานการณ์ที่มีการเปลี่ยนแปลงระดับการเปรียบเทียบ แต่ไม่มีการเปรียบเทียบระดับฐานข้อมูลคือ (ทั้งอธิบายในรายละเอียดด้านล่าง):

    • การเปรียบเทียบที่อาจเกิดขึ้นกับตารางชั่วคราว (แต่ไม่ใช่ตัวแปรของตาราง)
    • รหัสที่อาจเกิดความเสียหายหากการใส่ตัวแปรและ / หรือเคอร์เซอร์ไม่ตรงกับการประกาศ (แต่สิ่งนี้สามารถเกิดขึ้นได้หากย้ายไปยังอินสแตนซ์ที่มีการเปรียบเทียบแบบไบนารีหรือแบบตัวพิมพ์ใหญ่ - เล็ก)
  • ความแตกต่างหนึ่งระหว่างการเปรียบเทียบทั้งสองนี้คือวิธีที่พวกเขาจัดเรียงอักขระบางตัวสำหรับVARCHARข้อมูล (สิ่งนี้ไม่ส่งผลกระทบต่อNVARCHARข้อมูล) การจัดSQL_เรียงที่ไม่ใช่ EBCDIC ใช้สิ่งที่เรียกว่า "การเรียงสตริง" สำหรับVARCHARข้อมูลในขณะที่การเรียงข้อมูลอื่นทั้งหมดและแม้กระทั่งNVARCHARข้อมูลสำหรับการจัดSQL_เรียงที่ไม่ใช่ EBCDIC ให้ใช้สิ่งที่เรียกว่า "การเรียงลำดับของ Word" ความแตกต่างคือใน "การเรียงลำดับของ Word" เส้นประ-และเครื่องหมายอัญประกาศเดี่ยว'(และอาจเป็นอักขระอื่นสองสามตัว) ได้รับน้ำหนักที่ต่ำมากและจะถูกละเว้นเป็นหลักเว้นแต่จะไม่มีความแตกต่างอื่น ๆ ในสายอักขระ หากต้องการดูพฤติกรรมนี้ในการทำงานให้เรียกใช้สิ่งต่อไปนี้:

    DECLARE @Test TABLE (Col1 VARCHAR(10) NOT NULL);
    INSERT INTO @Test VALUES ('aa');
    INSERT INTO @Test VALUES ('ac');
    INSERT INTO @Test VALUES ('ah');
    INSERT INTO @Test VALUES ('am');
    INSERT INTO @Test VALUES ('aka');
    INSERT INTO @Test VALUES ('akc');
    INSERT INTO @Test VALUES ('ar');
    INSERT INTO @Test VALUES ('a-f');
    INSERT INTO @Test VALUES ('a_e');
    INSERT INTO @Test VALUES ('a''kb');
    
    SELECT * FROM @Test ORDER BY [Col1] COLLATE SQL_Latin1_General_CP1_CI_AS;
    -- "String Sort" puts all punctuation ahead of letters
    
    SELECT * FROM @Test ORDER BY [Col1] COLLATE Latin1_General_100_CI_AS;
    -- "Word Sort" mostly ignores dash and apostrophe

    ผลตอบแทน:

    String Sort
    -----------
    a'kb
    a-f
    a_e
    aa
    ac
    ah
    aka
    akc
    am
    ar

    และ:

    Word Sort
    ---------
    a_e
    aa
    ac
    a-f
    ah
    aka
    a'kb
    akc
    am
    ar

    ในขณะที่คุณจะ "สูญเสีย" พฤติกรรม "การเรียงลำดับสตริง" ฉันไม่แน่ใจว่าจะเรียกว่า "ฟีเจอร์" มันเป็นพฤติกรรมที่ไม่พึงประสงค์ (เห็นได้จากข้อเท็จจริงที่ว่าไม่ได้นำไปสู่การเปรียบเทียบ Windows ใด ๆ ) อย่างไรก็ตามมันเป็นความแตกต่างที่ชัดเจนของพฤติกรรมระหว่างการเปรียบเทียบสองครั้ง (อีกครั้งสำหรับข้อมูลที่ไม่ใช่ EBCDIC VARCHAR) และคุณอาจมีรหัสและ / หรือความคาดหวังของลูกค้าตามพฤติกรรม "การเรียงลำดับสตริง" สิ่งนี้ต้องการการทดสอบรหัสของคุณและอาจทำการวิจัยเพื่อดูว่าการเปลี่ยนแปลงลักษณะการทำงานนี้อาจส่งผลเสียต่อผู้ใช้หรือไม่

  • ความแตกต่างระหว่างอีกSQL_Latin1_General_CP1_CI_ASและLatin1_General_100_CI_ASมีความสามารถที่จะทำขยายในVARCHARข้อมูล ( NVARCHARข้อมูลอยู่แล้วสามารถทำสิ่งเหล่านี้ให้มากที่สุดSQL_Collations) เช่นการจัดการæราวกับว่ามันเป็นae:

    IF ('æ' COLLATE SQL_Latin1_General_CP1_CI_AS =
        'ae' COLLATE SQL_Latin1_General_CP1_CI_AS)
    BEGIN
      PRINT 'SQL_Latin1_General_CP1_CI_AS';
    END;
    
    IF ('æ' COLLATE Latin1_General_100_CI_AS =
        'ae' COLLATE Latin1_General_100_CI_AS)
    BEGIN
      PRINT 'Latin1_General_100_CI_AS';
    END;

    ผลตอบแทน:

    Latin1_General_100_CI_AS

    สิ่งเดียวที่คุณ "สูญเสีย" ที่นี่คือไม่สามารถทำการขยายเหล่านี้ได้ โดยทั่วไปแล้วนี่เป็นข้อดีอีกประการหนึ่งของการย้ายไปใช้การจัดเรียง Windows อย่างไรก็ตามเช่นเดียวกับการย้าย "String Sort" เป็น "Word Sort" ข้อควรระวังที่เหมือนกันใช้: มันเป็นความแตกต่างที่ชัดเจนของพฤติกรรมระหว่างการเปรียบเทียบสองครั้ง (อีกครั้งสำหรับVARCHARข้อมูล) และคุณอาจมีรหัสและ / หรือลูกค้า ความคาดหวังจากการไม่มีการแมปเหล่านี้ สิ่งนี้ต้องการการทดสอบรหัสของคุณและอาจทำการวิจัยเพื่อดูว่าการเปลี่ยนแปลงลักษณะการทำงานนี้อาจส่งผลเสียต่อผู้ใช้หรือไม่

    (ข้อสังเกตแรกในคำตอบ SO นี้โดย @Zarepheth: SQL Server SQL_Latin1_General_CP1_CI_AS สามารถแปลงเป็น Latin1_General_CI_AS ได้อย่างปลอดภัยหรือไม่ )

  • [model]การเปรียบเทียบระดับเซิร์ฟเวอร์ใช้ในการตั้งเปรียบเทียบของฐานข้อมูลของระบบซึ่งรวมถึง [model]ฐานข้อมูลถูกนำมาใช้เป็นแม่แบบในการสร้างฐานข้อมูลใหม่ซึ่งรวมถึง[tempdb]เมื่อเริ่มต้นแต่ละเซิร์ฟเวอร์ แต่ถึงแม้จะมีการเปลี่ยนแปลงของการเปรียบเทียบระดับเซิร์ฟเวอร์เปลี่ยนการเปรียบเทียบของ[tempdb]มีเป็นวิธีที่ค่อนข้างง่ายที่จะแก้ไขความแตกต่างระหว่างการเปรียบเทียบฐานข้อมูลที่เป็น "ปัจจุบัน" เมื่อมีการดำเนินการและCREATE #TempTable [tempdb]เมื่อสร้างตารางชั่วคราวให้ประกาศการเรียงโดยใช้ส่วนCOLLATEคำสั่งและระบุการเรียงเป็นDATABASE_DEFAULT:

    CREATE TABLE #Temp (Col1 NVARCHAR(40) COLLATE DATABASE_DEFAULT);

  • เป็นการดีที่สุดที่จะใช้รุ่นล่าสุดของการเปรียบเทียบที่ต้องการหากมีหลายรุ่น เริ่มต้นใน SQL Server 2005 มีการแนะนำชุดการเปรียบเทียบชุด "90" และ SQL Server 2008 ได้นำชุดการเปรียบเทียบชุด "100" คุณสามารถค้นหาการเปรียบเทียบเหล่านี้โดยใช้แบบสอบถามต่อไปนี้:

    SELECT * FROM sys.fn_helpcollations() WHERE [name] LIKE N'%[_]90[_]%'; -- 476
    
    SELECT * FROM sys.fn_helpcollations() WHERE [name] LIKE N'%[_]100[_]%'; -- 2686

    ตั้งแต่คุณอยู่ใน SQL Server 2008 R2 คุณควรใช้แทนLatin1_General_100_CI_ASLatin1_General_CI_AS

  • ความแตกต่างระหว่างตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ของการเปรียบเทียบที่เฉพาะเจาะจงเหล่านี้ (เช่นSQL_Latin1_General_CP1_CS_ASและLatin1_General_100_CS_AS) นั้นอยู่ในลำดับของตัวพิมพ์ใหญ่และตัวพิมพ์เล็กเมื่อทำการเรียงลำดับแบบตรงตามตัวพิมพ์ใหญ่ - เล็ก สิ่งนี้ยังส่งผลต่อช่วงคลาสอักขระเดี่ยว (เช่น[start-end]) ที่สามารถใช้กับLIKEโอเปอเรเตอร์และPATINDEXฟังก์ชันได้ เคียวรีสามข้อต่อไปนี้แสดงเอฟเฟกต์นี้สำหรับการเรียงลำดับและช่วงอักขระ:

    SELECT tmp.col AS [Upper-case first]
    FROM (VALUES ('a'), ('A'), ('b'), ('B'), ('c'), ('C')) tmp(col)
    WHERE tmp.col LIKE '%[A-C]%' COLLATE SQL_Latin1_General_CP1_CS_AS
    ORDER BY tmp.col COLLATE SQL_Latin1_General_CP1_CS_AS; -- Upper-case first
    
    SELECT tmp.col AS [Lower-case first]
    FROM (VALUES ('a'), ('A'), ('b'), ('B'), ('c'), ('C')) tmp(col)
    WHERE tmp.col LIKE '%[A-C]%' COLLATE Latin1_General_100_CS_AS
    ORDER BY tmp.col COLLATE Latin1_General_100_CS_AS; -- Lower-case first
    
    SELECT tmp.col AS [Lower-case first]
    FROM (VALUES (N'a'), (N'A'), (N'b'), (N'B'), (N'c'), (N'C')) tmp(col)
    WHERE tmp.col LIKE N'%[A-C]%' COLLATE SQL_Latin1_General_CP1_CS_AS
    ORDER BY tmp.col COLLATE SQL_Latin1_General_CP1_CS_AS; -- Lower-case first

    วิธีเดียวที่จะได้ตัวพิมพ์ใหญ่ก่อนหน้าตัวพิมพ์เล็ก (สำหรับตัวอักษรเดียวกัน) คือการใช้หนึ่งใน 31 การเรียงหน้าที่รองรับพฤติกรรมดังกล่าวซึ่งคือการHungarian_Technical_*เรียงหน้าและการเรียงแบบกำมือหนึ่งครั้งSQL_(ซึ่งสนับสนุนพฤติกรรมนี้เท่านั้นสำหรับVARCHARข้อมูล )

  • ความสำคัญน้อยกว่าสำหรับการเปลี่ยนแปลงเฉพาะนี้ แต่ก็ยังดีที่ควรทราบเนื่องจากจะมีผลกระทบหากการเปลี่ยนเซิร์ฟเวอร์เป็นการเปรียบเทียบแบบไบนารีหรือแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่คือการเปรียบเทียบระดับเซิร์ฟเวอร์นั้นมีผลต่อ:

    • ชื่อตัวแปรท้องถิ่น
    • ชื่อเคอร์เซอร์
    • ป้ายกำกับ GOTO
    • การsysnameจำแนกชื่อประเภทข้อมูล


    หมายความว่าถ้าคุณหรือ "โปรแกรมเมอร์ที่เพิ่งลาออก" ซึ่งเป็นผู้รับผิดชอบโค้ดที่ไม่ดีทั้งหมด ;-) ไม่ระวังเกี่ยวกับการใส่ปลอกและประกาศตัวแปรว่า@SomethingIDแต่หลังจากนั้นเรียกมันใน@somethingIdภายหลัง -sensitive หรือการเปรียบเทียบไบนารี ในทำนองเดียวกันรหัสที่ใช้sysnameประเภทข้อมูล แต่อ้างถึงว่าเป็นSYSNAME, SysNameหรือสิ่งอื่นที่ไม่ใช่ตัวพิมพ์เล็กทั้งหมดจะแตกถ้าย้ายไปยังอินสแตนซ์โดยใช้การเปรียบเทียบตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่

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