ในขณะที่ตรวจสอบรหัสบางส่วนบนเว็บและสคริปต์ที่สร้างขึ้นโดย SQL Server Management Studio ฉันสังเกตว่าคำสั่งบางคำจะจบลงด้วยเครื่องหมายอัฒภาค
ดังนั้นเมื่อไรฉันจึงควรใช้
ในขณะที่ตรวจสอบรหัสบางส่วนบนเว็บและสคริปต์ที่สร้างขึ้นโดย SQL Server Management Studio ฉันสังเกตว่าคำสั่งบางคำจะจบลงด้วยเครื่องหมายอัฒภาค
ดังนั้นเมื่อไรฉันจึงควรใช้
คำตอบ:
จากบทความ SQLServerCentral.Com โดย Ken Powers:
อัฒภาค
อักขระเครื่องหมายอัฒภาคเป็นตัวสิ้นสุดของคำสั่ง มันเป็นส่วนหนึ่งของมาตรฐาน ANSI SQL-92 แต่ไม่เคยใช้ภายใน Transact-SQL แน่นอนว่ามันเป็นไปได้ที่จะใช้รหัส T-SQL เป็นเวลาหลายปีโดยไม่ต้องใช้เครื่องหมายอัฒภาค
การใช้
มีสองสถานการณ์ที่คุณต้องใช้เครื่องหมายอัฒภาค สถานการณ์แรกคือตำแหน่งที่คุณใช้ Common Table Expression (CTE) และ CTE ไม่ใช่คำสั่งแรกในแบตช์ ข้อที่สองคือที่ที่คุณใช้คำสั่ง Service Broker และคำสั่ง Service Broker ไม่ใช่คำสั่งแรกในแบตช์
THROW
คำสั่งที่บริการนายหน้า? เราต้องรวมเซมิโคลอนไว้ก่อนที่จะแสดงในตัวอย่างนี้:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
ตัวอย่างเช่น) ดังที่กล่าวไว้ในคำตอบอื่น ๆ ในมาตรฐาน ANSI พวกเขาจำเป็นต้องใช้
โดยค่าเริ่มต้นคำสั่ง SQL จะถูกยกเลิกด้วยเครื่องหมายอัฒภาค คุณใช้เครื่องหมายอัฒภาคเพื่อยกเลิกคำสั่งเว้นแต่ว่าคุณจะตั้งค่าตัวยกเลิกคำสั่งใหม่ (ไม่ค่อย)
หากคุณส่งคำสั่งเพียงคำเดียวคุณสามารถแจกจ่ายคำสั่งนั้นได้ด้วยเทคนิค ในสคริปต์เมื่อคุณส่งคำสั่งมากกว่าหนึ่งคำสั่งคุณจำเป็นต้องใช้
ในทางปฏิบัติให้รวมเทอร์มิเนเตอร์เสมอแม้ว่าคุณจะส่งคำสั่งหนึ่งไปยังฐานข้อมูล
แก้ไข: ในการตอบสนองต่อคำพูดที่บอกเลิกไม่จำเป็นต้อง [โดยเฉพาะ RDBMS] ในขณะที่อาจเป็นจริงพวกเขาจะต้องใช้มาตรฐาน ANSI SQL ในการเขียนโปรแกรมทั้งหมดหากเราสามารถปฏิบัติตามมาตรฐานโดยไม่สูญเสียฟังก์ชันการทำงานเราควรเพราะรหัสของเราหรือนิสัยของเรานั้นไม่ได้ผูกติดอยู่กับผู้ให้บริการรายเดียว
ด้วยคอมไพเลอร์ C บางตัวเป็นไปได้ที่จะมีโมฆะการส่งคืนหลักแม้ว่ามาตรฐานจะต้องการ main เพื่อคืนค่า int แต่การทำเช่นนั้นทำให้โค้ดของเราและตัวเราเองพกพาได้น้อยลง
ปัญหาที่ยากที่สุดในการเขียนโปรแกรมอย่างมีประสิทธิภาพไม่ได้เรียนรู้สิ่งใหม่มันเป็นนิสัยที่ไม่ดี เท่าที่เราสามารถหลีกเลี่ยงการรับนิสัยที่ไม่ดีในตอนแรกมันเป็นชัยชนะสำหรับเราสำหรับรหัสของเราและสำหรับทุกคนที่อ่านหรือใช้รหัสของเรา
ใน SQL2008 BOL พวกเขากล่าวว่าในเซมิโคลอนรุ่นถัดไปจะต้องใช้ ดังนั้นควรใช้มันเสมอ
อ้างอิง:
คุณต้องใช้มัน
การฝึกใช้เซมิโคลอนเพื่อบอกเลิกคำสั่งเป็นมาตรฐานและอันที่จริงเป็นข้อกำหนดในแพลตฟอร์มฐานข้อมูลอื่น ๆ SQL Server จำเป็นต้องใช้เครื่องหมายอัฒภาคในบางกรณีเท่านั้น แต่ในกรณีที่ไม่จำเป็นต้องใช้เครื่องหมายอัฒภาคการใช้อันหนึ่งจะไม่ทำให้เกิดปัญหา ฉันขอแนะนำอย่างยิ่งให้คุณรับเอาแนวปฏิบัติในการยกเลิกข้อความทั้งหมดด้วยเครื่องหมายอัฒภาค ไม่เพียง แต่การทำเช่นนี้จะช่วยปรับปรุงความสามารถในการอ่านโค้ดของคุณ แต่ในบางกรณีอาจช่วยให้คุณเศร้าโศกได้ (เมื่อต้องการใช้เครื่องหมายอัฒภาคและไม่ได้ระบุข้อความแสดงข้อผิดพลาดที่ SQL Server สร้างขึ้นจะไม่ชัดเจนเสมอไป)
และที่สำคัญที่สุด:
เอกสารคู่มือ SQL Server บ่งชี้ว่าการยกเลิกคำสั่ง T-SQL ด้วยเครื่องหมายอัฒภาคนั้นเป็นคุณสมบัติที่เลิกใช้แล้ว ซึ่งหมายความว่าเป้าหมายระยะยาวคือการบังคับใช้เครื่องหมายอัฒภาคในผลิตภัณฑ์รุ่นอนาคต นั่นเป็นอีกเหตุผลหนึ่งที่ทำให้การเลิกใช้งบทั้งหมดของคุณเป็นไปได้แม้จะไม่จำเป็นก็ตาม
ที่มา: พื้นฐาน T-SQL ของ Microsoft SQL Server 2012 โดย Itzik Ben-Gan
ตัวอย่างของเหตุผลที่คุณต้องใช้เสมอ;
คือแบบสอบถามสองแบบต่อไปนี้ (คัดลอกมาจากโพสต์นี้):
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
THROW
END CATCH
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
เป็นเทคนิคที่เลิกใช้แล้วคุณควรใช้มัน หากไม่มีความเสี่ยงที่จะประสบในอนาคต หากคุณไม่ได้วางแผนที่จะอัพเกรด / สลับงานและมักจะทำงานกับ SQL Server 2000 คุณจะปลอดภัย :-)
Incorrect syntax near 'THROW'.
SQL Server 2008 (10.0.6241.0) ซึ่งเป็นรุ่นที่ฉันต้องจัดการกับที่ทำงาน มันทำงานตามที่แสดงในปี 2012 ฉันมั่นใจที่จะเริ่มใช้เครื่องหมายอัฒภาคเนื่องจากการคัดค้าน ฉันไม่คาดหวังว่ามันจะเป็นปัญหาในปี 2008 โดยส่วนใหญ่
ถ้าฉันอ่านอย่างถูกต้องมันจะเป็นข้อกำหนดให้ใช้เครื่องหมายอัฒภาคเพื่อสิ้นสุดคำสั่ง TSQL http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
แก้ไข: ฉันพบปลั๊กอินสำหรับ SSMS 2008R2 ที่จะจัดรูปแบบสคริปต์ของคุณและเพิ่มเครื่องหมายอัฒภาค ฉันคิดว่ามันยังอยู่ในช่วงเบต้า แต่ ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
แก้ไข: ฉันพบเครื่องมือที่ดียิ่งขึ้น / ปลั๊กอินที่เรียกว่า ApexSQL ... http://www.apexsql.com/
ความคิดเห็นส่วนตัว:ใช้งานเฉพาะเมื่อจำเป็นเท่านั้น (ดูคำตอบของ TheTXI ด้านบนสำหรับรายการที่ต้องการ)
เนื่องจากคอมไพเลอร์ไม่ต้องการพวกเขาคุณสามารถวางมันไว้ได้ แต่ทำไม? คอมไพเลอร์จะไม่บอกตำแหน่งที่คุณลืมไปดังนั้นคุณจะต้องใช้งานอย่างไม่สอดคล้องกัน
[ความคิดเห็นนี้เฉพาะกับ SQL Server ฐานข้อมูลอื่นอาจมีข้อกำหนดที่เข้มงวดกว่านี้ หากคุณกำลังเขียน SQL ให้ทำงานบนฐานข้อมูลหลาย ๆ ข้อกำหนดของคุณอาจแตกต่างกันไป]
tpdi ระบุไว้ข้างต้น "ในสคริปต์เนื่องจากคุณส่งข้อความมากกว่าหนึ่งรายการคุณจำเป็นต้องใช้มัน" ที่จริงไม่ถูกต้อง คุณไม่ต้องการพวกเขา
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';
เอาท์พุท:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
ฉันยังมีอีกมากที่ต้องเรียนรู้เกี่ยวกับ T-SQL แต่ในการทำงานโค้ดบางอย่างสำหรับธุรกรรม (และการอ้างอิงรหัสจากตัวอย่างจาก stackoverflow และไซต์อื่น ๆ ) ฉันพบกรณีที่ดูเหมือนว่าต้องใช้เครื่องหมายอัฒภาคและหากมันหายไป ดูเหมือนว่าคำสั่งจะไม่ดำเนินการเลยและไม่มีข้อผิดพลาดเกิดขึ้น สิ่งนี้ดูเหมือนจะไม่ครอบคลุมในคำตอบข้างต้นใด ๆ (สิ่งนี้ใช้ MS SQL Server 2012)
เมื่อฉันทำรายการทำงานตามที่ฉันต้องการฉันตัดสินใจที่จะลองทำมันดังนั้นหากมีข้อผิดพลาดใด ๆ ที่จะได้รับการย้อนกลับ หลังจากทำเช่นนี้แล้วการทำธุรกรรมดังกล่าวก็ไม่ได้กระทำ (SSMS ยืนยันสิ่งนี้เมื่อพยายามปิดหน้าต่างด้วยข้อความที่ดีเพื่อเตือนให้คุณทราบว่ามีการทำธุรกรรมที่ไม่ได้รับการยอมรับ
ดังนั้นนี่
COMMIT TRANSACTION
นอกบล็อกเริ่มต้น BEGIN TRY / END TRY ทำงานได้ดีในการส่งมอบธุรกรรม แต่ภายในบล็อกนั้นจะต้องเป็น
COMMIT TRANSACTION;
หมายเหตุไม่มีข้อผิดพลาดหรือคำเตือนให้และไม่มีการบ่งชี้ว่าการทำธุรกรรมยังคงปราศจากข้อผูกมัดจนกว่าจะพยายามที่จะปิดแท็บแบบสอบถาม
โชคดีที่สิ่งนี้ทำให้เกิดปัญหาใหญ่ที่เห็นได้ชัดในทันทีว่ามีปัญหา น่าเสียดายเนื่องจากไม่มีรายงานข้อผิดพลาด (ไวยากรณ์หรืออย่างอื่น) จึงไม่ชัดเจนว่าปัญหานั้นเกิดขึ้นในทันที
ตรงกันข้ามการทำธุรกรรม ROLLBACK ดูเหมือนจะทำงานได้ดีพอ ๆ กันในบล็อก BEGIN CATCH ที่มีหรือไม่มีเครื่องหมายอัฒภาค
อาจมีเหตุผลบางอย่างในเรื่องนี้ แต่มันให้ความรู้สึกตามอำเภอใจและ Alice-in-Wonderland-ish
COMMIT TRANSACTION
ยอมรับการทำธุรกรรมหรือชื่อจุดบันทึก (ซึ่งจะละเว้น) หากไม่มีเครื่องหมายอัฒภาคCOMMIT TRANSACTION
สามารถกินสัญลักษณ์ต่อไปหากแยกวิเคราะห์เป็นตัวบ่งชี้ซึ่งสามารถเปลี่ยนความหมายของรหัสได้อย่างรุนแรง หากสิ่งนี้ส่งผลให้เกิดข้อผิดพลาดCATCH
อาจเรียกใช้โดยไม่COMMIT
ต้องถูกดำเนินการ ในทางกลับกันในขณะที่ROLLBACK TRANSACTION
ยังยอมรับตัวระบุที่เป็นตัวเลือกเช่นนี้ข้อผิดพลาดในการแยกวิเคราะห์มีแนวโน้มมากที่สุดที่จะทำให้ธุรกรรมถูกย้อนกลับ
ปรากฏว่าอัฒภาคไม่ควรนำมาใช้ร่วมกับการดำเนินงานของเคอร์เซอร์: OPEN
, FETCH
, และCLOSE
DEALLOCATE
ฉันเพิ่งเสียเวลาสองสามชั่วโมงกับสิ่งนี้ ฉันดู BOL อย่างใกล้ชิดและสังเกตว่า [;] ไม่แสดงในไวยากรณ์สำหรับคำสั่งเคอร์เซอร์เหล่านี้ !!
ดังนั้นฉันจึง:
OPEN mycursor;
และนี่ทำให้ฉันเกิดข้อผิดพลาด 16916
แต่:
OPEN mycursor
ทำงาน
ตามอนุสัญญาไวยากรณ์ของ Transact-SQL (Transact-SQL) (MSDN)
ตัวสิ้นสุดคำสั่ง Transact-SQL แม้ว่าจะไม่จำเป็นต้องใช้เครื่องหมายอัฒภาคสำหรับคำสั่งส่วนใหญ่ใน SQL Server รุ่นนี้ แต่จะต้องใช้ในรุ่นอนาคต
(โปรดดูความคิดเห็นของ @gerryLowry)
เมื่อใช้คำสั่ง DISABLE หรือ ENABLE TRIGGER ในแบทช์ที่มีคำสั่งอื่นอยู่คำสั่งก่อนที่จะต้องจบด้วยเซมิโคลอน มิฉะนั้นคุณจะได้รับข้อผิดพลาดทางไวยากรณ์ ฉันฉีกผมออกด้วยอันนี้ ... และหลังจากนั้นฉันก็สะดุดกับรายการ MS Connect นี้เกี่ยวกับสิ่งเดียวกัน มันถูกปิดเนื่องจากไม่สามารถแก้ไขได้
ดูที่นี่
หมายเหตุ: นี่ตอบคำถามตามที่เขียน แต่ไม่ใช่ปัญหาตามที่ระบุไว้ เพิ่มที่นี่เนื่องจากผู้คนจะค้นหา
อัฒภาคยังใช้มาก่อนWITH
ในคำสั่ง CTE แบบเรียกซ้ำ:
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
แบบสอบถามนี้จะสร้าง CTE ที่เรียกว่า Numbers ซึ่งประกอบด้วยจำนวนเต็ม [1..10] ทำได้โดยการสร้างตารางที่มีค่า 1 เท่านั้นจากนั้นเรียกซ้ำจนกว่าจะถึง 10
ถ้าคุณชอบรับCommand Timeoutแบบสุ่มข้อผิดพลาดใน SQLServer ให้ละจากเครื่องหมายทวิภาคตอนท้ายของสตริง CommandText ของคุณ
ฉันไม่รู้ว่านี่เป็นเอกสารที่ใดหรือเป็นข้อผิดพลาดหรือไม่ แต่มันเกิดขึ้นและฉันได้เรียนรู้จากประสบการณ์ที่ขมขื่น
ฉันมีตัวอย่างที่ตรวจสอบได้และทำซ้ำได้โดยใช้ SQLServer 2008
aka -> ในทางปฏิบัติให้ใส่เทอร์มิเนเตอร์แม้ว่าคุณจะส่งคำสั่งหนึ่งไปยังฐานข้อมูล
อัฒภาคไม่ทำงานเสมอในคำสั่งผสมคำสั่ง
เปรียบเทียบทั้งสองเวอร์ชันที่แตกต่างกันของคำสั่ง SELECT แบบผสม
รหัส
DECLARE @Test varchar(35);
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.';);););
SELECT @Test Test;
ผลตอบแทน
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.
อย่างไรก็ตามรหัส
DECLARE @Test varchar(35)
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.')))
SELECT @Test Test
ผลตอบแทน
Test
-----------------------------------
Semicolons do not always work fine.
(1 row(s) affected)