2013-07-03 66 views
0

我正試圖使存儲過程從用戶表中返回行。 我使用pg_函數從php中調用它:pg_prepare($conn, $id, 'SELECT user_read_all()')pg_execute($conn, $id, array())。可悲的是我沒有PDO只爲MySQL。php-plpgsql調用存儲過程並獲取結果集

我試着用這個代碼,但我有多個問題:

CREATE OR REPLACE FUNCTION user_read_all() 
    RETURNS table(user_id INT, user_name VARCHAR, user_email VARCHAR) 
AS 
    $BODY$ 
    BEGIN 
    return query SELECT 
     user_id, user_name, user_email 
    FROM 
     user; 
    END; 
$BODY$ 
LANGUAGE 'plpgsql' VOLATILE; 

通過pg_fetch,結果是array('test' => string(...))而不是array(user_id => 1, user_name => '', user_email => '')。我想切斷user_前綴太多,但我得到這個語法錯誤:

CREATE OR REPLACE FUNCTION user_read_all() 
    RETURNS table(id INT, name VARCHAR, email VARCHAR) 
AS 
    $BODY$ 
    BEGIN 
    return query SELECT 
     user_id as id, user_name as name, user_email as email 
    FROM 
     user; 
    END; 
$BODY$ 
LANGUAGE 'plpgsql' VOLATILE; 

;-(

是否有可能與PLPGSQL做到這一點

我的目標是使存儲過程的唯一接口,但我嚴重懷疑...與MySQL這是很容易的,但MySQL已經比pgsql的只有有限的功能...

CREATE PROCEDURE `user_read_all`() 
BEGIN 
    SELECT `user_id` AS `id`, `user_name` AS `name`, `user_email` AS `email` FROM `user` 
    ORDER BY `user_id` DESC; 
END; 

所以,問題是如何修復存儲過程和PHP結果集?

溶液

CREATE FUNCTION test() 
    RETURNS TABLE (id INT, name VARCHAR, email VARCHAR) 
AS 
    $BODY$ 
    BEGIN 
    return QUERY SELECT 
     "user".user_id, "user".user_name, "user".user_email 
    FROM 
     "user"; 
    END; 
$BODY$ 
LANGUAGE 'plpgsql' VOLATILE; 

SELECT * FROM test(); 
在PHP側

回答

1

它返回一個表中的功能,所以你必須把它像一個表:

SELECT * FROM user_read_all(); 

無論是在PSQL嘗試,並在輸出仔細看。您的原始方式返回一組行類型,FROM方式返回列。

關於語法錯誤 - 你不給它,所以我不能說。

儘管避免使用列/表名的保留字。比如「類型」,「名稱」,「用戶」等 - 請參閱文檔瞭解詳情。

+0

部分解決了這個問題,現在我用剛空值取有單排...字符串是空值連接起來......用戶表不爲空,當我使用它引用我得到了同樣的結果... – inf3rno

+0

我必須使用「user」.user_id而不是簡單的user_id。現在它返回結果,但我想返回它作爲id,名稱,電子郵件,而不是作爲user_id,user_name,user_email ...我試圖爲每行添加「as」,但結果是語法錯誤... – inf3rno

1

這裏真正的問題是,user是PostgreSQL中保留關鍵字除了current_user,相反到MySQL,它只是current_user被保留。

函數的第一種形式在創建時沒有產生語法錯誤,因爲plpgsql解析器沒有嘗試識別列。儘管如此,它在運行時肯定會失敗。如果php代碼沒有發出任何錯誤,那麼它的錯誤檢測代碼可能缺乏。

在PG

user返回的登錄名,並且可以使用,如果它是一個表: SELECT * FROM user,或作爲一個獨立的表達式:SELECT user,[other columns] FROM table...

如果你仍然想使用它作爲表名,你必須用雙引號將它括起來:SELECT * FROM "user"(假設它被創建爲小寫字母。雙引號的另一個影響是它打開了精確的大小寫匹配)。

此外,對於像剛剛運行查詢的函數,您不希望使用過程式plpgsql語言,而是更高效的SQL語言。在SQL函數是:

CREATE OR REPLACE FUNCTION user_read_all() 
    RETURNS table(id INT, name VARCHAR, email VARCHAR) 
AS 
    $BODY$ 
    SELECT 
     user_id as id, user_name as name, user_email as email 
    FROM 
     "user"; 
    $BODY$ 
LANGUAGE sql; 

您可以用SELECT user_read_all()調用它,但SELECT * from user_read_all()可能是你想要拿到3分適當列什麼。

+0

「對於像你這樣只運行查詢的函數,你也不希望使用過程式plpgsql語言,而是更高效的sql語言。」 - 是的,我可以做到簡單的SQL,但我正在學習plpgsql ... – inf3rno

+0

順便說一句,與plpgsql相同,並返回查詢引發語法錯誤... – inf3rno

+0

該報價並不真正由用戶計數。我的意思是我現在得到了與空值相同的結果。用戶表不是空的... select * from是向前邁進的一步... – inf3rno

-2
$get_test = "SELECT test()"; 
    $test = pg_query($db_server, $get_test); 
    while ($row = pg_fetch_array($test)) { 
     $value = $row[0]; 
    } 

    echo $value; 
+1

一些解釋會有很大幫助。 –

+0

雖然這個答案可能是正確和有用的,但如果您在解釋問題的過程中包含一些解釋並解釋它是如何有助於解決問題的話,那麼這是首選。如果存在導致其停止工作並且用戶需要了解其曾經工作的變化(可能不相關),這在未來變得特別有用。 –

相關問題