简体   繁体   English

在SQL Server中使用phpunit / dbunit时出错

[英]Error when using phpunit/dbunit with SQL Server

I am using phpunit/dbunit to test sql server database, but it shows the following error 我正在使用phpunit / dbunit测试sql server数据库,但显示以下错误

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.] 1)Tests \\ Integration \\ BlocksDaoIntegrationTest :: test_insert_block PHPUnit_Extensions_Database_Operation_Exception:COMPOSITE [TRUNCATE]操作在查询时失败:使用args截断表DIGITAL_DOCUMENTS_IMAGES:数组()[SQLSTATE [42000]:[Microsoft] [SQL Server 1.0]无法截断表“ DIGITAL_DOCUMENTS_IMAGES”,因为它已被FOREIGN KEY约束引用。]

Could someone please help me to solve it? 有人可以帮我解决吗? Thank you 谢谢
(sorry for the english I'm Brazilian) (对不起英语,我是巴西人)

I have solved the problem extending the class PHPUnit_Extensions_Database_Operation_Truncate and then returning it: 我已经解决了扩展类PHPUnit_Extensions_Database_Operation_Truncate然后返回它的问题:

The operation 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"');

    }
}

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

The problem is you have foreign keys in the table DIGITAL_DOCUMENTS_IMAGES . 问题是您在表DIGITAL_DOCUMENTS_IMAGES具有外键。
Try replacing the command 尝试替换命令

TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES

with

DELETE FROM DIGITAL_DOCUMENTS_IMAGES

and you will get the same result Maybe it can take some additional time but at the end you will have you table empty. 您将获得相同的结果,也许会花费一些时间,但最后您将表空了。

There are some restrictions when you use TRUNCATE`. 使用TRUNCATE`时有一些限制。 You cannot use TRUNCATE TABLE on tables that: 您不能在以下表上使用TRUNCATE TABLE:

  • Are referenced by a FOREIGN KEY constraint. 由FOREIGN KEY约束引用。 (You can truncate a table that has a foreign key that references itself.) (您可以截断具有引用自身的外键的表。)

  • Participate in an indexed view. 参与索引视图。

  • Are published by using transactional replication or merge replication. 通过使用事务复制或合并复制来发布。

Here you have additional information about the difference between TRUNCATE and DELETE 在这里,TRUNCATE有关TRUNCATEDELETE之间的区别的更多信息。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM