Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在具有Symfony和DORITOR的数据库中使用INSERT时忽略重复项_Php_Mysql_Symfony1_Doctrine_Symfony 1.4 - Fatal编程技术网

Php 在具有Symfony和DORITOR的数据库中使用INSERT时忽略重复项

Php 在具有Symfony和DORITOR的数据库中使用INSERT时忽略重复项,php,mysql,symfony1,doctrine,symfony-1.4,Php,Mysql,Symfony1,Doctrine,Symfony 1.4,我有一张桌子 CREATE TABLE `sob_tags_articles` ( `tag_id` int(11) NOT NULL, `article_id` int(11) NOT NULL, `id` int(11) NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=112 以及用命令来拯救一个物体: $sbTagsArticles = new SobTagsArtic

我有一张桌子

CREATE TABLE `sob_tags_articles` (
  `tag_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `id` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=112
以及用命令来拯救一个物体:

$sbTagsArticles = new SobTagsArticles();
$sbTagsArticles->article_id = $pubId;
$sbTagsArticles->tag_id = $tagId;
$sbTagsArticles->save();
但如果存在具有相同$pubId和$tagId的记录,则新记录将与新PK一起插入

如何使用symfony将忽略插入到表中

$sbTagsArticles->isNew();
返回1

Thnx

您应该确保应用程序端而不是SQL端不存在相同的记录。如果您不希望存在相同的文章/标签组合,请向
(文章id,标签id)
添加唯一索引。这将生成一个mysql错误,这将反过来生成一个您可以捕获的条令异常。保存时没有忽略标志。。。您可能可以使用在较低级别的DBAL(Doctrine_查询、Doctrine_连接等)上操作的数据库,但不能使用ORM层的directl

doctor\u Record::isNew()
如果您实例化了一条记录,而不是从数据库中提取它,那么它将始终返回true,否则它无法知道该记录是/不是新的

还有,为什么要使用MyISAM存储引擎?我很确定这在使用条令时会导致更多的开销,因为它需要在php端模拟约束。通常情况下,您的模式如下所示:

CREATE TABLE `sob_tags_articles` (
  `tag_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `id` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`id`),
  CONSTRAINT `some_unique_constraint_name_1`
      FOREIGN KEY `article_id`
      REFERENCES `article` (`id`)
      ON DELETE CASCADE,
  CONSTRAINT `some_unique_constraint_name_2`
      FOREIGN KEY `tag_id`
      REFERENCES `tag` (`id`)
      ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=112
CREATE TABLE `sob_tags_articles` (
  `tag_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `id` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`id`),
  UNIQUE INDEX `sb_tags_articles_unique` (`tag_id` ASC, `article_id` ASC),
  CONSTRAINT `some_unique_constraint_name_1`
      FOREIGN KEY `article_id`
      REFERENCES `article` (`id`)
      ON DELETE CASCADE,
  CONSTRAINT `some_unique_constraint_name_2`
      FOREIGN KEY `tag_id`
      REFERENCES `tag` (`id`)
      ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=112

您可以使用新的保存方法扩展SobTagsArticles对象,并检查记录是否已存在:

public function exists() {
  $q = Doctrine_Query::create()
    ->from('sobtagsarticles ta')
    ->where('ta.tag_id = ? and ta.article_id = ?', array($this->getTagId(), $this->getArticleId()));

  if (!$result = $q->execute())
  {
    parent::save();
  }
}
这样,仅当对象不存在时才会保存该对象

您还可以为表设置唯一索引,如下所示:

UNIQUE INDEX `sb_tags_articles_unique` (`tag_id` ASC, `article_id` ASC)
您的架构如下所示:

CREATE TABLE `sob_tags_articles` (
  `tag_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `id` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`id`),
  CONSTRAINT `some_unique_constraint_name_1`
      FOREIGN KEY `article_id`
      REFERENCES `article` (`id`)
      ON DELETE CASCADE,
  CONSTRAINT `some_unique_constraint_name_2`
      FOREIGN KEY `tag_id`
      REFERENCES `tag` (`id`)
      ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=112
CREATE TABLE `sob_tags_articles` (
  `tag_id` int(11) NOT NULL,
  `article_id` int(11) NOT NULL,
  `id` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`id`),
  UNIQUE INDEX `sb_tags_articles_unique` (`tag_id` ASC, `article_id` ASC),
  CONSTRAINT `some_unique_constraint_name_1`
      FOREIGN KEY `article_id`
      REFERENCES `article` (`id`)
      ON DELETE CASCADE,
  CONSTRAINT `some_unique_constraint_name_2`
      FOREIGN KEY `tag_id`
      REFERENCES `tag` (`id`)
      ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=112

这是要使用的实际代码

try
{
    $record->save();
}
catch(Doctrine_Connection_Exception $e)
{
    if($e->getPortableCode() != Doctrine::ERR_ALREADY_EXISTS)
    {
        /**
         * if its not the error code for a duplicate key 
         * value then rethrow the exception
         */
        throw $e;
    }
    /**
     * you might want to fetch the real record here instead 
     * so yure working with the persisted copy
     */
}

哦,谢谢!该模式对于这个任务来说非常好,但我不能修改表引擎。我读过,教义是更好和更新的推动,所以我使用它。我添加了一个索引。现在我需要抓住例外。你知道怎么做吗?我使用ajax查询来保存记录,所以我不需要在firebug中看到所有这些垃圾。典型的Try/Catch块带有一些逻辑,以确保它是您期望的错误。。。如果条令引发一般条令异常或其他更具体的情况,您可能需要检查错误代码i don memberbr。例如,见上文。我似乎最终得到了实体管理器“关闭”的副作用。。。以下是异常说明
EntityManager已关闭
。用条令优雅地处理个别例外并不是一个真正的选择。你失去了状态。后续声明无效。最好在存储库中重新考虑并使用函数,或者使用事务检查然后插入,或者使用重复键忽略写入内容。@ficuscr我很确定这是Doctrine2特有的,因为在Doctrine2.x中没有EntityManager。(该Q/A是关于1.x的)。也就是说,你的论点和解决方案是有道理的,而且肯定是首选。你为什么不使用
(tag\u id,article\u id)
作为主键?@user274101:你不需要更改StackOverflow上已解决问题的标题。您应该接受正确的答案。我认为最好不要再次查询mysql以检查记录是否存在。是的,您可以使用memcached或redis队列