ในคำถามอื่นที่ฉันโพสต์มีคนบอกฉันว่ามีความแตกต่างระหว่าง:
@variable
และ:
variable
ใน MySQL เขายังกล่าวถึงวิธี MSSQL มีขอบเขตชุดและ MySQL มีขอบเขตเซสชัน บางคนสามารถอธิบายเรื่องนี้ให้ฉันได้ไหม
ในคำถามอื่นที่ฉันโพสต์มีคนบอกฉันว่ามีความแตกต่างระหว่าง:
@variable
และ:
variable
ใน MySQL เขายังกล่าวถึงวิธี MSSQL มีขอบเขตชุดและ MySQL มีขอบเขตเซสชัน บางคนสามารถอธิบายเรื่องนี้ให้ฉันได้ไหม
คำตอบ:
MySQLมีแนวคิดของตัวแปรที่ผู้ใช้กำหนด
พวกเขาเป็นตัวแปรที่พิมพ์อย่างหลวม ๆ ที่อาจเริ่มต้นที่ไหนสักแห่งในเซสชั่นและเก็บค่าของพวกเขาจนกว่าเซสชั่นจะสิ้นสุดลง
พวกเขาได้รับการต่อเติมด้วย@เครื่องหมายเช่นนี้@var
คุณสามารถเริ่มต้นตัวแปรนี้ด้วยSETคำสั่งหรือภายในในแบบสอบถาม:
SET @var = 1
SELECT @var2 := 2
เมื่อคุณพัฒนาโพรซีเดอร์ที่เก็บในMySQLคุณสามารถส่งผ่านพารามิเตอร์อินพุตและประกาศตัวแปรโลคัล:
DELIMITER //
CREATE PROCEDURE prc_test (var INT)
BEGIN
DECLARE var2 INT;
SET var2 = 1;
SELECT var2;
END;
//
DELIMITER ;
ตัวแปรเหล่านี้ไม่ได้เติมไว้พร้อมกับคำนำหน้าใด ๆ
ความแตกต่างระหว่างตัวแปรขั้นตอนและตัวแปรที่ผู้ใช้กำหนดเฉพาะเซสชันคือตัวแปรขั้นตอนจะเริ่มต้นใหม่NULLทุกครั้งที่มีการเรียกใช้โพรซีเดอร์ในขณะที่ตัวแปรเฉพาะเซสชันไม่ได้เป็น:
CREATE PROCEDURE prc_test ()
BEGIN
DECLARE var2 INT DEFAULT 1;
SET var2 = var2 + 1;
SET @var2 = @var2 + 1;
SELECT var2, @var2;
END;
SET @var2 = 1;
CALL prc_test();
var2 @var2
--- ---
2 2
CALL prc_test();
var2 @var2
--- ---
2 3
CALL prc_test();
var2 @var2
--- ---
2 4
ดังที่คุณเห็นvar2(ตัวแปรขั้นตอน) จะเริ่มต้นใหม่ทุกครั้งที่มีการเรียกขั้นตอนขณะที่@var2(ตัวแปรเฉพาะเซสชัน) ไม่
(นอกจากตัวแปรที่ผู้ใช้กำหนดเอง MySQL ยังมี "ตัวแปรระบบ" ที่กำหนดไว้ล่วงหน้าซึ่งอาจเป็น "ตัวแปรทั่วโลก" เช่น@@global.portหรือ "ตัวแปรเซสชัน" เช่น@@session.sql_mode"ตัวแปรเซสชัน" เหล่านี้ไม่เกี่ยวข้องกับเซสชันที่ผู้ใช้กำหนด ตัวแปร.)
SELECT @@version;ตัวอย่าง นี่คือเหตุผลว่าทำไมการใช้งานDELIMITER @@ไม่ใช่ความคิดที่ดีจริงๆ
@vs ไม่?
:=และ=และนั่นคือการ:=ทำงานเป็นผู้ประกอบการกำหนดตัวแปรทุกที่ในขณะที่=ทำงานได้ด้วยวิธีการในSETงบและเป็นผู้ประกอบการเปรียบเทียบทุกที่อื่น ดังนั้นSELECT @var = 1 + 1;จะปล่อยให้ @var ไม่เปลี่ยนแปลงและคืนค่าบูลีน (1 หรือ 0 ขึ้นอยู่กับค่าปัจจุบันของ @var) ในขณะที่SELECT @var := 1 + 1;จะเปลี่ยน @var เป็น 2 และส่งคืน 2
ใน MySQL, @variableบ่งชี้ตัวแปรที่ผู้ใช้กำหนด คุณสามารถกำหนดของคุณเอง
SET @a = 'test';
SELECT @a;
นอกโปรแกรมที่จัดเก็บไว้ a variable, ภายนอก@, เป็นตัวแปรระบบซึ่งคุณไม่สามารถกำหนดได้
ขอบเขตของตัวแปรนี้คือเซสชันทั้งหมด นั่นหมายความว่าในขณะที่การเชื่อมต่อกับฐานข้อมูลของคุณยังคงมีอยู่ตัวแปรยังคงสามารถใช้งานได้
สิ่งนี้ตรงกันข้ามกับ MSSQL ซึ่งตัวแปรจะพร้อมใช้งานในชุดการสืบค้นปัจจุบันเท่านั้น (กระบวนงานที่เก็บไว้สคริปต์หรืออย่างอื่น) มันจะไม่สามารถใช้ได้ในชุดที่แตกต่างกันในเซสชั่นเดียวกัน
SET @@a = 'test';cf เลย dev.mysql.com/doc/refman/5.1/en/set-statement.html
@@คุณไม่สามารถตั้งตัวแปรเซสชั่นที่ผู้ใช้กำหนดโดยใช้ ตัวอย่างเช่นset@@my_var=1, set@@session.my_var=1และset session my_var=1จะไม่ทำงานเพราะmy_varไม่ได้เป็นระบบตัวแปรในขณะที่เราสามารถทำได้set@@big_tables=1, set@@session.big_tables=1และset session big_tables=1เพราะbig_tablesเป็นตัวแปรระบบ
var2เป็นตัวแปรที่ไม่มี@คำนำหน้า แต่ไม่ใช่ตัวแปรระบบ: มันเป็นตัวแปรขั้นตอน สิ่งนี้ได้รับอนุญาตเพราะมันอยู่ในขั้นตอนการจัดเก็บ (aka โปรแกรมที่เก็บไว้) นอกเหนือจากกระบวนงานที่เก็บไว้แล้วตัวแปรที่ไม่มี@คือตัวแปรของระบบ
MSSQL ต้องการให้ตัวแปรภายในโพรซีเดอร์เป็น DECLAREd และ folks ใช้ไวยากรณ์ @Variable (DECLARE @TEXT VARCHAR (25) = 'text') นอกจากนี้ MS อนุญาตให้ประกาศภายในบล็อกใด ๆ ในโพรซีเดอร์ซึ่งแตกต่างจาก mySQL ซึ่งต้องการ DECLARE ทั้งหมดที่ด้านบน
ในขณะที่ดีในบรรทัดคำสั่งฉันรู้สึกว่าการใช้ "set = @variable" ภายในกระบวนงานที่เก็บไว้ใน mySQL มีความเสี่ยง ไม่มีขอบเขตและตัวแปรอยู่ในขอบเขตของขอบเขต สิ่งนี้คล้ายกับตัวแปรใน JavaScript ที่ประกาศโดยไม่มีคำนำหน้า "var" ซึ่งก็คือเนมสเปซส่วนกลางและสร้างการชนและการเขียนทับที่ไม่คาดคิด
ฉันหวังว่าคนดี ๆ ที่ mySQL จะอนุญาตให้ DECLARE @Variable ที่ระดับบล็อกต่าง ๆ ภายในกระบวนงานที่เก็บไว้ สังเกตเห็นเครื่องหมาย @ (ที่เครื่องหมาย) คำนำหน้า @ sign ช่วยแยกชื่อตัวแปรออกจากชื่อคอลัมน์ตารางซึ่งมักจะเหมือนกัน แน่นอนหนึ่งสามารถเพิ่มคำนำหน้า "v" หรือ "l_" ได้เสมอ แต่เครื่องหมาย @ เป็นวิธีที่สะดวกและกระชับเพื่อให้ชื่อตัวแปรตรงกับคอลัมน์ที่คุณอาจกำลังดึงข้อมูลจากโดยไม่ต้องปิดบังมัน
MySQL เป็นเครื่องมือใหม่ในการจัดเก็บและทำงานได้ดีสำหรับรุ่นแรก มันจะเป็นเรื่องน่ายินดีที่ได้เห็นว่าพวกเขาใช้ภาษาที่ไหนและดูที่ฝั่งเซิร์ฟเวอร์ของภาษาที่พัฒนาแล้ว
โดยหลักการแล้วฉันใช้ UserDefinedVariables (เติมด้วย @) ภายในกระบวนงานที่เก็บไว้ สิ่งนี้ทำให้ชีวิตง่ายขึ้นโดยเฉพาะเมื่อฉันต้องการตัวแปรเหล่านี้ในกระบวนงานที่เก็บไว้สองกระบวนขึ้นไป เมื่อฉันต้องการตัวแปรเฉพาะภายใน ONE Stored Procedure เท่านั้นฉันใช้ System Variable (โดยไม่ต้องใส่เครื่องหมาย @)
@Xybo: ฉันไม่เข้าใจว่าทำไมการใช้ @variables ใน StoredProcedures จึงมีความเสี่ยง คุณช่วยอธิบาย "ขอบเขต" และ "ขอบเขต" ได้ง่ายขึ้นหน่อย (สำหรับฉันในฐานะมือใหม่)?
@@GLOBALตัวแปรต่าง ๆ ยิ่ง "ทั่วโลก" และร้ายกาจ พวกเขาข้ามช่วง! @variablesมี "ขอบเขตเซสชั่น" ดังนั้นอย่างน้อยพวกเขาก็ยังคงอยู่ในลักษณะนั้น ในภาษาปกติใด ๆ ที่เป็นสิ่งที่คุณเรียกว่าขอบเขต "ทั่วโลก" (เมื่อข้ามฟังก์ชัน ฯลฯ ) แนวคิด MySQL ของ "global" น่าจะเรียกว่า "universal" ซึ่งมันครอบคลุมขอบเขตของกระบวนการที่เรียกใช้ โดยทั่วไป "ทั่วโลก" ไม่สามารถทำได้ในภาษามาตรฐานเนื่องจากกระบวนการไม่แชร์พื้นที่หน่วยความจำ สิ่งนี้เกิดจากแนวโน้ม (vs volatile) ที่คงอยู่ของ SQL