mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-02 13:02:24 +08:00
Fixes #14289: Added yii\db\Command::executeResetSequence() to work with Oracle
This commit is contained in:
committed by
Alexander Makarov
parent
68e5a9b315
commit
3555633223
@ -931,10 +931,10 @@ class Command extends Component
|
||||
/**
|
||||
* Creates a SQL command for resetting the sequence value of a table's primary key.
|
||||
* The sequence will be reset such that the primary key of the next new row inserted
|
||||
* will have the specified value or 1.
|
||||
* will have the specified value or the maximum existing value +1.
|
||||
* @param string $table the name of the table whose primary key sequence will be reset
|
||||
* @param mixed $value the value for the primary key of the next new row inserted. If this is not set,
|
||||
* the next new row's primary key will have a value 1.
|
||||
* the next new row's primary key will have the maximum existing value +1.
|
||||
* @return $this the command object itself
|
||||
* @throws NotSupportedException if this is not supported by the underlying DBMS
|
||||
*/
|
||||
@ -945,6 +945,22 @@ class Command extends Component
|
||||
return $this->setSql($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a db command resetting the sequence value of a table's primary key.
|
||||
* Reason for execute is that some databases (Oracle) need several queries to do so.
|
||||
* The sequence is reset such that the primary key of the next new row inserted
|
||||
* will have the specified value or the maximum existing value +1.
|
||||
* @param string $table the name of the table whose primary key sequence is reset
|
||||
* @param mixed $value the value for the primary key of the next new row inserted. If this is not set,
|
||||
* the next new row's primary key will have the maximum existing value +1.
|
||||
* @throws NotSupportedException if this is not supported by the underlying DBMS
|
||||
* @since 2.0.16
|
||||
*/
|
||||
public function executeResetSequence($table, $value = null)
|
||||
{
|
||||
return $this->db->getQueryBuilder()->executeResetSequence($table, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a SQL command for enabling or disabling integrity check.
|
||||
* @param bool $check whether to turn on or off the integrity check.
|
||||
|
||||
@ -1028,10 +1028,10 @@ class QueryBuilder extends \yii\base\BaseObject
|
||||
/**
|
||||
* Creates a SQL statement for resetting the sequence value of a table's primary key.
|
||||
* The sequence will be reset such that the primary key of the next new row inserted
|
||||
* will have the specified value or 1.
|
||||
* will have the specified value or the maximum existing value +1.
|
||||
* @param string $table the name of the table whose primary key sequence will be reset
|
||||
* @param array|string $value the value for the primary key of the next new row inserted. If this is not set,
|
||||
* the next new row's primary key will have a value 1.
|
||||
* the next new row's primary key will have the maximum existing value +1.
|
||||
* @return string the SQL statement for resetting sequence
|
||||
* @throws NotSupportedException if this is not supported by the underlying DBMS
|
||||
*/
|
||||
@ -1040,6 +1040,22 @@ class QueryBuilder extends \yii\base\BaseObject
|
||||
throw new NotSupportedException($this->db->getDriverName() . ' does not support resetting sequence.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a SQL statement for resetting the sequence value of a table's primary key.
|
||||
* Reason for execute is that some databases (Oracle) need several queries to do so.
|
||||
* The sequence is reset such that the primary key of the next new row inserted
|
||||
* will have the specified value or the maximum existing value +1.
|
||||
* @param string $table the name of the table whose primary key sequence is reset
|
||||
* @param array|string $value the value for the primary key of the next new row inserted. If this is not set,
|
||||
* the next new row's primary key will have the maximum existing value +1.
|
||||
* @throws NotSupportedException if this is not supported by the underlying DBMS
|
||||
* @since 2.0.16
|
||||
*/
|
||||
public function executeResetSequence($table, $value = null)
|
||||
{
|
||||
$this->db->createCommand()->resetSequence($table, $value)->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a SQL statement for enabling or disabling integrity check.
|
||||
* @param bool $check whether to turn on or off the integrity check.
|
||||
|
||||
@ -138,27 +138,34 @@ EOD;
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resetSequence($table, $value = null)
|
||||
public function executeResetSequence($table, $value = null)
|
||||
{
|
||||
$tableSchema = $this->db->getTableSchema($table);
|
||||
if ($tableSchema === null) {
|
||||
throw new InvalidArgumentException("Unknown table: $table");
|
||||
}
|
||||
if ($tableSchema->sequenceName === null) {
|
||||
return '';
|
||||
throw new InvalidArgumentException("There is no sequence associated with table: $table");
|
||||
}
|
||||
|
||||
if ($value !== null) {
|
||||
$value = (int) $value;
|
||||
} else {
|
||||
if (count($tableSchema->primaryKey)>1) {
|
||||
throw new InvalidArgumentException("Can't reset sequence for composite primary key in table: $table");
|
||||
}
|
||||
// use master connection to get the biggest PK value
|
||||
$value = $this->db->useMaster(function (Connection $db) use ($tableSchema) {
|
||||
return $db->createCommand("SELECT MAX(\"{$tableSchema->primaryKey}\") FROM \"{$tableSchema->name}\"")->queryScalar();
|
||||
return $db->createCommand(
|
||||
'SELECT MAX("' . $tableSchema->primaryKey[0] . '") FROM "'. $tableSchema->name . '"'
|
||||
)->queryScalar();
|
||||
}) + 1;
|
||||
}
|
||||
|
||||
return "DROP SEQUENCE \"{$tableSchema->name}_SEQ\";"
|
||||
. "CREATE SEQUENCE \"{$tableSchema->name}_SEQ\" START WITH {$value} INCREMENT BY 1 NOMAXVALUE NOCACHE";
|
||||
//Oracle needs at least two queries to reset sequence (see adding transactions and/or use alter method to avoid grants' issue?)
|
||||
$this->db->createCommand('DROP SEQUENCE "' . $tableSchema->sequenceName . '"')->execute();
|
||||
$this->db->createCommand('CREATE SEQUENCE "' . $tableSchema->sequenceName . '" START WITH ' . $value
|
||||
. ' INCREMENT BY 1 NOMAXVALUE NOCACHE')->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user