将 phpunit/dbunit 与 SQL 服务器一起使用时出错
Error when using phpunit/dbunit with SQL Server
我正在使用 phpunit/dbunit 测试 sql 服务器数据库,但它显示以下错误
1) Tests\Integration\BlocksDaoIntegrationTest::test_insert_block
PHPUnit_Extensions_Database_Operation_Exception: COMPOSITE[TRUNCATE] operation failed on query:
TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES
using args: Array
(
)
[SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Cannot truncate table 'DIGITAL_DOCUMENTS_IMAGES' because it is being referenced by a FOREIGN KEY constraint.]
有人可以帮我解决吗?谢谢
(抱歉我是巴西人的英语)
问题是 table DIGITAL_DOCUMENTS_IMAGES
.
中有外键
尝试替换命令
TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES
和
DELETE FROM DIGITAL_DOCUMENTS_IMAGES
你会得到相同的结果
也许这可能需要一些额外的时间,但最后你会 table 空着。
使用 TRUNCATE` 时有一些限制。您不能在 table 上使用 TRUNCATE TABLE:
被 FOREIGN KEY 约束引用。 (您可以截断具有引用自身的外键的 table。)
参与索引视图。
使用事务复制或合并复制发布。
Here 你有更多关于 TRUNCATE
和 DELETE
之间区别的信息
希望对您有所帮助。
我已经解决了扩展 class PHPUnit_Extensions_Database_Operation_Truncate 然后返回它的问题:
操作class:
class SQLServerTruncateOperation extends \PHPUnit_Extensions_Database_Operation_Truncate {
private $reseed = "DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SET NOCOUNT ON;';
;WITH s(t) AS
(
SELECT
QUOTENAME(OBJECT_SCHEMA_NAME(referenced_object_id))
+ '.' + QUOTENAME(OBJECT_NAME(referenced_object_id))
FROM sys.foreign_keys AS k
WHERE EXISTS
(
SELECT 1 FROM sys.identity_columns
WHERE [object_id] = k.referenced_object_id
)
GROUP BY referenced_object_id
)
SELECT @sql = @sql + N'DBCC CHECKIDENT(''' + t + ''', RESEED, 0) WITH NO_INFOMSGS;'
FROM s;
EXEC sp_executesql @sql;";
public function execute(\PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, \PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) {
$connection->getConnection()->query('EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"');
$connection->getConnection()->query('EXEC sp_MSForEachTable "DELETE FROM ?"');
$connection->getConnection()->query($this->reseed);
$connection->getConnection()->query('EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"');
}
}
我的测试基地class:
abstract class DBUnitAbstractTestCase extends \PHPUnit_Extensions_Database_TestCase{
static private $pdo = null;
private $conn = null;
protected function getConnection() {
if ($this->conn === null) {
if (self::$pdo == null) {
self::$pdo = new \PDO("sqlsrv:Server=server;Database=db", "user", 'password');
}
$this->conn = $this->createDefaultDBConnection(self::$pdo, 'database');
}
return $this->conn;
}
public function getSetUpOperation() {
$cascadeTruncates = TRUE;
return new \PHPUnit_Extensions_Database_Operation_Composite(array(
new SQLServerTruncateOperation($cascadeTruncates),
\PHPUnit_Extensions_Database_Operation_Factory::INSERT()
));
}
}
我正在使用 phpunit/dbunit 测试 sql 服务器数据库,但它显示以下错误
1) Tests\Integration\BlocksDaoIntegrationTest::test_insert_block PHPUnit_Extensions_Database_Operation_Exception: COMPOSITE[TRUNCATE] operation failed on query: TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES using args: Array ( ) [SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Cannot truncate table 'DIGITAL_DOCUMENTS_IMAGES' because it is being referenced by a FOREIGN KEY constraint.]
有人可以帮我解决吗?谢谢
(抱歉我是巴西人的英语)
问题是 table DIGITAL_DOCUMENTS_IMAGES
.
中有外键
尝试替换命令
TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES
和
DELETE FROM DIGITAL_DOCUMENTS_IMAGES
你会得到相同的结果 也许这可能需要一些额外的时间,但最后你会 table 空着。
使用 TRUNCATE` 时有一些限制。您不能在 table 上使用 TRUNCATE TABLE:
被 FOREIGN KEY 约束引用。 (您可以截断具有引用自身的外键的 table。)
参与索引视图。
使用事务复制或合并复制发布。
Here 你有更多关于 TRUNCATE
和 DELETE
希望对您有所帮助。
我已经解决了扩展 class PHPUnit_Extensions_Database_Operation_Truncate 然后返回它的问题:
操作class:
class SQLServerTruncateOperation extends \PHPUnit_Extensions_Database_Operation_Truncate {
private $reseed = "DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SET NOCOUNT ON;';
;WITH s(t) AS
(
SELECT
QUOTENAME(OBJECT_SCHEMA_NAME(referenced_object_id))
+ '.' + QUOTENAME(OBJECT_NAME(referenced_object_id))
FROM sys.foreign_keys AS k
WHERE EXISTS
(
SELECT 1 FROM sys.identity_columns
WHERE [object_id] = k.referenced_object_id
)
GROUP BY referenced_object_id
)
SELECT @sql = @sql + N'DBCC CHECKIDENT(''' + t + ''', RESEED, 0) WITH NO_INFOMSGS;'
FROM s;
EXEC sp_executesql @sql;";
public function execute(\PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, \PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) {
$connection->getConnection()->query('EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"');
$connection->getConnection()->query('EXEC sp_MSForEachTable "DELETE FROM ?"');
$connection->getConnection()->query($this->reseed);
$connection->getConnection()->query('EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"');
}
}
我的测试基地class:
abstract class DBUnitAbstractTestCase extends \PHPUnit_Extensions_Database_TestCase{
static private $pdo = null;
private $conn = null;
protected function getConnection() {
if ($this->conn === null) {
if (self::$pdo == null) {
self::$pdo = new \PDO("sqlsrv:Server=server;Database=db", "user", 'password');
}
$this->conn = $this->createDefaultDBConnection(self::$pdo, 'database');
}
return $this->conn;
}
public function getSetUpOperation() {
$cascadeTruncates = TRUE;
return new \PHPUnit_Extensions_Database_Operation_Composite(array(
new SQLServerTruncateOperation($cascadeTruncates),
\PHPUnit_Extensions_Database_Operation_Factory::INSERT()
));
}
}