จะประกาศตัวแปรใน MySQL ได้อย่างไร?


386

วิธีการประกาศตัวแปรใน MySQL เพื่อให้แบบสอบถามที่สองของฉันสามารถใช้งานได้อย่างไร

ฉันต้องการเขียนสิ่งที่ชอบ:

SET start = 1;
SET finish = 10;

SELECT * FROM places WHERE place BETWEEN start AND finish;

อย่าลืมว่าคุณอาจต้อง "อนุญาตให้ผู้ใช้ตัวแปร = จริง"
Steve Smith

คำตอบ:


636

มีตัวแปรหลักสามประเภทใน MySQL:

  1. ตัวแปรที่ผู้ใช้กำหนด (นำหน้าด้วย@):

    คุณสามารถเข้าถึงตัวแปรที่ผู้ใช้กำหนดเองโดยไม่ต้องประกาศหรือเริ่มต้น หากคุณอ้างถึงตัวแปรที่ยังไม่ได้เริ่มต้นมันมีค่าNULLและชนิดของสตริง

    SELECT @var_any_var_name

    คุณสามารถเริ่มต้นตัวแปรโดยใช้SETหรือSELECTคำสั่ง:

    SET @start = 1, @finish = 10;    

    หรือ

    SELECT @start := 1, @finish := 10;
    
    SELECT * FROM places WHERE place BETWEEN @start AND @finish;

    ตัวแปรผู้ใช้สามารถกำหนดค่าจากชุดข้อมูลชนิด จำกัด : จำนวนเต็ม, ทศนิยม, ทศนิยม, ทศนิยมหรือสตริงไบนารี่หรือไม่ใช่ไบนารีหรือค่า NULL

    ตัวแปรที่ผู้ใช้กำหนดเป็นแบบเฉพาะเซสชัน นั่นคือตัวแปรผู้ใช้ที่กำหนดโดยลูกค้ารายหนึ่งไม่สามารถมองเห็นหรือใช้โดยลูกค้ารายอื่น

    พวกเขาสามารถนำมาใช้ในSELECTคำสั่งโดยใช้ขั้นสูง MySQL เทคนิคตัวแปรของผู้ใช้

  2. ตัวแปรท้องถิ่น (ไม่มีคำนำหน้า):

    จำเป็นต้องประกาศตัวแปรท้องถิ่นDECLAREก่อนการใช้งาน

    สามารถใช้เป็นตัวแปรโลคัลและพารามิเตอร์อินพุตภายในโพรซีเดอร์ที่เก็บ:

    DELIMITER //
    
    CREATE PROCEDURE sp_test(var1 INT) 
    BEGIN   
        DECLARE start  INT unsigned DEFAULT 1;  
        DECLARE finish INT unsigned DEFAULT 10;
    
        SELECT  var1, start, finish;
    
        SELECT * FROM places WHERE place BETWEEN start AND finish; 
    END; //
    
    DELIMITER ;
    
    CALL sp_test(5);

    หากข้อจะหายไปค่าเริ่มต้นคือDEFAULTNULL

    ขอบเขตของตัวแปรท้องถิ่นคือBEGIN ... ENDบล็อกที่มีการประกาศ

  3. ตัวแปรระบบเซิร์ฟเวอร์ (นำหน้าด้วย@@):

    เซิร์ฟเวอร์ MySQL รักษาตัวแปรระบบจำนวนมากที่กำหนดค่าเป็นค่าเริ่มต้น พวกเขาสามารถเป็นชนิดGLOBAL, หรือSESSIONBOTH

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

    เพื่อดูค่าที่ใช้ในปัจจุบันโดยเซิร์ฟเวอร์ที่ใช้ใช้คำสั่งหรือSHOW VARIABLESSELECT @@var_name

    SHOW VARIABLES LIKE '%wait_timeout%';
    
    SELECT @@sort_buffer_size;

    พวกเขาสามารถตั้งค่าเมื่อเริ่มต้นเซิร์ฟเวอร์โดยใช้ตัวเลือกในบรรทัดคำสั่งหรือในไฟล์ตัวเลือก ส่วนใหญ่สามารถเปลี่ยนแปลงได้แบบไดนามิกในขณะที่เซิร์ฟเวอร์กำลังทำงานโดยใช้SET GLOBALหรือSET SESSION:

    -- Syntax to Set value to a Global variable:
    SET GLOBAL sort_buffer_size=1000000;
    SET @@global.sort_buffer_size=1000000;
    
    -- Syntax to Set value to a Session variable:
    SET sort_buffer_size=1000000;
    SET SESSION sort_buffer_size=1000000;
    SET @@sort_buffer_size=1000000;
    SET @@local.sort_buffer_size=10000;

3
=โอเปอร์เรเตอร์ไม่ได้ผลสำหรับฉัน มันใช้งานได้ดีเมื่อฉันใช้:=โอเปอเรเตอร์
divinedragon

24
=ผู้ประกอบการใช้งานได้เฉพาะในSETข้อ สำหรับการกำหนดค่าให้กับตัวแปรในSELECTเคียวรีคุณสามารถใช้:=โอเปอเรเตอร์เช่นSELECT @start := 1
Omesh

2
คุณช่วยอธิบายให้ชัดเจนได้ไหมว่าสิ่งนี้หมายความว่าอย่างไร: "ไม่จำเป็นต้องประกาศตัวแปรที่ผู้ใช้กำหนดเองซึ่งระบุด้วยคำนำหน้า @"
billynoah

3
@billynoah ฉันถือว่ามันหมายความว่าตัวแปรเซสชันที่กำหนดโดยผู้ใช้ (ซึ่งเริ่มต้นด้วย @) ไม่จำเป็นต้องมีการประกาศอย่างชัดเจน คุณสามารถมอบหมายให้พวกเขาได้ทันทีราวกับว่าพวกเขาได้รับการประกาศแล้ว
jobo3208

2
และคุณสามารถกำหนดตัวแปรที่มีผลลัพธ์ของคำสั่ง select ดังนี้: SET @subscriptionId = (เลือก SubscriptionId จากผู้ใช้ที่ emailAddress='ac@tmail.com ');
ผู้เผยพระวจนะซอฟต์แวร์

28

ตลาดหลักทรัพย์

SET @var_name = value 

หรือ

SET @var := value

ทั้งผู้ประกอบการ=และ=ได้รับการยอมรับ


เลือก

SELECT col1, @var_name := col2 from tb_name WHERE "conditon";

หากพบหลายชุดเร็กคอร์ดเฉพาะค่าสุดท้ายใน col2 คือ keep (override);

SELECT col1, col2 INTO @var_name, col3 FROM .....

ในกรณีนี้ผลลัพธ์ของการเลือกไม่มีค่า col2


ใช้ทั้งสองวิธี

- TRIGGER_BEFORE_INSERT --- การตั้งค่าคอลัมน์จากการคำนวณ

...
SELECT count(*) INTO @NR FROM a_table WHERE a_condition;
SET NEW.ord_col =  IFNULL( @NR, 0 ) + 1;
...

3
ความแตกต่างระหว่าง=และ:=คืออะไร?
Koray Tugay

2
ฉันเดาว่าสำหรับ mysql SELECT ไวยากรณ์จำเป็นต้องแยกความหมายของ = (การเปรียบเทียบ) จาก: = (
asign

1
ในบางกรณีค่าที่เหลือในตัวแปรอาจไม่ตรงกับแถวสุดท้ายที่ส่งคืน ตัวอย่างเช่นSELECT DISTINCT IFNULL(@var:=Name,'unknown') FROM Customers ORDER BY <some non-indexed expression> LIMIT 10ปรากฏขึ้นเพื่อประเมินการกำหนดตัวแปรก่อนที่จะดำเนินการตามลำดับเพื่อให้ค่าที่ส่งคืนของ @var อาจไม่เกี่ยวข้องกับแถวใด ๆ ที่ส่งคืน แม้ว่าเอกสารจะไม่พูดภายใต้เงื่อนไขว่าสิ่งนี้สามารถเกิดขึ้นได้
Doin


3

ตัวแปรประเภทต่างๆ:

  • ตัวแปรโลคัล (ซึ่งไม่ได้นำหน้าด้วย @) ถูกพิมพ์อย่างยิ่งและกำหนดขอบเขตให้กับบล็อกโปรแกรมที่เก็บไว้ซึ่งถูกประกาศ โปรดทราบว่าตามเอกสารภายใต้ไวยากรณ์ DECLARE :

DECLARE ได้รับอนุญาตเฉพาะในคำสั่งผสม BEGIN ... END และจะต้องอยู่ที่จุดเริ่มต้นก่อนที่จะมีคำสั่งอื่นใด

  • ตัวแปรผู้ใช้ (ซึ่งนำหน้าด้วย @) จะถูกพิมพ์แบบหลวม ๆ และกำหนดขอบเขตให้กับเซสชัน โปรดทราบว่าพวกเขาไม่ต้องการหรือไม่สามารถประกาศได้ - เพียงแค่ใช้พวกเขาโดยตรง

ดังนั้นหากคุณกำหนดโปรแกรมที่เก็บไว้และต้องการ "ตัวแปรท้องถิ่น" คุณจะต้องวางอักขระ @ และตรวจสอบให้แน่ใจว่าคำสั่ง DECLARE ของคุณอยู่ที่จุดเริ่มต้นของบล็อกโปรแกรมของคุณ มิฉะนั้นหากต้องการใช้ "ตัวแปรผู้ใช้" ให้วางคำสั่ง DECLARE

นอกจากนี้คุณจะต้องล้อมรอบแบบสอบถามของคุณในวงเล็บเพื่อดำเนินการเป็นแบบสอบถามย่อย:

SET @countTotal = (เลือก COUNT (*) จาก nGrams);

มิฉะนั้นคุณสามารถใช้ SELECT ... เข้าสู่:

เลือก COUNT (*) เข้าสู่ @countTotal จาก nGrams;


1

สำหรับบุคคลใดก็ตามที่ใช้ @variable ในฟังก์ชัน concat_ws เพื่อรับค่าที่ต่อกันอย่าลืมกำหนดค่าเริ่มต้นใหม่ด้วยค่าว่าง มิฉะนั้นจะสามารถใช้ค่าเก่าสำหรับเซสชันเดียวกัน

Set @Ids = '';

select 
  @Ids := concat_ws(',',@Ids,tbl.Id),
  tbl.Col1,
  ...
from mytable tbl;


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