Resolvendo o erro “Procedure or function sp_attach_db has too many arguments specified” no SQL Server
Esse erro do SQL Server ocorre quando passamos muitos parâmetros ao realizar um attach de uma base a uma instância do SQL Server 2005/2008/2008 R2. Por limitação da procedure sp_attach_db não é possível realizar attach de mais de 16 datafiles (incluindo o log). Veja como resolver!
Realizar o attach de uma base se torna uma ação comum no dia-a-dia de um DBA SQL Server, porém, quando é necessário fazer essa tarefa em uma base que possui muitos datafiles pode gerar uma certa dor cabeça!
A procedure sp_attach_db possui algumas limitações, dentre elas o fato de não aceitar mais de 16 datafiles (incluindo o logfile) como parâmetros a serem anexados ao banco, gerando o erro “Procedure or function sp_attach_db has too many arguments specified”.
A maneira correta de resolver este erro é usando o comando CREATE DATABASE … FOR ATTACH. Este comando substituirá a procedure sp_attach_db que entrará em desuso futuramente.
Vamos simular o problema criando uma base com 16 datafiles + 1 logfile com 5mb cada, gerando uma base de 85mb:
1 – Criando o banco de dados
-- Cria a base com 16 datafiles e 1 logfile de 5mb cada CREATE DATABASE [DatabaseTest] ON PRIMARY ( NAME = 'DatabaseTest01', FILENAME = 'C:\DatabaseTest\DatabaseTest01.mdf' , SIZE = 5120KB), ( NAME = 'DatabaseTest02', FILENAME = 'C:\DatabaseTest\DatabaseTest02.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest03', FILENAME = 'C:\DatabaseTest\DatabaseTest03.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest04', FILENAME = 'C:\DatabaseTest\DatabaseTest04.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest05', FILENAME = 'C:\DatabaseTest\DatabaseTest05.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest06', FILENAME = 'C:\DatabaseTest\DatabaseTest06.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest07', FILENAME = 'C:\DatabaseTest\DatabaseTest07.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest08', FILENAME = 'C:\DatabaseTest\DatabaseTest08.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest09', FILENAME = 'C:\DatabaseTest\DatabaseTest09.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest10', FILENAME = 'C:\DatabaseTest\DatabaseTest10.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest11', FILENAME = 'C:\DatabaseTest\DatabaseTest11.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest12', FILENAME = 'C:\DatabaseTest\DatabaseTest12.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest13', FILENAME = 'C:\DatabaseTest\DatabaseTest13.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest14', FILENAME = 'C:\DatabaseTest\DatabaseTest14.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest15', FILENAME = 'C:\DatabaseTest\DatabaseTest15.ndf' , SIZE = 5120KB), ( NAME = 'DatabaseTest16', FILENAME = 'C:\DatabaseTest\DatabaseTest16.ndf' , SIZE = 5120KB) LOG ON ( NAME = 'DatabaseTest_log', FILENAME = 'C:\DatabaseTest\DatabaseTest_log.ldf' , SIZE = 5120KB) GO
2 – Realizando o dettach do banco
USE [master] GO ALTER DATABASE [DatabaseTest] SET SINGLE_USER WITH ROLLBACK IMMEDIATE GO EXEC master..sp_detach_db @dbname = 'DatabaseTest' GO
3 – Tentando incluir o banco usando a procedure sp_attach_db
EXEC sp_attach_db 'DatabaseTest', 'C:\DatabaseTest\DatabaseTest01.mdf', 'C:\DatabaseTest\DatabaseTest02.ndf', 'C:\DatabaseTest\DatabaseTest03.ndf', 'C:\DatabaseTest\DatabaseTest04.ndf', 'C:\DatabaseTest\DatabaseTest05.ndf', 'C:\DatabaseTest\DatabaseTest06.ndf', 'C:\DatabaseTest\DatabaseTest07.ndf', 'C:\DatabaseTest\DatabaseTest08.ndf', 'C:\DatabaseTest\DatabaseTest09.ndf', 'C:\DatabaseTest\DatabaseTest10.ndf', 'C:\DatabaseTest\DatabaseTest11.ndf', 'C:\DatabaseTest\DatabaseTest12.ndf', 'C:\DatabaseTest\DatabaseTest13.ndf', 'C:\DatabaseTest\DatabaseTest14.ndf', 'C:\DatabaseTest\DatabaseTest15.ndf', 'C:\DatabaseTest\DatabaseTest16.ndf', 'C:\DatabaseTest\DatabaseTest_log.ldf' GO
Ao tentar incluir a base retornará o erro abaixo:
Msg 8144, Level 16, State 2, Procedure sp_attach_db, Line 0
Procedure or function sp_attach_db has too many arguments specified.
4 – Incluindo o banco usando o comando CREATE DATABASE … FOR ATTACH
Sendo assim, a única maneira de incluir a base é utilizando o comando CREATE DATABASE … FOR ATTACH:
CREATE DATABASE [DatabaseTest] ON ( FILENAME = 'C:\DatabaseTest\DatabaseTest01.mdf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest02.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest03.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest04.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest05.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest06.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest07.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest08.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest09.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest10.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest11.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest12.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest13.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest14.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest15.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest16.ndf' ), ( FILENAME = 'C:\DatabaseTest\DatabaseTest_log.ldf' ) FOR ATTACH GO
Dessa forma conseguimos incluir a base sem problemas, considerando que todos os caminhos do banco estejam corretos e não tenha esquecido nenhum deles:
Command(s) completed successfully.
Uma informação importante sobre o FOR ATTACH é que quando especificado no CREATE DATABASE a base criada herda todas as configurações e propriedades da base original.
Outra observação a ser considerada é que a procedure sp_attach_db será descontinuada conforme a documentação da própria Microsoft.

Nenhum comentário
Seja o primeiro a comentar