在另外一個問題中,我發佈了一我的告訴我,二者之間是有區別的: sql
@variable
和: 數據庫
variable
在MySQL中。 他還提到了MSSQL如何具備批處理範圍,而MySQL如何具備會話範圍。 有人能夠爲我詳細說明嗎? 服務器
在MySQL中, @variable
表示用戶定義的變量 。 您能夠定義本身的。 session
SET @a = 'test'; SELECT @a;
在存儲程序以外,不帶@
的variable
是系統變量 ,您沒法定義本身。 ui
此變量的範圍是整個會話。 這意味着,儘管您與數據庫的鏈接存在,但仍能夠使用該變量。 spa
這與MSSQL相反,在MSSQL中,變量僅在當前的查詢批次(存儲過程,腳本或其餘)中可用。 在同一會話中,將不能以其餘批次使用它。 .net
MySQL
具備用戶定義變量的概念。 命令行
它們是鬆散類型的變量,能夠在會話的某處初始化,並保持其值直到會話結束。 code
它們以@
符號開頭,例如: @var
ip
您能夠使用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
;這些「會話變量」 」與特定於會話的用戶定義變量無關。)
原則上,我在存儲過程當中使用UserDefinedVariables(以@開頭)。 這使工做變得更輕鬆,尤爲是當我在兩個或多個存儲過程當中須要這些變量時。 只是當我僅須要一個存儲過程當中的變量時,我才使用系統變量(不帶@)。
@Xybo:我不明白爲何在StoredProcedures中使用@variables應該會有風險。 您能簡單解釋一下「範圍」和「邊界」嗎(對我來講,這是一個新手)?
MSSQL要求過程當中的變量爲DECLAREd,人們使用@Variable語法(DECLARE @TEXT VARCHAR(25)='text')。 此外,MS容許在過程的任何塊中進行聲明,這與mySQL不一樣,mySQL要求在頂部使用全部DECLARE。
雖然在命令行上不錯,但我認爲在mySQL的存儲過程當中使用「 set = @variable」是有風險的。 沒有範圍,變量跨越範圍邊界。 這相似於在JavaScript中聲明的不帶「 var」前綴的變量,這些變量將成爲全局命名空間併產生意外的衝突和覆蓋。
我但願mySQL的優秀人士將容許在存儲過程的各個塊級別使用DECLARE @Variable。 注意@(在符號處)。 @符號前綴有助於將變量名與表列名分開-由於它們一般是相同的。 固然,老是能夠添加「 v」或「 l_」前綴,可是@符號是一種方便且簡潔的方法,能夠使變量名與您要從中提取數據的列匹配而不會破壞數據。
MySQL是存儲過程的新手,他們在第一個版本中作得很好。 很高興看到他們在這裏採用什麼形式,並觀察該語言在服務器端的各個方面。