Symfony ve Doktrin ile bir veritabanında INSERT kullanırken çiftleri görmezden

3 Cevap php

Ben bir tablo var

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

Ve Doktrin ile bir nesneyi kaydetmek için triing:

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

Rekor aynı $ PubID ve $ TagId ile varsa ancak yeni rekor yeni PK ile insertet olacak.

Nasıl INSERT yapmak symfony ile tabloya GÖRMEZDEN?

$sbTagsArticles->isNew();

1 döndürür.

Thnx.

3 Cevap

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
     */
}

Sen aynı kayıt uygulama tarafında değil, SQL tarafında yok sağlamak gerekir. Hiç aynı haber / tag combo var istemiyorsanız o zaman (article_id, tag_id) benzersiz bir dizin ekleyin. Bu da yakalayabilirsiniz bir doktrin durum üretecek bir mysql hatası oluşturmak gerekir. Tasarruf için bir görmezden bayrağı yok ... Sen (. Vb Doctrine_Query, Doctrine_Connection) DBal bir alt düzeyde bir işletim kullanmak mümkün ama ORM katmanı directl olmayabilir.

Doctrine_Record::isNew() her zaman kayıt db çekerek için asopposed örneği var, aksi takdirde o kayıt / yeni değildir olduğunu bilmek bir yolu vardır bir yolu vardır true dönecektir.

Ayrıca neden MyISAM depolama motorunu kullanıyorsunuz? Daha sonra php tarafında kısıtlamaları taklit etmek gerekiyor çünkü Doktrini kullanırken, bu aslında daha fazla havai neden olur oldukça emin Im. Normalde şema bu gibi bir şey olacaktır:

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

Bu kullanılacak gerçek kod

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
     */
}

Yeni bir tasarruf yöntemi ile SobTagsArticles nesnesi genişletmek ve kayıt zaten varsa kontrol edebilir:

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();
  }
}

Mevcut değil sadece bu şekilde nesne kaydedilecektir.

Sen de bu yüzden gibi tabloya benzersiz bir dizin ayarlayabilirsiniz:

UNIQUE INDEX `sb_tags_articles_unique` (`tag_id` ASC, `article_id` ASC)

Sizin şema aşağıdaki gibi olacaktır:

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