2013-04-04 64 views
1

我刚刚将Doctrine DBAL安装到一个简单的测试PHP项目中,并创建了一个测试数据库,并且成功地发生了一些查询。包括使用位置参数和命名参数的查询,例如:Doctrine DBAL支持存储过程

echo '<br/>'; 
echo 'Simple SELECT WHERE Query using prepaired statements with positional paramaters:<br/>'; 
$Users_FirstName = 'Bill'; 
$sql = "SELECT * FROM users WHERE Users_FirstName = ?"; 
$stmt = $conn->prepare($sql); 
$stmt->bindValue(1, $Users_FirstName); 
$stmt->execute(); 
while ($row = $stmt->fetch()) { 
    echo $row['Users_FirstName'].'<br/>'; 
} 

echo '<br/>'; 
echo 'Simple SELECT WHERE Query using prepaired statements with named paramaters:<br/>'; 
$Users_FirstName = 'Bill'; 
$sql = "SELECT * FROM users WHERE Users_FirstName = :Users_FirstName"; 
$stmt = $conn->prepare($sql); 
$stmt->bindValue('Users_FirstName', $Users_FirstName); 
$stmt->execute(); 
while ($row = $stmt->fetch()) { 
    echo $row['Users_FirstName'].'<br/>'; 
} 

以上所有工作都没有问题。现在我正在尝试执行一个简单的存储过程。
目标数据库是MySQL 5.1.37。 存储的过程如下:

delimiter // 
DROP PROCEDURE IF EXISTS TestProcedure// 
CREATE PROCEDURE TestProcedure(INOUT TestParam VARCHAR(50)) 
BEGIN 
    SELECT CONCAT('Hi ', TestParam, '!!') INTO TestParam; 
END// 

我已经测试这在MySQL与下面的SQL代码:

delimiter ; 
SET @testParam = 'Bill'; 
CALL `TestProcedure`(@testParam); 
SELECT @testParam; 

它正确返回

'Hi Bill!!' 

结果现在我我试图使用Doctrine DBAL使用以下代码执行相同的存储过程PHP:

echo '<br/>'; 
echo 'Call Stored Procedure with INOUT Parm:<br/>'; 
$INOUTParam = 'Bill'; 
$sql = "CALL TestProcedure(?)"; 
$stmt = $conn->prepare($sql); 
$stmt->bindParam(1, $INOUTParam); 
$stmt->execute(); 
echo $INOUTParam; 

然而,这将返回以下错误:

呼叫存储过程INOUT帕姆: 异常 'PDOException' 与消息“SQLSTATE [42000]:语法错误或访问冲突:1414 OUT或INOUT参数1用于常规phptestdb.TestProcedure不是在[PATH REMOVED] \ Doctrine \ DBAL \ Statement.php中的BEFORE触发器中的变量或NEW伪变量:138堆栈跟踪:#0

我已经遍布整个地方搜索,找到任何使用带有INOUT或OUT参数的bindParam调用存储过程的示例。 有谁知道,如果教条主义支持存储过程,如果是这样你怎么称呼一个? 在他们的网站上找不到任何示例。

Regards,

Scott。

回答

0

原生SQL是一个选项,您甚至可以使用存储过程进行数据检索。

http://www.doctrine-project.org/blog/doctrine2-native-queries.html

或者你也可以在MySQL中使用触发器。触发器不会涉及Doctrine,symfony和PHP中的任何编码。只需存储过程。为了检查Doctrine的记录监听器或记录钩子。

http://docs.doctrine-project.org/projects/doctrine1/en/latest/index.html#record-listeners http://docs.doctrine-project.org/projects/doctrine1/en/latest/index.html#record-hooks

我希望它有助于..

+0

是的,我看到的帖子...但它仍然没有告诉我,如果学说支持存储的特效?原生SQL会提示它是特定于数据库的......我认为数据库抽象层的想法是,您不必更改所有查询来更改目标数据库。如果它们是本地查询,是不是没有达到目的? – user2109254 2013-04-04 06:37:35

+0

确定发现导致错误的潜在问题是由MySQL中的错误引起的。看到这里:http://stackoverflow.com/questions/118506/stored-procedures-mysql-and-php/4502524#4502524有一个链接到这里:http://bugs.mysql.com/bug.php?id = 11638,据我所知,它在2005年被识别出来,并且从未修复过MySQL 5.6.10,因为这是我测试过的最后一个版本。 – user2109254 2013-04-05 03:51:42

+0

@ user2109254,我不认为你会发现数据库不可能的抽象可能。存储过程/函数,视图等以db到db的完全不同的方式实现,使得它不太可能有任何抽象就足以表示它们。例如在postgres中,存储过程可以用作select语句中的子查询。在MySQL中,这不是必要的,而是要求你使用一个黑客来创建一个临时表来弥补查询。这就是人生。 – Shayne 2016-01-06 01:58:48