6

我有一张桌子

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

并尝试使用 Doctrine 保存对象:

$sbTagsArticles = new SobTagsArticles();
$sbTagsArticles->article_id = $pubId;
$sbTagsArticles->tag_id = $tagId;
$sbTagsArticles->save();

但是如果存在具有相同 $pubId 和 $tagId 的记录,则新记录将插入新的 PK。

如何使用 symfony 将 IGNORE 插入到表中?

$sbTagsArticles->isNew();

返回 1。

谢谢。

4

3 回答 3

13
try
{
    $record->save();
}
catch(Doctrine_Exception $e)
{
    if($e->getErrorCode() !== $duplicateKeyCode)
    {
        /**
         * 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
     */
}

您应该确保在应用程序端而不是 SQL 端不存在相同的记录。如果您不希望存在相同的文章/标签组合,则将唯一索引添加到(article_id, tag_id). 这应该会生成一个 mysql 错误,进而生成一个您可以捕获的学说异常。没有用于保存的忽略标志...您可以使用在较低级别的 DBAL(Doctrine_Query、Doctrine_Connection 等)上操作的标志,但不能直接来自 ORM 层。

Doctrine_Record::isNew()如果您已实例化记录而不是将其从数据库中拉出,则将始终返回 true,否则它无法知道该记录是/不是新的。

另外,您为什么要使用 MyISAM 存储引擎?我很确定这实际上会在使用 Doctrine 时导致更多开销,因为它需要在 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
于 2010-02-16T06:30:54.187 回答
6

这是要使用的实际代码

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
     */
}
于 2012-07-20T13:56:07.187 回答
-1

您可以使用新的保存方法扩展 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`),
  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
于 2010-02-16T07:56:34.917 回答