2013-07-03 44 views
0

我注意到在mysql中,爲什麼要準備一個動態查詢,它需要我認爲是一個全局變量。有沒有辦法將變量的範圍限制在開始和結束語句之間?以下是我的測試腳本,它返回limitCnt變量的值10。存儲過程中的變量作用域?

delimiter // 
drop procedure if exists testProc// 
create procedure testProc() 
begin 
-- DECLARE limitCnt INT default 10; 
    SET @limitCnt = 10; 

    PREPARE stmt FROM 'SELECT * FROM `participants` LIMIT ?'; 
    EXECUTE stmt USING @limitCnt; -- the using part of the execute does not like the local variable 

    DEALLOCATE PREPARE stmt; 
end// 
call testProc()// 
select @limitCnt// 

drop procedure testProc// 
delimiter ; 

回答

1

如果你想使用局部變量那麼他們必須begin...end塊內範圍的,但是如果你有嵌套beginend阻止某些beginend塊內,則在「所謂的」父聲明的變量beginend區塊可從「所謂的」兒童beginend區塊訪問。請通讀http://dev.mysql.com/doc/refman/5.0/en/local-variable-scope.html

你在你的代碼做的是設置稱爲limitCnt會話變量是在你的程序中,因此你正在10作爲結果,當你做select @limitCnt訪問,可在任何地方。

要在您的begin...end塊中使用本地變量,請使用declare var_name var_type塊。

希望這回答你的問題。

0

根據MySQL 5.0 Documentation,您不能在EXECUTE ... USING語句中使用局部變量。請參閱以下有關如何使用聲明的文檔摘錄:

EXECUTE stmt_name 
[USING @var_name [, @var_name] ...] 

您必須使用@前綴。

0

沒有辦法繞過它。這是在MySql中設計的。

本地/存儲過程/存儲函數級變量

  1. 不能用於PREPARE聲明從
  2. 不能在你被稱爲事先準備好的聲明
  3. 不能使用傳遞一個參數值,以與EXECUTEUSING

PREPARE Syntax
...語句名稱不區分大小寫。 preparable_stmt是 字符串文字或用戶變量,其中包含SQL 語句的文本。 ...

...在存儲程序上下文準備不能引用存儲 過程或函數的參數或局部變量,因爲他們去 超出範圍的程序結束時和將不可用的聲明是在 聲明稍後在程序之外執行。 ...

EXECUTE Syntax
... 僅可通過用戶變量和USING 子句提供參數值,該子句必須與語句中參數 標記的數目完全相同。 ...

用戶變量有一個會話範圍。

現在,爲了解決您的問題,只需在使用它之前始終明確地將值設置爲用戶定義的變量。就像您分配默認值到@limitCnt一樣。

SET @limitCnt = 10; 

你也可以在你的存儲過程/存儲函數/腳本的末尾設置的NULL這種變量的值。

SET @limitCnt = NULL; 

這裏是SQLFiddle演示