将phpunit / dbunit与SQL Server一起使用时出错

时间:2015-06-19 13:13:55

标签: php sql-server testing phpunit dbunit

我使用phpunit / dbunit来测试sql server数据库,但它显示以下错误

  

1)Tests \ Integration \ BlocksDaoIntegrationTest :: test_insert_block   PHPUnit_Extensions_Database_Operation_Exception:COMPOSITE [TRUNCATE]操作在查询时失败:                   TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES                使用args:Array   (   )    [SQLSTATE [42000]:[Microsoft] [SQL Server Native Client 11.0] [SQL Server]无法截断表'DIGITAL_DOCUMENTS_IMAGES',因为它正被FOREIGN KEY约束引用。]

有人可以帮我解决一下吗?谢谢你 (对不起英语我是巴西人)

2 个答案:

答案 0 :(得分:0)

我解决了扩展PHPUnit_Extensions_Database_Operation_Truncate类然后返回它的问题:

操作类:

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

    }
}

我的测试基类:

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

答案 1 :(得分:-1)

问题是表DIGITAL_DOCUMENTS_IMAGES中有外键 尝试替换命令

TRUNCATE TABLE DIGITAL_DOCUMENTS_IMAGES

DELETE FROM DIGITAL_DOCUMENTS_IMAGES

你会得到相同的结果 也许它可能需要一些额外的时间,但最后你会让你空着。

使用TRUNCATE时有一些限制。您不能在以下表格上使用TRUNCATE TABLE:

  • 由FOREIGN KEY约束引用。 (您可以截断具有引用自身的外键的表。)

  • 参与索引视图。

  • 使用事务复制或合并复制发布。

Here您有关于TRUNCATEDELETE之间差异的其他信息

希望这有帮助。