2016-01-24 106 views
0
PHP 5.6.11 
MySQL 5.6 
CentOS 7 (with MySQL 5.6) 

注意:这不是我的文字代码。我抽象了某些部分。执行时没有错误。没有数据写入contact表。PHP:为什么我的PDO准备语句不能将数据插入到我的表中?

我有一个名为通讯录...

CREATE TABLE IF NOT EXISTS `database`.`contact`(
`contact_id` VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Contact ID', 
`firstname` VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'First name.', 
`lastname` VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Last name.', 
`email` VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'E-mail address.', 
`phone` VARCHAR(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Telephone number', 
`country_code` VARCHAR(7) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Country code number', 
`extension` VARCHAR(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Telephone extension', 
`company` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Company affiliation.', 
`address` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Street Address.', 
`city` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'City.', 
`state` VARCHAR(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'State.', 
`zip` VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Zip code.', 
`country` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Country.', 
`phone_type` ENUM('Cellular', 'Landline') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Telephone type', 
`time_to_contact` ENUM('A.M.', 'P.M.') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Morning or Afternoon', 
`contact_pref` ENUM('Email', 'Phone', 'Mail') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Contact preference', 
`job_location` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Jobsite location', 
`news_subscribed` ENUM('N', 'Y') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Contact subscribed to newsletter.', 
`news_subs_token` VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Used when subscribing to the newsletter.', 
`news_unsub_token` VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Used when unsubscribing to the newsletter.', 
`message_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Time of last message.', 
CONSTRAINT `contactconstr01` PRIMARY KEY (`contact_id`)) 
ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci COMMENT 'Contacts (external) table.'; 

...我想用这个存储过程,嵌入准备好的声明中,插入记录。

CREATE DEFINER = 'blahfoobar'@'localhost' 
PROCEDURE `database`.add_contact_sp(
      IN contact_id VARCHAR(32), 
      IN firstname VARCHAR(30), 
      IN lastname VARCHAR(30), 
      IN email VARCHAR(128), 
      IN phone VARCHAR(12), 
      IN country_code VARCHAR(7), 
      IN extension VARCHAR(5), 
      IN company VARCHAR(50), 
      IN address VARCHAR(100), 
      IN city VARCHAR(50), 
      IN st VARCHAR(6), 
      IN zip VARCHAR(10), 
      IN country VARCHAR(50), 
      IN phone_type VARCHAR(8), 
      IN time_to_contact VARCHAR(4), 
      IN contact_preference VARCHAR(5), 
      IN job_location VARCHAR(100), 
      IN news_subscribed VARCHAR(1), 
      IN news_sub_token VARCHAR(60), 
      IN news_unsub_token VARCHAR(60)) 
    COMMENT 'Insert new contact record.' 
LANGUAGE SQL 
DETERMINISTIC 
MODIFIES SQL DATA 
     SQL SECURITY DEFINER 
    BEGIN 
      SET @id  = contact_id; 
      SET @fName = firstname; 
      SET @lName = lastname; 
      SET @eMail = email; 
      SET @p  = phone; 
      SET @cc  = country_code; 
      SET @ext  = extension; 
      SET @comp = company; 
      SET @addr = address; 
      SET @c  = city; 
      SET @s  = st; 
      SET @zCode = zip; 
      SET @coun = country; 
      SET @pType = phone_type; 
      SET @ttc  = time_to_contact; 
      SET @cPref = contact_preference; 
      SET @jLoc = job_location; 
      SET @news = news_subscribed; 
      SET @nSubT = news_subs_tokens; 
      SET @nUnsubT = news_unsub_token; 

      PREPARE `insert_contact_stmt` FROM 
        'INSERT INTO `contact` 
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; 
      EXECUTE `insert_contact_stmt` USING @id, @fName, @lName, @eMail, @p, @cc, @ext, @comp, @addr, @c, @s, @zCode, @coun, @pType, @ttc, @cPref, @jLoc, @news, @nSubT, @nUnsubT; 
      DEALLOCATE PREPARE `insert_contact_stmt`; 
     END// 

安全设置的样子....

GRANT INSERT ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost'; 
GRANT SELECT ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost'; 
GRANT UPDATE ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost'; 
GRANT DELETE ON TABLE `database`.`contact` TO 'blahfoobar'@'localhost'; 

GRANT EXECUTE ON PROCEDURE `database`.`add_contact_sp` TO 'blahfoobar'@'localhost', 'blahblahblah'@'localhost'; 

...其中 'blahblahblah' @ 'localhost' 的代表,使PDO连接期间到MySQL服务器的连接实际用户阶段(未示出)。

我的PHP,子类Contact(超一流Person)的保护方法如下所示,其中顶部附近$db对象是一个PDO连接的包装对象。

protected function insert() 
{ 
    try 
    {    
     $this->db->startTransaction(); 

     $stmt = $this->db->prepare('add_contact_sp(:contact_id, :firstname, :lastname, :email, :phone, :country_code, :extension, :company, :address, :city, :state, :zip, :country, :phone_type, :time_to_contact, :contact_pref, :job_location, :news_subscribed, :news_sub_token, :news_unsub_token'); 

     if($stmt instanceof PDOStatement) 
     { 
      //Where $stmt is passed by reference. 

      $this->db->bindParam($stmt, ':contact_id', $this->id); 
      $this->db->bindParam($stmt, ':firstname', $this->firstname); 
      $this->db->bindParam($stmt, ':lastname', $this->lastname); 
      $this->db->bindParam($stmt, ':email', $this->email); 
      $this->db->bindParam($stmt, ':phone', $this->phone); 
      $this->db->bindParam($stmt, ':country_code', $this->countryCode); 
      $this->db->bindParam($stmt, ':extension', $this->extension); 
      $this->db->bindParam($stmt, ':company', $this->company); 
      $this->db->bindParam($stmt, ':address', $this->address); 
      $this->db->bindParam($stmt, ':city', $this->city); 
      $this->db->bindParam($stmt, ':state', $this->state); 
      $this->db->bindParam($stmt, ':zip', $this->zip); 
      $this->db->bindParam($stmt, ':country', $this->country); 
      $this->db->bindParam($stmt, ':phone_type', $this->phoneType);  
      $this->db->bindParam($stmt, ':time_to_contact', $this->timeToContact); 
      $this->db->bindParam($stmt, ':contact_pref', $this->contactPref); 
      $this->db->bindParam($stmt, ':job_location', $this->jobLocation); 
      $this->db->bindParam($stmt, ':news_subscribed', $this->newsSubscribed); 
      $this->db->bindParam($stmt, ':news_sub_token', $this->newsSubToken); 
      $this->db->bindParam($stmt, ':news_unsub_token', $this->newsUnsubToken); 

      if(!$stmt->execute()) 
      { 
       print_r($stmt->errorInfo(), true); //Just for debugging. 
      } 
      else 
      { 
       $this->db->commit(); 
      } 
     } 
     else 
     { 
      throw new PDOException("Failed to prepare the PDO statement."); 
     } 
    } 
    catch(Exception $e) 
    { 
     $this->db->rollback(); 
     return false; 
    } 

    return true; 
} 

没有错误。没有数据写入数据库。没有。是否有可能使用嵌入了预准备语句的MySQL存储过程执行PDO事务?

这是我的数据库连接选项的要求。

$options = [ 
       PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
       PDO::ATTR_PERSISTENT => true, 
       PDO::ATTR_EMULATE_PREPARES => false, 
       PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 
       PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'utf8mb4\' COLLATE \'utf8mb4_unicode_ci\'' 
      ]; 
+2

我建议你看着写[一个最小的完整的例子(http://stackoverflow.com/help/mcve),并给予明确的问题陈述:你是怎么想到要发生了什么事情,而不是。现在,有太多的细节很难找到真正的问题。 – IMSoP

+0

@IMSoP它只是一张桌子。然后,一个存储过程将记录插入到该表中。接下来,安全设置。最后,调用存储过程的PHP。像这样看,这不是一个复杂的演示。如果你看过一个,你就会看到它们。不过,我没有得到任何错误。奇怪。 – Melinda

+0

@AnonyRutledge您是否认为尝试绑定太多参数可能存在问题? – Melinda

回答

1

您的PDO :: prepare语句中还存在其他错误,但是这是第一个错误。您在PREPARE语句结尾缺少括号。它应该看起来像这样。其余的与你的参数和绑定顺序有关。你有20个参数。确保它们处于正确的相应顺序。现在,他们不是。

$stmt = $this->db->prepare('add_contact_sp(:contact_id, :firstname, :lastname, :email, :phone, :country_code, :extension, :company, :address, :city, :state, :zip, :country, :phone_type, :time_to_contact, :contact_pref, :job_location, :news_subscribed, :news_sub_token, :news_unsub_token)'); 
+0

THANKYOU !!!!!你是正确的,改变参数的顺序,并添加缺少的括号。感谢您对此深入研究! – Melinda

相关问题