【问题标题】:Php Mysql Stored Procedure IN OUTphp Mysql 存储过程 IN OUT
【发布时间】:2011-06-23 22:39:46
【问题描述】:

案例:存储过程看起来像:

DROP PROCEDURE IF EXISTS `XofferCommon`.`getCdpc`;<br>
DELIMITER $$<br>
CREATE PROCEDURE `XofferCommon`.`getCdpc` (IN in_city_ID INT, OUT out_country_id INT, OUT out_district_id INT, OUT out_provence_id INT, OUT out_city_id INT)<br>
BEGIN<br>
DECLARE city_ID INT DEFAULT in_city_ID;<br>
SELECT t.Id, d.Id, p.Id, c.Id INTO out_country_id, out_district_id, out_provence_id, out_city_id FROM ((tblCity AS c INNER JOIN tblProvence AS p ON c.tblProvence_Id = p.ID) INNER JOIN tblDistrict AS d ON p.tblDistrict_Id = d.ID) INNER JOIN tblCountry AS t ON -d.tblCountry_Id = t.ID WHERE c.id = city_ID;<br>
END$$<br>
DELIMITER ;<br><br>
<br>---------------------------------------------------
Input: int referring to in_city_id<br>
Output: 4 x int country district provence and city id's<br>
---------------------------------------------------<br>

Php:我想调用该过程并将 4 个返回的对象存储到 4 个变量中

if ($res = $mysqli->query( 'CALL getCdpc(1321,@co,@di,@pr,@ci);SELECT @co,@di,@pr,@ci'))<br>
{<br>
    while($row = $res->fetch_object())<br>
    {<br>
        print($row);<br>
    }<br>
    $res->close();<br>
}<br>
else<br>
{<br>
    print "<br> no result given <br>";<br>
}<br>
<br>
Result:<br>
-------<br>

我总是返回零行

<br>
<br>
More info:<br>
----------<br>
in mysql sql the results get returned when I do:<br>
->call xoffercommon.getCdpc(1321,@co,@di,@pr,@ci);<br>
->select @co,@di,@pr,@ci;<br>
=> @co @di @pr @ci<br>
   1   2   3   4<br>
<br>
Question:<br>
---------<br>

我是否必须运行 2 个查询、一个对过程的调用和一个对该结果的选择?
有没有办法在一行中运行它?
...请帮助我找不到解决问题的方法,已经尝试在程序中返回,但这仅在函数中允许。 已经 2 周过去了...通过阅读/反复试验学到了很多东西 ;-),但没有任何东西可以破解这个案例....

【问题讨论】:

    标签: php mysql mysqli procedure


    【解决方案1】:

    当您可以简单地返回结果集时,不确定为什么要传递 4 个变量。这也将避免您每次想要扩展您输出的数据时都必须更改存储过程接口。

    MySQL

    drop procedure if exists XofferCommon.getCdpc;
    
    delimiter #
    
    create procedure XofferCommon.getCdpc
    (
    in p_city_id int unsigned
    )
    begin
        select
         t.Id as country_id, 
         d.Id as district_id, 
         p.Id as provence_id, 
         c.Id as city_id
        from 
         tblCity c
         inner join tblProvence p on c.tblProvence_Id = p.Id 
         inner join tblDistrict d on p.tblDistrict_Id = d.Id 
         inner join tblCountry t on d.tblCountry_Id = t.Id 
        where
         c.Id = p_city_id;
    end#
    
    delimiter ;
    

    PHP

    <?php
    
    ob_start(); 
    
    try
    {
        $db = new mysqli("localhost", "foo_dbo", "pass", "foo_db", 3306);
    
        if ($db->connect_errno) 
            throw new exception(sprintf("Could not connect: %s", $db->connect_error));
    
        $sqlCmd = sprintf("call getCdpc(%d)", 1);
    
        $result = $db->query($sqlCmd);
    
        if(!$result) throw new exception(sprintf("Invalid query : %s", $sqlCmd));
    
        if($result->num_rows <= 0){
            echo "no records found !";
        }
        else{
            $row = $result->fetch_assoc();
            echo sprintf("country_id = %d district_id = %d, provence_id = %d, city_id = %d",
                $row["country_id"],$row["district_id"],$row["provence_id"],$row["city_id"]);
        }
        $db->next_result(); 
        $result->close();
    }
    catch(exception $ex)
    {
        ob_clean(); 
        echo sprintf("zomg borked - %s", $ex->getMessage());
    }
    
    if(!$db->connect_errno) $db->close();
    ob_end_flush();
    ?>
    

    清理模式也是值得的,这样您的键就有更合适的整数数据类型(并非所有内容都是 4 字节的有符号整数),并避免混合您似乎为同一事物选择的字段名,即Id、ID、City_Id、City_ID 等将避免所有不必要的别名!

    http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html

    MySQL 修改架构

    • 删除了 tbl 表名前缀
    • 为您的键选择更合适的整数数据类型
    • 重命名您的关键字段,使其保持一致,即 city_id

    表格

    drop table if exists country;
    create table country
    (
    country_id tinyint unsigned not null auto_increment primary key -- 0 to 255 countries;
    )
    engine=innodb;
    
    drop table if exists district;
    create table district
    (
    district_id smallint unsigned not null auto_increment primary key, -- 0 to 65535 districts
    country_id tinyint unsigned not null
    )
    engine=innodb;
    
    drop table if exists provence;
    create table provence
    (
    provence_id smallint unsigned not null auto_increment primary key, - 0 to 65535 provences
    district_id smallint unsigned not null
    )
    engine=innodb;
    
    drop table if exists city;
    create table city
    (
    city_id mediumint unsigned not null auto_increment primary key, - 0 to 16777215 cities
    provence_id smallint unsigned not null
    )
    engine=innodb;
    

    存储过程

    drop procedure if exists getCdpc;
    
    delimiter #
    
    create procedure getCdpc
    (
    in p_city_id mediumint unsigned
    )
    begin
        select
         t.country_id, 
         d.district_id, 
         p.provence_id, 
         c.city_id
        from 
         city c
         inner join provence p on c.provence_id = p.provence_id
         inner join district d on p.district_id = d.district_id
         inner join country t on d.country_id = t.country_id
        where
         c.city_id = p_city_id;
    end#
    
    delimiter ;
    

    希望这会有所帮助:)

    【讨论】:

      【解决方案2】:

      usemulti_query 函数

      $mysqli->multi_query($query)
      

      看例子

      PHP + MySql + Stored Procedures, how do I get access an "out" value?

      【讨论】:

        猜你喜欢
        • 2011-07-29
        • 1970-01-01
        • 2010-09-08
        • 2021-05-18
        • 1970-01-01
        • 2013-03-22
        • 1970-01-01
        • 2020-01-09
        相关资源
        最近更新 更多