2012-12-04 53 views
4

我寫過一個存儲過程函數來從表中獲取名稱。麻煩的是,我想作爲參數傳遞的表名(有幾個不同的表,我需要使用該功能):存儲過程函數中的動態表名

DELIMITER $$ 

CREATE DEFINER=`root`@`localhost` FUNCTION `getName`(tableName VARCHAR(50), myId INT(11)) RETURNS VARCHAR(50) 

    begin 

    DECLARE myName VARCHAR(50); 

    SELECT 
    'name' INTO myName 
    FROM 
    tableName 
    WHERE 
    id=myId; 

    RETURN myName; 

    end 

,因爲它使用的變量名這種方法有一個錯誤「 tableName「而不是變量的實際值。

我可以解決此問題在程序使用CONCAT這樣的:

SET @GetName = CONCAT(" 
    SELECT 
     'name' 
    FROM 
     ",tableName," 
    WHERE 
     id=",myId,"; 
    "); 

    PREPARE stmt FROM @GetName; 
    EXECUTE stmt; 

...但是,當我嘗試做一個功能我得到一個消息說:

動態SQL沒有包括在存儲函數或觸發允許

我試圖用程序取而代之,但我無法讓它只返回一個值,就像一個函數一樣。

所以,任何人都可以看到一種方法來解決這個問題。它真的非常基礎。

+1

如何使用'OUT'或'INOUT'參數覆蓋您的返回值? – eisberg

回答

12

如果要使用標識符buld SQL語句,則需要使用預準備語句;但準備好的語句不能在函數中使用。所以,你可以創建一個帶有OUT參數的存儲過程 -

CREATE PROCEDURE getName 
(IN tableName VARCHAR(50), IN myId INT(11), OUT myName VARCHAR(50)) 
BEGIN 

    SET @GetName = 
    CONCAT('SELECT name INTO @var1 FROM ', tableName, ' WHERE id=', myId); 
    PREPARE stmt FROM @GetName; 
    EXECUTE stmt; 

    SET myName = @var1; 
END 

使用的例子 -

SET @tableName = 'tbl'; 
SET @myId = 1005; 
SET @name = NULL; 
CALL getName(@tableName, @myId, @name); 
SELECT @name; 
+0

你好 我想爲下面的嵌套查詢製作過程。 DELETE FROM TABLENAME WHERE'id' NOT IN(SELECT 'refer_id' FROM'hrs_demo_data_references' WHERE 'demo_data_records_id' IN ( SELECT'id' FROM'hrs_demo_data_records' WHERE 'table_name' =「TABLENAME '和'refer_id' IN ( SELECT'id' FROM TABLENAME WHERE'company_details_id' = 1 ) ) ) 在這種tableNa我會充滿活力。你可以幫幫我嗎? –

0

我同意,我們可以使用存儲過程的OUT參數,但如果我們創建這個存儲過程對於Web應用程序沒有。其他實例將使用相同的過程並更改此OUT變量。在mysql中,OUT變量就像全局變量。一個實例會改變它的值,在我們的程序讀取它的值之前,它會被另一個實例在web上改變。另一種解決方案是什麼?我面臨同樣的問題,我想要返回值+我想使用動態表名。