Backup failed in stored procedure - sql-server

If I am using BACKUP statement:
BACKUP DATABASE [Database name]
TO DISK = ‘Location’
WITH INIT, NOSKIP, NOFORMAT
Backup did work. But if I am trying to use same query in a stored procedure like
SET #SQLCMD = N'BACKUP DATABASE [Database Name] TO DISK = ''' + #FILENAME + ''' WITH INIT,NOSKIP, NOFORMAT'
EXEC (#SQLCMD)
I am getting error message:
Msg 203, Level 16, State 2, Procedure sp_BackupDatabase, Line 31
The name 'BACKUP DATABASE [Database Name] TO DISK =
'C:\Users\PC\Desktop\Backup\20121008\db.bak' WITH INIT,NOSKIP,
NOFORMAT' is not a valid identifier.
I couldn't figure out where I am making error.

Sir what you are doing executes the command as a stored procedure and ofcourse it's not a valid identifier for the name of the stored procedure! So I recommend you to use "sp_executesql" instead. If your code works fine, it should work everywhere else.
Referring to http://msdn.microsoft.com/en-us/library/ms175170(v=sql.105).aspx
Like this code:
Declare #Command Nvarchar(500);
Select #Command = N'BACKUP DATABASE [Database Name] TO DISK = ''' + #FILENAME + ''' WITH INIT,NOSKIP, NOFORMAT';
Execute sp_executesql #Command
Cheers

Related

SQL Server on database drop trigger deleting associated agent jobs

We have databases with associated SQL agent jobs that we keep track in a table called databasename.dbo.sqlagentjobs. Some databases are demos or QA databases and get regularly deleted.
At some point it happens that the administrator forgets to delete the associated SQL Agent jobs. In this case I wanted to write a trigger on database drop like this:
create trigger deleteagentjobs on all server for drop_database as
begin
declare #databasename nvarchar(100)
declare #eventdata xml
declare #query nvarchar(1000)
set #eventdata = EVENTDATA()
set #databasename = #eventData.value('(/EVENT_INSTANCE/DatabaseName)[1]','varchar(128)')
if object_id(#databasename +'.dbo.sqlagentjobs') is not null begin -- check if the database is a database with "our" database scheme
set #query = N'declare c insensitive cursor for select jobname_komplett from ' + #databasename + N'.dbo.sqlagentjobs ' +
N'declare #jobname nvarchar(257) ' +
N'declare #jobid uniqueidentifier ' +
N'open c ' +
N'fetch next from c into #jobname ' +
N'while ##FETCH_STATUS = 0 begin ' +
N' select job_id from msdb.dbo.sysjobs where name = #jobname ' +
N' exec msdb.dbo.sp_delete_job #jobid ' +
N' fetch next from c into #jobname ' +
N'end ' +
N'close c ' +
N'deallocate c '
exec sp_sqlexec #query
end
end
The issue with the trigger is that I get the following logical error message when I try to drop the database as follows:
exec msdb.dbo.sp_delete_database_backuphistory #database_name = n'demo'
go
alter database [demo] set single_user with rollback immediate
go
drop database [demo]
Error message:
Msg 5064, Level 16, State 1, Line 3
Changes to the state or options of database demo cannot be made at this time. The database is in single-user mode, and a user is currently connected to it.
Msg 5069, Level 16, State 1, Line 3
ALTER DATABASE statement failed.
Msg 3702, Level 16, State 4, Line 5
Cannot drop database demo because it is currently in use.
The error makes sense to me since I set the database to single user mode and try to access the database inside of the trigger.
Any ideas how to fix this? Thanks in advance!

Error when trying to delete the database in azure portal after removing from SQL pool

I am trying to delete a datapase in azure portal. After removing from SQL pool, I am getting the following error:
Msg 37106, Level 16, State 1, Line 7 The database '{databasename}' on server {'servername}' is in use by job account 'jobagent'. The database cannot be deleted or renamed while associated with a job account.
How should I address fixing this?
If you don't have other databases on it, you could simply drop the server and recreate it. That will get you around the issue.
Else Follow below steps delete database
You can kill a process by a right click on the process in the grid and selecting the Kill Process menu item. You will be asked for a confirmation to kill the related process and then will kill the open connection to the database over this process. This action is just like running to kill sql process t-sql command for a single process.
Way to drop all active connections of a database can be implemented by generating dynamic sql commands that runs a list of "Kill #spId" commands.
DECLARE #DatabaseName nvarchar(50)
SET #DatabaseName = N'Works'
--SET #DatabaseName = DB_NAME()
DECLARE #SQL varchar(max)
SET #SQL = ''
SELECT #SQL = #SQL + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(#DatabaseName) AND SPId <> ##SPId
-- SELECT #SQL
EXEC(#SQL)
A very similar to the sql code above, an other code block can be used by using the COALESCE as shown below
DECLARE #DatabaseName nvarchar(50)
SET #DatabaseName = N'Works'
DECLARE #SQL varchar(max)
SELECT #SQL = COALESCE(#SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(#DatabaseName) AND SPId <> ##SPId
--SELECT #SQL
EXEC(#SQL)
You can also refer this article

Could not find stored procedure 'sp_msforeachtable' while looping through server for stats (SSMS)

I've written this to loop through each database on a server, collecting the statistics for each table and storing them in a temp table. Eventually, I'll integrate this into a more permanent structure, but for now I'm just trying to get this working. My problem is, after 57 databases, I get the error stating it can't find the stored procedure sp_msforeachtable.
I've verified that this stored procedure exists on every database on the server and on the server level.
I've excluded this database in the findings by adding it to the "where name not in" condition, and it just moves to the next one in the list and gives the same error.(I've confirmed it exists on the next database also). I've actually done this for the next 6 databases.
This is causing me to not collect accurate information. Am I running out of resources somewhere?
DECLARE #Database TABLE (DbName SYSNAME);
IF OBJECT_ID('tempdb.dbo.#TableLvlSizes', 'U') IS NOT NULL
BEGIN
PRINT 'dropping table'
DROP TABLE tempdb.dbo.#TableLvlSizes;
END
CREATE TABLE #TableLvlSizes (
TableName nvarchar(128)
,NumberOfRows varchar(50)
,ReservedSpace varchar(50)
,TableDataSpace varchar(50)
,IndexSize varchar(50)
,unused varchar(50))
DECLARE #DbName AS SYSNAME;
DECLARE #Sql1 AS VARCHAR(MAX);
SET #DbName = '';
INSERT INTO #Database (DbName)
SELECT NAME
FROM sys.databases
where name not in ('tempdb')
ORDER BY NAME ASC;
WHILE #DbName IS NOT NULL
BEGIN
SET #DbName = (
SELECT MIN(DbName)
FROM #Database
WHERE DbName > #DbName
);
print #DbName;
SET #Sql1 =
'USE ' + #DbName + '; ' + '
Exec sp_msforeachtable
''insert into #TableLvlSizes exec sp_spaceused [?]''
'
Exec (#SQL1);
END
If someone is using Azure SQL, they will not find sp_MSforeachtable since it is not available in Azure SQL.
You may need to create one for yourself.
Since you already verified that the stored procedure does in fact exist, I believe your database is case sensitive. Therefore, the error is still accurate. Basically, the stored procedure with the case you used does not exist. The actual procedure name is sp_MSforeachtable
In your code, you are using the following:
Exec sp_msforeachtable
If you change your code to use the proper case for the stored procedure to be sp_MSforeachtable, it should work:
SET #Sql1 =
'USE ' + #DbName + '; ' + '
Exec sp_MSforeachtable
''insert into #TableLvlSizes exec sp_spaceused [?]'''

Restore master database into newly named database with .bak file

I wrote a script to restore to a new database that already has populated tables (basically the master database contains the same tables as the school database but one table needs renaming as it was renamed incorrectly in master). The .bak file was from the master database, and i'm trying to restore it to the new database, however I'm getting an error.
(2 rows affected)
-------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------
master mastlog
(1 row affected)
C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA
C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA
(1 row affected)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA
(1 row affected)
Msg 3176, Level 16, State 1, Line 59
File '' is claimed by 'mastlog'(2) and 'master'(1). The WITH MOVE clause can be used to relocate one or more files.
Msg 3013, Level 16, State 1, Line 59
RESTORE DATABASE is terminating abnormally.
And this is the script:
use school;
DECLARE #TableSchema sys.sysname = N'dbo'
DECLARE #TableName sys.sysname = N'rights'
DECLARE #OldTableName sys.sysname = N'rigths'
DECLARE #OldTableWithSchema NVARCHAR(256) = QUOTENAME(#TableSchema) + '.' + QUOTENAME(#OldTableName)
DECLARE #TableWithSchema NVARCHAR(256) = QUOTENAME(#TableSchema) + '.' + QUOTENAME(#TableName)
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #TableSchema
AND TABLE_NAME = #TableName))
BEGIN
EXEC sp_rename #TableWithSchema, #OldTableName
END
DECLARE #Table TABLE ([LogicalName] varchar(128),[PhysicalName] varchar(128), [Type] varchar, [FileGroupName] varchar(128), [Size] varchar(128),
[MaxSize] varchar(128), [FileId]varchar(128), [CreateLSN]varchar(128), [DropLSN]varchar(128), [UniqueId]varchar(128), [ReadOnlyLSN]varchar(128), [ReadWriteLSN]varchar(128),
[BackupSizeInBytes]varchar(128), [SourceBlockSize]varchar(128), [FileGroupId]varchar(128), [LogGroupGUID]varchar(128), [DifferentialBaseLSN]varchar(128), [DifferentialBaseGUID]varchar(128),
[IsReadOnly]varchar(128), [IsPresent]varchar(128), [TDEThumbprint]varchar(128), [SnapshotUrl]varchar(128)
)
DECLARE #Path varchar(1000)='C:\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\Backup\SQL2008backup.bak'
DECLARE #LogicalNameData varchar(128),#LogicalNameLog varchar(128)
INSERT INTO #table
EXEC('
RESTORE FILELISTONLY
FROM DISK=''' +#Path+ '''
')
SET #LogicalNameData=(SELECT LogicalName FROM #Table WHERE Type='D')
SET #LogicalNameLog=(SELECT LogicalName FROM #Table WHERE Type='L')
SELECT #LogicalNameData, #LogicalNameLog
use master;
declare #MasterData nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg0', #MasterData output
select #MasterData=substring(#MasterData, 3, 255)
select #MasterData=substring(#MasterData, 1, len(#MasterData) - charindex('\', reverse(#MasterData)))
print #MasterData
declare #MasterLog nvarchar(512)
exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg2', #MasterLog output
select #MasterLog=substring(#MasterLog, 3, 255)
select #MasterLog=substring(#MasterLog, 1, len(#MasterLog) - charindex('\', reverse(#MasterLog)))
print #MasterLog
declare #NewDefaultData nvarchar(512)
select isnull(#NewDefaultData, CONVERT(nvarchar(512), #MasterData))
declare #NewDefaultLog nvarchar(512)
select isnull(#NewDefaultLog, CONVERT(nvarchar(512), #MasterLog))
SET DEADLOCK_PRIORITY 10
ALTER DATABASE school
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE school FROM DISK=#Path
WITH
MOVE #LogicalNameData TO #NewDefaultData,
MOVE #LogicalNameLog TO #NewDefaultLog,
REPLACE
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #TableSchema
AND TABLE_NAME = #OldTableName))
BEGIN
EXEC sp_rename #OldTableWithSchema, #TableName
END
Updated with new code but new error
The Master database is usually used for system tables and I have never seen it used for application tables. If by accident it was used you should restore the database under a different name and copy out the tables (and other user objects) to a user database. If you insist on using master (and as we say in Brooklyn only bad things can come from this) you need to do the following:
Put the database in single user mode (by using the -m parameter in the startup file)
From sqlcmd run this command (with the actual location of the backup file):
RESTORE DATABASE master
FROM DISK = 'c:\backups\master.bak'
WITH REPLACE;
You need to overwrite your current database with the backed up database. You can do this with the REPLACE option
The basic syntax is...
SET DEADLOCK_PRIORITY 10
ALTER DATABASE master
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
restore database master from disk = 'c:\somefile.bak'
with replace

how to backup with a unique file name

i am trying to take a backup by creating a job in sql server agent using stored procedure. i am able to take the backup but each time it overwrites my previous backup file. i want my backup should create a different file with unique file name using date. how can I achieve this. below is my code, any help would be appreciated
DECLARE #backupfilename VARCHAR(1000)
DECLARE #path VARCHAR(1000)
SET #backupfilename='C:\SqlBackups\AdventureWorks\Full\backup_' + CONVERT (VarChar, GetDate(), 112) + '.bak'
SET #path = 'BACKUP DATABASE AdventureWorks2012 TO DISK = ''' + #backupfilename + ''''
EXEC msdb.dbo.sp_add_jobstep
#job_name = 'BackupDatabase',
#step_name = 'Weekly Full Backup',
#subsystem = 'TSQL',
#command = #path;

Resources