ใครช่วยบอกทีว่าต้องใช้begin
และend
บล็อกใน SQL Server เมื่อไหร่และที่ไหน
นอกจากนี้Go
คีย์เวิร์ดทำอะไรกันแน่?
ใครช่วยบอกทีว่าต้องใช้begin
และend
บล็อกใน SQL Server เมื่อไหร่และที่ไหน
นอกจากนี้Go
คีย์เวิร์ดทำอะไรกันแน่?
คำตอบ:
GO เปรียบเสมือนจุดสิ้นสุดของสคริปต์
คุณสามารถมีคำสั่ง CREATE TABLE หลายรายการโดยคั่นด้วย GO เป็นวิธีการแยกส่วนหนึ่งของสคริปต์ออกจากอีกส่วนหนึ่ง แต่ส่งทั้งหมดในบล็อกเดียว
BEGIN และ END เหมือนกับ {and} ใน C / ++ / #, Java และอื่น ๆ
พวกเขาผูกบล็อกโค้ดเชิงตรรกะ ฉันมักจะใช้ BEGIN และ END ที่จุดเริ่มต้นและจุดสิ้นสุดของโพรซีเดอร์ที่เก็บไว้ แต่ก็ไม่จำเป็นอย่างยิ่งที่นั่น ในกรณีที่จำเป็นสำหรับลูปและคำสั่ง IF ฯลฯ ซึ่งคุณต้องการมากกว่าหนึ่งขั้นตอน ...
IF EXISTS (SELECT * FROM my_table WHERE id = @id)
BEGIN
INSERT INTO Log SELECT @id, 'deleted'
DELETE my_table WHERE id = @id
END
คุณต้อง BEGIN ... END เพื่อสร้างบล็อกที่ครอบคลุมมากกว่าหนึ่งคำสั่ง ดังนั้นหากคุณต้องการทำ 2 สิ่งใน 'ขา' เดียวของคำสั่ง IF หรือหากคุณต้องการทำมากกว่าหนึ่งสิ่งในเนื้อหาของลูปในขณะที่คุณต้องยึดคำสั่งเหล่านั้นด้วย BEGIN ... สิ้นสุด
คีย์เวิร์ด GO ไม่ได้เป็นส่วนหนึ่งของ SQL Query Analyzer ใช้เพื่อแบ่งสคริปต์ออกเป็น "แบทช์" ที่ดำเนินการอย่างอิสระ
GO ไม่ใช่คีย์เวิร์ดใน SQL Server มันเป็นตัวคั่นแบทช์ GO จบงบชุดหนึ่ง สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคุณใช้บางอย่างเช่น SQLCMD สมมติว่าคุณกำลังป้อนคำสั่ง SQL ในบรรทัดคำสั่ง คุณไม่จำเป็นต้องให้สิ่งนั้นดำเนินการทุกครั้งที่คุณจบคำสั่งดังนั้น SQL Server จะไม่ทำอะไรเลยจนกว่าคุณจะเข้าสู่ "GO"
ในทำนองเดียวกันก่อนที่แบตช์ของคุณจะเริ่มขึ้นคุณมักจะต้องมองเห็นวัตถุบางอย่าง ตัวอย่างเช่นสมมติว่าคุณกำลังสร้างฐานข้อมูลแล้วทำการสืบค้น คุณไม่สามารถเขียน:
CREATE DATABASE foo;
USE foo;
CREATE TABLE bar;
เนื่องจาก foo ไม่มีอยู่สำหรับชุดงานที่สร้างตาราง คุณต้องทำสิ่งนี้:
CREATE DATABASE foo;
GO
USE foo;
CREATE TABLE bar;
BEGIN และ END ได้รับคำตอบจากผู้อื่นเป็นอย่างดี
ดังที่ Gary ชี้ให้เห็นว่า GO เป็นตัวแยกแบทช์ซึ่งใช้โดยเครื่องมือไคลเอนต์ที่ Microsoft จัดหาให้เช่น isql, sqlcmd, ตัววิเคราะห์แบบสอบถามและสตูดิโอการจัดการเซิร์ฟเวอร์ SQL (อย่างน้อยเครื่องมือบางอย่างก็อนุญาตให้เปลี่ยนตัวคั่นแบทช์ได้ฉันไม่เคยเห็นการใช้สำหรับการเปลี่ยนตัวคั่นแบทช์)
ในการตอบคำถามว่าจะใช้ GO เมื่อใดต้องทราบว่าเมื่อใดที่ต้องแยก SQL ออกเป็นแบตช์
ข้อความบางรายการต้องเป็นคำสั่งแรกของชุดงาน
select 1
create procedure #Zero as
return 0
บน SQL Server 2000 ข้อผิดพลาดคือ:
Msg 111, Level 15, State 1, Line 3
'CREATE PROCEDURE' must be the first statement in a query batch.
Msg 178, Level 15, State 1, Line 4
A RETURN statement with a return value cannot be used in this context.
ใน SQL Server 2005 ข้อผิดพลาดมีประโยชน์น้อย:
Msg 178, Level 15, State 1, Procedure #Zero, Line 5
A RETURN statement with a return value cannot be used in this context.
ดังนั้นใช้GO
เพื่อแยกคำสั่งที่ต้องเป็นจุดเริ่มต้นของชุดงานจากคำสั่งที่อยู่ข้างหน้าในสคริปต์
เมื่อเรียกใช้สคริปต์ข้อผิดพลาดจำนวนมากจะทำให้การดำเนินการของชุดงานหยุดลง แต่จากนั้นไคลเอนต์จะส่งชุดถัดไปการเรียกใช้สคริปต์จะไม่หยุด ฉันมักจะใช้สิ่งนี้ในการทดสอบ ฉันจะเริ่มสคริปต์ด้วย start transaction และจบลงด้วย rollback ทำการทดสอบทั้งหมดตรงกลาง:
begin transaction
go
... test code here ...
go
rollback transaction
ด้วยวิธีนี้ฉันจะกลับสู่สถานะเริ่มต้นเสมอแม้ว่าจะมีข้อผิดพลาดเกิดขึ้นในรหัสทดสอบคำสั่งธุรกรรมเริ่มต้นและย้อนกลับซึ่งเป็นส่วนหนึ่งของชุดงานที่แยกจากกันยังคงเกิดขึ้น หากพวกเขาไม่ได้อยู่ในแบทช์ที่แยกจากกันข้อผิดพลาดทางไวยากรณ์จะทำให้การทำธุรกรรมไม่เกิดขึ้นเนื่องจากแบตช์จะถูกแยกวิเคราะห์เป็นหน่วย และข้อผิดพลาดรันไทม์จะทำให้การย้อนกลับไม่เกิดขึ้น
นอกจากนี้หากคุณกำลังทำสคริปต์การติดตั้งและมีหลายชุดในไฟล์เดียวข้อผิดพลาดในชุดเดียวจะไม่ทำให้สคริปต์ทำงานต่อไปซึ่งอาจทำให้ยุ่งเหยิง (สำรองข้อมูลก่อนติดตั้งทุกครั้ง)
เกี่ยวข้องกับสิ่งที่ Dave Markel ชี้ให้เห็นมีบางกรณีที่การแยกวิเคราะห์จะล้มเหลวเนื่องจาก SQL Server กำลังค้นหาในพจนานุกรมข้อมูลสำหรับวัตถุที่สร้างขึ้นก่อนหน้านี้ในชุดงาน แต่การแยกวิเคราะห์สามารถเกิดขึ้นได้ก่อนที่จะเรียกใช้คำสั่งใด ๆ บางครั้งนี่เป็นปัญหาบางครั้งก็ไม่ใช่ ฉันไม่สามารถหาตัวอย่างที่ดีได้ แต่ถ้าคุณเคยได้รับข้อผิดพลาด 'X ไม่มีอยู่จริง' เมื่อคำสั่งนั้นจะแบ่งออกเป็นแบตช์
และบันทึกสุดท้าย ธุรกรรมสามารถครอบคลุมแบทช์ (ดูด้านบน) ตัวแปรไม่ขยายแบทช์
declare @i int
set @i = 0
go
print @i
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "@i".
GO สิ้นสุดแบทช์คุณแทบจะไม่จำเป็นต้องใช้ในโค้ดเท่านั้น โปรดทราบว่าหากคุณใช้ใน proc ที่จัดเก็บไว้จะไม่มีการเรียกใช้โค้ดหลังจาก GO เมื่อคุณดำเนินการ proc
BEGIN และ END จำเป็นสำหรับคำสั่งประเภทขั้นตอนใด ๆ ที่มีโค้ดหลายบรรทัดในการประมวลผล คุณจะต้องใช้สำหรับลูปและเคอร์เซอร์ในขณะที่ (ซึ่งคุณจะหลีกเลี่ยงได้หากเป็นไปได้แน่นอน) และคำสั่ง IF (โดยทางเทคนิคแล้วคุณไม่จำเป็นต้องใช้มันสำหรับสถิติ IF ที่มีโค้ดเพียงบรรทัดเดียว แต่ง่ายกว่า รักษารหัสหากคุณใส่ไว้หลัง IF เสมอ) คำสั่ง CASE ยังใช้ END แต่ไม่มี BEGIN
หลังจากต่อสู้กับปัญหานี้ในวันนี้ความคิดเห็นของฉันคือ: BEGIN ... END brackets code เหมือนกับที่ {.... } ทำในภาษา C เช่นรหัสบล็อกสำหรับ if ... else และลูป
GO คือ (ต้อง) ใช้เมื่อคำสั่งสำเร็จขึ้นอยู่กับวัตถุที่กำหนดโดยคำสั่งก่อนหน้า ฐานข้อมูล USE เป็นตัวอย่างที่ดีข้างต้น แต่สิ่งต่อไปนี้จะกัดคุณด้วย:
alter table foo add bar varchar(8);
-- if you don't put GO here then the following line will error as it doesn't know what bar is.
update foo set bar = 'bacon';
-- need a GO here to tell the interpreter to execute this statement, otherwise the Parser will lump it together with all successive statements.
สำหรับฉันแล้วปัญหาคือสิ่งนี้: SQL Server SQL Parser ซึ่งแตกต่างจาก Oracle ไม่สามารถตระหนักได้ว่าคุณกำลังกำหนดสัญลักษณ์ใหม่ในบรรทัดแรกและสามารถอ้างอิงในบรรทัดต่อไปนี้ได้ มันจะไม่ "เห็น" สัญลักษณ์จนกว่าจะพบกับโทเค็น GO ซึ่งบอกให้เรียกใช้ SQL ที่นำหน้าตั้งแต่ GO ครั้งสุดท้าย ณ จุดนั้นสัญลักษณ์จะถูกนำไปใช้กับฐานข้อมูลและจะปรากฏให้ผู้แยกวิเคราะห์มองเห็นได้
ทำไมมันไม่เพียง แต่ถือว่าเซมิโคลอนเป็นตัวแบ่งความหมายและใช้คำสั่งทีละคำฉันไม่รู้และหวังว่ามันจะเป็นเช่นนั้น โบนัสเดียวที่ฉันเห็นคือคุณสามารถใส่คำสั่ง print () ก่อนหน้า GO และหากข้อความใด ๆ ล้มเหลวการพิมพ์จะไม่ทำงาน มีปัญหามากมายสำหรับผลประโยชน์เล็กน้อย