在学说 2 中启用 IDENTITY_INSERT
Enable IDENTITY_INSERT in doctrine 2
我拥有一个 mssql 数据库服务器,并使用 doctrine2(sqlsrv) 连接到它
我想用给定的 id 创建新的实体实例。但是如果我尝试它,我会得到一个错误:
Cannot insert explicit value for identity column in table 'my_test_table' when IDENTITY_INSERT is set to OFF
我删除了 @GeneratedValue
注释。但我仍然收到此错误。
在那之后,我在`SQL服务器管理工作室中运行这个脚本:
SET IDENTITY_INSERT my_test_table ON
不幸的是我仍然得到错误,我不明白为什么
必须在学说连接上调用
$em->getConnection()->prepare("SET IDENTITY_INSERT my_test_table ON")->execute();
我的设置可能有所不同,或者 Doctrine 中的某些内容可能已更改,但这对我来说不适用于 Doctrine ORM 2.5.6、PHP 7.0.17 和 SQL 服务器 2014.
尽管在我的同花顺之前设置了它,但它不起作用。它也不能用于来自 class 层次结构的多个 table,因为 IDENTITY_INSERT 一次只能用于一个 table。
我能够通过对连接使用包装器 class 来弄清楚如何做到这一点。 Doctrine 通过 wrapperClass
配置参数支持这一点。以下是我的有效代码。
<?php
declare(strict_types=1);
namespace Application\Db;
/**
* Class SqlSrvIdentityInsertConnection
* This class is to enable Identity Insert when using Doctrine with SQLServer.
* Must use this class with the "wrapperClass" configuration option
* for EntityManager::create
*/
class SqlSrvIdentityInsertConnection extends \Doctrine\DBAL\Connection
{
private $tables = [];
private $enabled = [];
public function enableIdentityInsertFor(string $tableName)
{
$this->tables[] = $tableName;
$this->enabled[$tableName] = false;
}
private function setIdentityInsert(string $statement) {
// Must turn off IDENTITY_INSERT if it was enabled, and this table
// isn't in the query. Must do this first!
foreach($this->tables as $tableName) {
if (stristr($statement, "INSERT INTO $tableName") === false) {
if ($this->enabled[$tableName]) {
parent::exec("SET IDENTITY_INSERT " . $tableName . " OFF");
$this->enabled[$tableName] = false;
}
}
}
foreach($this->tables as $tableName) {
if (stristr($statement, "INSERT INTO $tableName") !== false) {
parent::exec("SET IDENTITY_INSERT ".$tableName." ON");
$this->enabled[$tableName] = true;
// Only one can be enabled at a time
return;
}
}
}
public function prepare($statement)
{
$this->setIdentityInsert($statement);
return parent::prepare($statement);
}
}
下面是当你想用
插入一些实体时如何使用它
$em->persist($newEntity);
/** @var SqlSrvIdentityInsertConnection $conn */
$conn = $em->getConnection();
$metadata = $this->session->getClassMetaData(MyEntityClass::class);
$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
$conn->enableIdentityInsertFor($metadata->getTableName());
$em->flush();
我拥有一个 mssql 数据库服务器,并使用 doctrine2(sqlsrv) 连接到它
我想用给定的 id 创建新的实体实例。但是如果我尝试它,我会得到一个错误:
Cannot insert explicit value for identity column in table 'my_test_table' when IDENTITY_INSERT is set to OFF
我删除了 @GeneratedValue
注释。但我仍然收到此错误。
在那之后,我在`SQL服务器管理工作室中运行这个脚本:
SET IDENTITY_INSERT my_test_table ON
不幸的是我仍然得到错误,我不明白为什么
必须在学说连接上调用
$em->getConnection()->prepare("SET IDENTITY_INSERT my_test_table ON")->execute();
我的设置可能有所不同,或者 Doctrine 中的某些内容可能已更改,但这对我来说不适用于 Doctrine ORM 2.5.6、PHP 7.0.17 和 SQL 服务器 2014.
尽管在我的同花顺之前设置了它,但它不起作用。它也不能用于来自 class 层次结构的多个 table,因为 IDENTITY_INSERT 一次只能用于一个 table。
我能够通过对连接使用包装器 class 来弄清楚如何做到这一点。 Doctrine 通过 wrapperClass
配置参数支持这一点。以下是我的有效代码。
<?php
declare(strict_types=1);
namespace Application\Db;
/**
* Class SqlSrvIdentityInsertConnection
* This class is to enable Identity Insert when using Doctrine with SQLServer.
* Must use this class with the "wrapperClass" configuration option
* for EntityManager::create
*/
class SqlSrvIdentityInsertConnection extends \Doctrine\DBAL\Connection
{
private $tables = [];
private $enabled = [];
public function enableIdentityInsertFor(string $tableName)
{
$this->tables[] = $tableName;
$this->enabled[$tableName] = false;
}
private function setIdentityInsert(string $statement) {
// Must turn off IDENTITY_INSERT if it was enabled, and this table
// isn't in the query. Must do this first!
foreach($this->tables as $tableName) {
if (stristr($statement, "INSERT INTO $tableName") === false) {
if ($this->enabled[$tableName]) {
parent::exec("SET IDENTITY_INSERT " . $tableName . " OFF");
$this->enabled[$tableName] = false;
}
}
}
foreach($this->tables as $tableName) {
if (stristr($statement, "INSERT INTO $tableName") !== false) {
parent::exec("SET IDENTITY_INSERT ".$tableName." ON");
$this->enabled[$tableName] = true;
// Only one can be enabled at a time
return;
}
}
}
public function prepare($statement)
{
$this->setIdentityInsert($statement);
return parent::prepare($statement);
}
}
下面是当你想用
插入一些实体时如何使用它 $em->persist($newEntity);
/** @var SqlSrvIdentityInsertConnection $conn */
$conn = $em->getConnection();
$metadata = $this->session->getClassMetaData(MyEntityClass::class);
$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
$conn->enableIdentityInsertFor($metadata->getTableName());
$em->flush();