diff --git a/src/Platforms/SQLServerPlatform.php b/src/Platforms/SQLServerPlatform.php index 03f1c240b28..52715e5f4e3 100644 --- a/src/Platforms/SQLServerPlatform.php +++ b/src/Platforms/SQLServerPlatform.php @@ -660,10 +660,9 @@ protected function getRenameColumnSQL(string $tableName, string $oldColumnName, */ private function getRenameSQL(string ...$arguments): string { - return 'EXEC sp_rename ' - . implode(', ', array_map(function (string $argument): string { - return 'N' . $this->quoteStringLiteral($argument); - }, $arguments)); + return $this->getExecSQL('sp_rename', ...array_map(function (string $argument): string { + return $this->quoteNationalStringLiteral($argument); + }, $arguments)); } /** @@ -692,14 +691,21 @@ protected function getAddExtendedPropertySQL( ?string $level2Type = null, ?string $level2Name = null, ): string { - return 'EXEC sp_addextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value ?? '') . ', ' . - 'N' . $this->quoteStringLiteral($level0Type ?? '') . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type ?? '') . ', ' . $level1Name . - ($level2Type !== null || $level2Name !== null - ? ', N' . $this->quoteStringLiteral($level2Type ?? '') . ', ' . $level2Name - : '' - ); + $arguments = [ + $this->quoteNationalStringLiteral($name), + $this->quoteNationalStringLiteral($value ?? ''), + $this->quoteNationalStringLiteral($level0Type ?? ''), + $level0Name ?? '', + $this->quoteNationalStringLiteral($level1Type ?? ''), + $level1Name ?? '', + ]; + + if ($level2Type !== null || $level2Name !== null) { + $arguments[] = $this->quoteNationalStringLiteral($level2Type ?? ''); + $arguments[] = $level2Name ?? ''; + } + + return $this->getExecSQL('sp_addextendedproperty', ...$arguments); } /** @@ -726,14 +732,20 @@ protected function getDropExtendedPropertySQL( ?string $level2Type = null, ?string $level2Name = null, ): string { - return 'EXEC sp_dropextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', ' . - 'N' . $this->quoteStringLiteral($level0Type ?? '') . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type ?? '') . ', ' . $level1Name . - ($level2Type !== null || $level2Name !== null - ? ', N' . $this->quoteStringLiteral($level2Type ?? '') . ', ' . $level2Name - : '' - ); + $arguments = [ + $this->quoteNationalStringLiteral($name), + $this->quoteNationalStringLiteral($level0Type ?? ''), + $level0Name ?? '', + $this->quoteNationalStringLiteral($level1Type ?? ''), + $level1Name ?? '', + ]; + + if ($level2Type !== null || $level2Name !== null) { + $arguments[] = $this->quoteNationalStringLiteral($level2Type ?? ''); + $arguments[] = $level2Name ?? ''; + } + + return $this->getExecSQL('sp_dropextendedproperty', ...$arguments); } /** @@ -762,14 +774,37 @@ protected function getUpdateExtendedPropertySQL( ?string $level2Type = null, ?string $level2Name = null, ): string { - return 'EXEC sp_updateextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value ?? '') . ', ' . - 'N' . $this->quoteStringLiteral($level0Type ?? '') . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral($level1Type ?? '') . ', ' . $level1Name . - ($level2Type !== null || $level2Name !== null - ? ', N' . $this->quoteStringLiteral($level2Type ?? '') . ', ' . $level2Name - : '' - ); + $arguments = [ + $this->quoteNationalStringLiteral($name), + $this->quoteNationalStringLiteral($value ?? ''), + $this->quoteNationalStringLiteral($level0Type ?? ''), + $level0Name ?? '', + $this->quoteNationalStringLiteral($level1Type ?? ''), + $level1Name ?? '', + ]; + + if ($level2Type !== null || $level2Name !== null) { + $arguments[] = $this->quoteNationalStringLiteral($level2Type ?? ''); + $arguments[] = $level2Name ?? ''; + } + + return $this->getExecSQL('sp_updateextendedproperty', ...$arguments); + } + + /** + * Returns the SQL statement that will execute the given stored procedure with the given arguments. + * + * @param string $procedureName The name of the stored procedure to execute. + * @param string ...$arguments The SQL fragments representing the arguments to pass to the stored procedure. + */ + private function getExecSQL(string $procedureName, string ...$arguments): string + { + return 'EXEC ' . $this->quoteSingleIdentifier($procedureName) . ' ' . implode(', ', $arguments); + } + + private function quoteNationalStringLiteral(string $value): string + { + return 'N' . $this->quoteStringLiteral($value); } public function getEmptyIdentityInsertSQL(string $quotedTableName, string $quotedIdentifierColumnName): string diff --git a/tests/Platforms/SQLServerPlatformTest.php b/tests/Platforms/SQLServerPlatformTest.php index 534b79e2537..b21401cf30d 100644 --- a/tests/Platforms/SQLServerPlatformTest.php +++ b/tests/Platforms/SQLServerPlatformTest.php @@ -657,7 +657,7 @@ public function testCreateTableWithSchemaColumnComments(): void $expectedSql = [ 'CREATE TABLE testschema.test (id INT NOT NULL, PRIMARY KEY (id))', - "EXEC sp_addextendedproperty N'MS_Description', N'This is a comment', " + "EXEC [sp_addextendedproperty] N'MS_Description', N'This is a comment', " . "N'SCHEMA', 'testschema', N'TABLE', 'test', N'COLUMN', 'id'", ]; @@ -678,7 +678,7 @@ public function testAlterTableWithSchemaColumnComments(): void $expectedSql = [ 'ALTER TABLE testschema.mytable ADD quota INT NOT NULL', - "EXEC sp_addextendedproperty N'MS_Description', N'A comment', " + "EXEC [sp_addextendedproperty] N'MS_Description', N'A comment', " . "N'SCHEMA', 'testschema', N'TABLE', 'mytable', N'COLUMN', 'quota'", ]; @@ -697,7 +697,7 @@ public function testAlterTableWithSchemaDropColumnComments(): void ]); $expectedSql = [ - "EXEC sp_dropextendedproperty N'MS_Description'" + "EXEC [sp_dropextendedproperty] N'MS_Description'" . ", N'SCHEMA', 'testschema', N'TABLE', 'mytable', N'COLUMN', 'quota'", ]; @@ -715,7 +715,7 @@ public function testAlterTableWithSchemaUpdateColumnComments(): void ), ]); - $expectedSql = ["EXEC sp_updateextendedproperty N'MS_Description', N'B comment', " + $expectedSql = ["EXEC [sp_updateextendedproperty] N'MS_Description', N'B comment', " . "N'SCHEMA', 'testschema', N'TABLE', 'mytable', N'COLUMN', 'quota'", ]; @@ -840,7 +840,7 @@ public function testGetVariableLengthBinaryTypeDeclarationSQLNoLength(): void */ protected function getAlterTableRenameIndexSQL(): array { - return ["EXEC sp_rename N'mytable.idx_foo', N'idx_bar', N'INDEX'"]; + return ["EXEC [sp_rename] N'mytable.idx_foo', N'idx_bar', N'INDEX'"]; } /** @@ -849,8 +849,8 @@ protected function getAlterTableRenameIndexSQL(): array protected function getQuotedAlterTableRenameIndexSQL(): array { return [ - "EXEC sp_rename N'[table].[create]', N'select', N'INDEX'", - "EXEC sp_rename N'[table].[foo]', N'bar', N'INDEX'", + "EXEC [sp_rename] N'[table].[create]', N'select', N'INDEX'", + "EXEC [sp_rename] N'[table].[foo]', N'bar', N'INDEX'", ]; } @@ -859,7 +859,7 @@ protected function getQuotedAlterTableRenameIndexSQL(): array */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ["EXEC sp_rename N'myschema.mytable.idx_foo', N'idx_bar', N'INDEX'"]; + return ["EXEC [sp_rename] N'myschema.mytable.idx_foo', N'idx_bar', N'INDEX'"]; } /** @@ -868,8 +868,8 @@ protected function getAlterTableRenameIndexInSchemaSQL(): array protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array { return [ - "EXEC sp_rename N'[schema].[table].[create]', N'select', N'INDEX'", - "EXEC sp_rename N'[schema].[table].[foo]', N'bar', N'INDEX'", + "EXEC [sp_rename] N'[schema].[table].[create]', N'select', N'INDEX'", + "EXEC [sp_rename] N'[schema].[table].[foo]', N'bar', N'INDEX'", ]; } @@ -933,7 +933,7 @@ protected function getAlterStringToFixedStringSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ["EXEC sp_rename N'mytable.idx_foo', N'idx_foo_renamed', N'INDEX'"]; + return ["EXEC [sp_rename] N'mytable.idx_foo', N'idx_foo_renamed', N'INDEX'"]; } protected function getLimitOffsetCastToIntExpectedQuery(): string