ในคำถามอื่นที่ฉันโพสต์มีคนบอกฉันว่ามีความแตกต่างระหว่าง:
@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