Limiting SQL Server Transaction log - sql-server

I currently have a SQL script that takes all the tables with a certain name and deletes records from it.
There are millions of records in these tables so the transaction log keeps growing even with recovery set to SIMPLE. I am putting the delete in side a transaction and it's only deleting around 50000 records at a time. Can anyone suggest some way to not let the transaction log grow uncontrollably. Below is the rough example of the SQL I am running.
DECLARE delete_cur CURSOR FOR
SELECT DISTINCT Name FROM Sys.tables WHERE name like 'ToDelete_%'
OPEN delete_cur
FETCH NEXT FROM delete_cur
INTO #tableName
WHILE ##FETCH_STATUS = 0 AND #timeToStop = 0
BEGIN
SELECT #RowCount = NULL, #MaxID = NULL, #MinID = NULL, #ID = NULL, #TableRowCount = 0
IF NOT Exists (Select 1 from ArchiveInfoAuditTables WHERE Name = #tableName)
BEGIN
SET #params = N'#MaxID_Out DECIMAL(18,0) OUT, #MinID_Out DECIMAL(18,0) OUT, #RowCount_Out DECIMAL(18,0) OUT';
SET #SQL = 'SELECT #RowCount_Out = COUNT(ID), #MaxID_Out = MAX(ID), #MinID_Out = MIN(ID) FROM ' + #tableName
print #SQL
EXEC sp_executesql #SQL, #params, #RowCount_Out = #RowCount OUT, #MaxID_Out = #MaxID OUT, #MinID_Out = #MinID OUT;
PRINT #tableName + ' Row Count: ' + CONVERT(VARCHAR, #RowCount) + ' Max ID: ' + CONVERT(VARCHAR, #MaxID) + ' Min ID: ' + CONVERT(VARCHAR, #MinID)
SET #params = N'#ID_Out DECIMAL(18,0) OUT, #Date DATETIME';
SET #SQL = 'SELECT TOP 1 #ID_Out = ID FROM ' + #tableName + ' WHERE AuditTimeStamp < #Date ORDER BY ID DESC'
print #SQL
EXEC sp_executesql #SQL, #params, #ID_Out = #ID OUT, #Date = #JanOfCurrentYear
INSERT INTO DeleteInfo (Name, StartDeletingFromID, MaxID, MinID, NumberOfRows)
VALUES (#tableName, #ID, #MaxID, #MinID, #RowCount)
END
ELSE
BEGIN
SELECT TOP 1 #ID = StartDeletingFromID FROM DeleteInfo WHERE Name = #tableName
END
IF (#ID IS NULL)
BEGIN
PRINT 'No Record needs to be deleted for Table: ' + #tableName
GOTO Fetch_Next
END
WHILE 1 = 1
BEGIN
BEGIN TRANSACTION
SET #params = N'#RowCount_Out DECIMAL(18,0) OUT, #NumOfRowsToDelete_Out BIGINT, #ID_Out DECIMAL(18,0)'
SET #SQL = 'DELETE TOP (#NumOfRowsToDelete_Out) FROM ' + #tableName + ' WHERE ID <= #ID_Out ;'
+ 'SELECT #RowCount_Out = ##RowCount'
PRINT #SQL
EXEC sp_executesql #SQL, #params, #RowCount_Out = #TempRowCount OUT, #NumOfRowsToDelete_Out = #NumOfRowsToDelete, #ID_Out = #ID
SET #TableRowCount += #TempRowCount
SET #TotalRowCount += #TableRowCount
COMMIT TRANSACTION
CHECKPOINT;
SET #MSG = 'Deleted ' + CAST(#TableRowCount AS VARCHAR) + '. ' + CONVERT(varchar, #TimeElapsed) + ' elapsed.'
RAISERROR (#MSG, 0, 1) WITH NOWAIT
IF #TempRowCount < #NumOfRowsToDelete BREAK;
END
Fetch_Next:
PRINT '/******************************************************************/'
FETCH NEXT FROM delete_cur
INTO #tableName
END
END_HERE:
CLOSE delete_cur;
DEALLOCATE delete_cur;

You can limit the size of the log (here we limit the size to 512 MB):
ALTER DATABASE [DatabaseName] MODIFY FILE ( NAME = N'DATABASENAME_Log', SIZE = 512000KB , FILEGROWTH = 0)
Create a maintenance job for backups the DB and shrinks the log
you can use this simple command to shrink the log file
DBCC SHRINKFILE (DataFile1, 512)

Related

How to create a temptable for this query

I would like to create a temptable that will hold the result of this query:
set #sql = 'use ' + #dbname + '; select db_name() , name from sys.tables where is_ms_shipped = 0 and type_desc = ''USER_TABLE'' '
exec (#sql)
Here is the full query I have:
declare #minx int = 0
declare #maxx int = (select max(id) from #DBS)
declare #sql nvarchar(1000)
declare #dbname varchar (130)
declare #count int
Select *
from #DBS
while (#count is not null
and #count <= #maxx)
begin
select #dbname = dbname
from #DBS where id = #count
print 'id = ' + convert (varchar, #count) + ' dbname = ' + #dbname
set #sql = 'use ' + #dbname + '; select db_name() , name from sys.tables where is_ms_shipped = 0 and type_desc = ''USER_TABLE'' '
exec (#sql)
set #count = #count + 1
break
end;
I have tried so many things and always getting error messages.
Anybody could give me an insight?
Not sure how you populate #DBS but:
CREATE TABLE #tables(db sysname, table_name sysname);
DECLARE #dbs cursor,
#context nvarchar(1000),
#sql nvarchar(max);
SET #sql = N'INSERT #tables(db, table_name)
SELECT DB_NAME(), name
FROM sys.tables
WHERE type = ''U'' AND is_ms_shipped = 0;';
SET #dbs = CURSOR FOR SELECT QUOTENAME(dbname)
+ N'.sys.sp_executesql' FROM #DBS;
OPEN #dbs;
FETCH NEXT FROM #dbs INTO #context;
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE #context #sql;
FETCH NEXT FROM #dbs INTO #context;
END
SELECT db, table_name FROM #tables;
Also see this related question.

T-SQL context issue

I have created a script to compare the tables of two databases to find differences. I want to be able to manually set two variables (one for each database) and have the 'USE' statement use the variable value for one of the databases but it changes context and does work correctly.
This is what I am trying to use to populating a variable (#Use) with the USE code to execute
--set #Use = 'USE ' + #NewProdDB + ';SELECT name FROM sys.tables'
--EXEC (#Use)
This is the entire query:
--========================================================================================================
-- Used to find table values in the test upgrade system database not found the newly upgraded system
-- database. Make sure change the system database names before running the query.
-- Also, select the upgraded database to run against
--========================================================================================================
DECLARE #NewProdDB VARCHAR(100)
DECLARE #TestUpgradeDB VARCHAR(100)
DECLARE #Columns VARCHAR (MAX)
DECLARE #Query VARCHAR(MAX)
DECLARE #ResultsTest VARCHAR(MAX)
DECLARE #SetResultsCursor NVARCHAR(MAX)
DECLARE #Fetcher NVARCHAR(MAX)
DECLARE #Use NVARCHAR(50)
DECLARE #ListOfTables VARCHAR(100)
DECLARE #WTF NVARCHAR(max)
DECLARE #rescanCode nvarchar(max)
/* Enter Upgraded system DB here */
SET #NewProdDB = 'zSBSSYS'
/* Enter Test Upgrade system DB here */
SET #TestUpgradeDB = 'TESTzSBSSYS'
--set #Use = 'USE ' + #NewProdDB + ';SELECT name FROM sys.tables'
--EXEC (#Use)
SET NOCOUNT ON
set #rescanCode = 'DECLARE recscan CURSOR FOR
SELECT TABLE_NAME FROM ' + #TestUpgradeDB + '.INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME NOT LIKE ''Mbf%'' AND TABLE_TYPE = ''BASE TABLE''
ORDER BY TABLE_NAME'
exec (#rescanCode)
OPEN recscan
FETCH NEXT FROM recscan INTO #ListOfTables
WHILE ##fetch_status = 0
BEGIN
BEGIN TRY
/* START Table column query */
Declare #Table varchar(60)
set #Table = #ListOfTables
set #table = (SELECT top 1 name FROM sys.tables where name = #Table)
DECLARE
#sql1 nvarchar(max) = ''
,#INTOColumns NVARCHAR(MAX)=''
,#Where nvarchar(max) = ''
,#ColumnID Int
,#Column Varchar(8000)
,#Type Varchar(8000)
,#Length Int
,#del1 varchar(2) = ','
,#CRLF bit = 1
,#aliasfield varchar(5) = '[a].'
DECLARE CSR_Attributes CURSOR FOR
SELECT
[ColumnID] = Col.column_id,
[Column] = Col.Name,
[Type] = [types].name,
[Length] = Col.max_length
FROM sys.objects Obj, sys.columns Col, sys.types [types]
WHERE Obj.OBJECT_ID = Col.OBJECT_ID AND Obj.TYPE = 'U'
AND Col.system_type_id = [types].system_type_id
AND Obj.name = #table
AND Col.name <> 'tstamp'
ORDER BY Obj.name, Col.column_id, Col.name
OPEN CSR_Attributes
FETCH NEXT FROM CSR_Attributes INTO #ColumnID, #Column, #Type, #Length
WHILE ##FETCH_STATUS = 0
BEGIN
set #sql1 += #column + #del1
set #Where += 'b.' + #column + '=a.' + #column + ' and '
set #INTOColumns += '#INTOcol,'
FETCH NEXT FROM CSR_Attributes INTO #ColumnID, #Column, #Type, #Length
END
CLOSE CSR_Attributes
DEALLOCATE CSR_Attributes
SET #Columns = SUBSTRING(#sql1,1,len(#sql1)-1) -- get rid of last comma
SET #Where = SUBSTRING(#Where,1,len(#Where)-4) -- get rid of last 'and'
SET #INTOColumns = SUBSTRING(#INTOColumns,1,len(#INTOColumns)-1) -- get rid of last comma
/* END Table column query */
/* Create SELECT statement here */
SET #ResultsTest='SELECT TOP 1 ' + #Columns + '
FROM ' + #TestUpgradeDB + '..' + #Table + ' A
WHERE NOT EXISTS
(SELECT ' + #Columns + '
FROM ' + #NewProdDB + '..' + #Table + ' B WHERE ' + #Where + ')'
SET #SetResultsCursor = 'DECLARE DataReturned CURSOR FOR ' + #ResultsTest
exec (#SetResultsCursor)
OPEN DataReturned
SET #Fetcher = 'DECLARE #INTOcol NVARCHAR(Max)
FETCH NEXT FROM DataReturned INTO ' + #INTOColumns
exec (#Fetcher)
if ##FETCH_STATUS = 0
begin
CLOSE DataReturned
DEALLOCATE DataReturned
SET #Query='SELECT ' + #Columns + '
FROM ' + #TestUpgradeDB + '..' + #Table + ' A WHERE NOT EXISTS
(SELECT ' + #Columns + ' FROM ' + #NewProdDB + '..' + #Table + ' B WHERE ' + #Where + ')'
select #Table
exec (#Query)
end
else
begin
CLOSE DataReturned
DEALLOCATE DataReturned
end
end try
begin catch
--SELECT ERROR_MESSAGE() AS ErrorMessage;
end catch
FETCH NEXT FROM recscan INTO #ListOfTables
end
CLOSE recscan
DEALLOCATE recscan
SET NOCOUNT OFF
You can't do this:
DECLARE #DB varchar(10) = 'beep';
DECLARE #USE varchar(50) = 'USE '+ #DB;
EXEC sp_sqlexec #USE;
SELECT blah FROM bloop
Database context is only used during the #USE sql, then reverts
You can do this:
DECLARE #DB varchar(10) = 'beep';
DECLARE #SQL varchar(50) = 'USE '+#DB+'; SELECT blah FROM bloop;'
EXEC sp_sqlexec #USE;
That aside, look into SQL Server Data Tools (SSDT)
It does exactly what it seems you are trying to do, schema and/or data compare between databases, and it's very easy to use.

Challenge with dynamic SQL

I have a procedure that generates dynamic SQL that creates an insert into statement while querying an excel spreadsheet.
The resulting print from the messages screen can be pasted into an ssms window and executes. When I try to execute the SQL from within the stored procedure I get a syntax error as follows:
'SELECT * into TestClient FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=YES;Database=G:\CustomerETL\Employee\PendingETL\ETLEmployeexls.xls;', [Sheet1$])'
Msg 102, Level 15, State 1, Line 15
Incorrect syntax near 'SELECT * into TestClient FROM OPENROWSET('.
Below is the entire stored procedure. I know the problem is in the ticks (within the SET blocks that create the dynamic SQL I just can't figure out where the missing ticks are.
Here is the proc:
USE [ETL]
GO
/****** Object: StoredProcedure [dbo].[ImportExcelSheetForCustomerEmployeeUpdate2] Script Date: 12/19/2017 4:03:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ImportExcelSheetForCustomerEmployeeUpdate2](#BatchID int)
as
--EXEC ImportExcelSheetForCustomerEmployeeUpdate 2
/* -- TRUNCATE TABLE FilesToImport
UPDATE FilesToImport
SET StatusID = 1
*/
-- Jeffery Williams
-- 12/18/2017
DECLARE #FileID int
,#ETLFilename varchar(250)
,#ClientName varchar(100)
,#FileType varchar(5)
,#ColumnCount int
,#RowsToETL int
,#StatusID int
,#Processed bit = 0
,#Count int
,#SQL nvarchar(4000)
,#Sheetname varchar(50) = '[Sheet1$]'
,#CMDSQL as varchar(4000)
,#SQLCmd NVARCHAR(MAX)
SELECT *
FROM FilesToImport
BEGIN
SELECT #Count = count(*)
FROM FilesToImport
WHERE BatchID = #BatchID
AND StatusID = 1
END
PRINT 'Count of records to process: ' + cast(#Count as varchar)
WHILE #Count > 0
BEGIN
BEGIN
SELECT TOP 1 #FileID = FileID, #ETLFilename = ETLFilename, #ClientName = ClientName
,#FileType = FileType, #ColumnCount = ColumnCount, #RowsToETL = RowsToETL
FROM FilesToImport
WHERE StatusID = 1
AND BatchID = #BatchID
END
-- Rename the file
set #CMDSQL = 'rename G:\CustomerETL\Employee\PendingETL\' + #ETLFilename + ' ETLEmployeexls.xls'
exec master..xp_cmdshell #CMDSQL
--PRINT cast(#cmdsql as varchar(4000))
-- Ciode below generates our select. Need to add an INTO clause and create a staging table for each import. Prior to this step we need to rename the file.
SET #SQL = ''''
SET #SQL = #SQL + 'SELECT * into ' + coalesce(#ClientName, 'TestClient') + ' FROM OPENROWSET('
SET #SQL = #SQL + ''''
SET #SQL = #SQL + '''' + 'Microsoft.ACE.OLEDB.12.0' + '''' --+ ', '
-- Excel 12.0;HDR=NO;Database=g:\UnZip\ImportSampleXLSX.xlsx;' + ''
SET #SQL = #SQL + '''' + ', '
SET #SQL = #SQL + '''' + '''Excel 12.0;HDR=YES;Database=G:\CustomerETL\Employee\PendingETL\ETLEmployeexls.xls;''' + '''' + ', ' + #Sheetname + ')'
SET #SQL = #SQL + ''''
PRINT cast(#SQL as varchar(8000))
EXEC sp_executesql #SQL
set #CMDSQL = 'rename G:\CustomerETL\Employee\PendingETL\ETLEmployeexls.xls ' + #ETLFilename
exec master..xp_cmdshell #CMDSQL
UPDATE FilesToImport
SET StatusID = 2
WHERE FileID = #FileID
/* -- TRUNCATE TABLE FilesToImport
UPDATE FilesToImport
SET StatusID = 1
*/
SET #Count = (#Count - 1)
CONTINUE
END
I am posting this as an answer but it should be comment. When I tried adding this as a comment StackOveflow kept thinking that I was trying to add #count as an email target.
In your code:
WHILE #Count > 0
BEGIN
BEGIN
SELECT TOP 1 #FileID = FileID, #ETLFilename = ETLFilename, #ClientName = ClientName
,#FileType = FileType, #ColumnCount = ColumnCount, #RowsToETL = RowsToETL
FROM FilesToImport
WHERE StatusID = 1
AND BatchID = #BatchID
END
you are not updating the value of #count. This will either never loop or loop forever. You probably want to add a statement (right before the end) such as this:
Set #count= ##rowcount;
Ben

Dynamic T-SQL stored procedure to insert in differents tables

What is the best way to achieve this
INSERT INTO #TableName (#ColumnNames)
EXEC sp_executesql #SQLResult;
Where #TableName, #ColumnNames, #SQLResult are varchar variables
I am trying to avoid do a separate insert for each table.
The best way is to write (or generate) all reqiured procedures for all table. 23 tables times 4 procedures (insert, update, delete and select) that can be generated automatically is nothing in dev time and pain compared to the so called "generic solution".
It's a path to poor perfomance, unreadable code, sql injection hazard and countless debuging hours.
First of all I appreciate all your comments. And I agree that SQL dynamic is a pain to debug (Thanks God, management studio has this possibility). And, of course there are hundreds of different solutions
I solved it in this way finally, more or less I try to explain why this solution of SQL dynamic. The client uses xlsx spreadsheets to enter certain data, so I read the spreadsheets and I insert the (data depends on the spreadsheet to insert into the proper table). Later the data in the tables are exported to XML to send a third party sofware.
SET #SEL = N'';
DECLARE sel_cursor CURSOR
FOR (SELECT sc.name as field
FROM sys.objects so INNER JOIN sys.columns sc ON so.[object_id]=sc.[object_id]
WHERE so.name= #TableName and sc.name not in ('InitDate', 'EndDate', 'Version', 'Status'));
SET #SEL = ''; set #i = 0;
OPEN sel_cursor
FETCH NEXT FROM sel_cursor INTO #field
WHILE ##FETCH_STATUS = 0
BEGIN
set #sel = #sel + ', '+ #field
set #i = 1;
FETCH NEXT FROM sel_cursor INTO #field
END
CLOSE sel_cursor;
DEALLOCATE sel_cursor;
SET #SQL = N''
SET #SQL = #SQL + N'SELECT * INTO XLImport FROM OPENROWSET'
SET #SQL = #SQL + N'('
SET #SQL = #SQL + N'''Microsoft.ACE.OLEDB.12.0'''+','
SET #SQL = #SQL + N'''Excel 12.0 Xml; HDR=YES;'
SET #SQL = #SQL + N'Database='+#file +''''+ ','
SET #SQL = #SQL + N'''select * from ['+ #SheetName + '$]'''+');'
EXEC sp_executesql #SQL
SET #SQL = N'';
SET #SQL = #SQL + N'
SELECT '+''''+CAST(#initDate AS VARCHAR(10))+'''' +', '+ ''''+CAST(#endDate AS VARCHAR(10))+''''
+ ', '+ CAST(#version AS VARCHAR(2)) +', ' +''''+#status+''''
+ #SEL
+' FROM DBO.XLImport '
DECLARE cols_cursor CURSOR
FOR (Select COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS where table_name = #tableName);
SET #SEL = ''; set #i = 0;
OPEN cols_cursor
FETCH NEXT FROM cols_cursor INTO #field
WHILE ##FETCH_STATUS = 0
BEGIN
set #sel = #sel + #field + ', '
set #i = 1;
FETCH NEXT FROM cols_cursor INTO #field
END
CLOSE cols_cursor;
DEALLOCATE cols_cursor;
SET #SEL = LEFT(#SEL, LEN(#SEL) - 1) -- remove last ,
SET #SQL = N''
SET #SQL = #SQL + N'SELECT * INTO XLImport FROM OPENROWSET'
SET #SQL = #SQL + N'('
SET #SQL = #SQL + N'''Microsoft.ACE.OLEDB.12.0'''+','
SET #SQL = #SQL + N'''Excel 12.0 Xml; HDR=YES;'
SET #SQL = #SQL + N'Database='+#file +''''+ ','
SET #SQL = #SQL + N'''select * from ['+ #SheetName + '$]'''+');'
EXEC sp_executesql #SQL
SET #SQLString =
N'INSERT INTO '+ #TableName + '('+ #SEL +') ' + #SQL;
EXEC sp_executesql #SQLString
Use EXECUTE sp_executesql #sql, here is example:
create proc sp_DynamicExcuteStore
#TableName varchar(50),
#ColumnNames varchar(50),
#SQLResult varchar(max)
as
declare #sql nvarchar(max) = '
INSERT INTO '+#TableName+' ('+#ColumnNames+')
EXEC sp_executesql '+#SQLResult
EXECUTE sp_executesql #sql
go
create proc sp_test
as
select 'test' + convert(varchar,RAND())
go
CREATE TABLE [dbo].[Test](
[text1] [nvarchar](500) NULL
) ON [PRIMARY]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[sp_DynamicExcuteStore]
#TableName = N'Test',
#ColumnNames = N'text1',
#SQLResult = N'proc_test'
SELECT 'Return Value' = #return_value
GO
SELECT TOP 1000 [text1]
FROM [test].[dbo].[Test]

MSSQL stored procedure call from ADO - not running properly

I have sp in MSSQL server - code below. When I run it from job, or SSMS it runs OK. But I need to run it from VB6 app with ADODB.
My VB6 code:
Dim cmd As New ADODB.Command
cmd.ActiveConnection = CNN
cmd.CommandTimeout = 180
cmd.CommandText = "dbbackup"
cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
cmd.Execute(, , ADODB.ConnectOptionEnum.adAsyncConnect)
Problem is: When database backup is almost done - about 90+%, cmd.State changes from Executing to Closed and VB6 code continue in executing (to this moment it waits for sp to complete). But there is a lot of code after backup which never run this way(old backup delete,...). I realized that “Last database backup” property on MSSQL database was not set and in table msdb.dbo.backupset there are no rows for my backup. But there si good restorable backup on HDD.
When i stops program for 5 minutes in debug, sp runs properly to end and everything is OK. This backup code is last code in app run and after it ends program closes all connections and exits. I added wait to VB6 code and it helps on some servers, but many other servers still has same problem.
I think main question is why MSSQL server returns control flow to VB6 code and sp is not completed yet.
Thanks
sp code:
PROCEDURE [dbo].[dbBackup]
AS
BEGIN
SET NOCOUNT ON;
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
If OBJECT_ID('tempdb..#DBName','u') IS NULL
Create Table #DBName
(
ID int identity (1,1) ,
Name varchar(128) not null ,
RetentionPeriod int null,
BackupPath varchar(255) default(''),
DBSize float default(0)
)
If OBJECT_ID('tempdb..#ExistingBackups', 'u') IS NULL
Create Table #ExistingBackups
(
Name varchar(128) ,
ID int identity (1,1)
)
Declare #Path varchar(255)
Declare #sql varchar(1000)
Declare #Name varchar(128)
Declare #RetentionPeriod int
Declare #LastBackupToKeep varchar(8)
Declare #ID int
Declare #MaxID int
Declare #eName varchar(255)
Declare #eMaxID int
Declare #eID int
Declare #eTimeStamp varchar(20)
Declare #errMsg nvarchar(2048)
Declare #errCount int; set #errCount = 0;
Declare #freeSpace bigint
Declare #pageSize float
Declare #dbSize bigint
Declare #procDate datetime
Declare #Sklad char(3)
Declare #backupName as varchar(255)
Select #pageSize = v.low / 1024 From master..spt_values v (noLock) Where v.number = 1 And v.[type] = 'E'
Select Top 1 #sklad = sklad_id From dbo.pohyb (noLock) Where Convert(int, sklad_id) > 500
Set #procDate = GETDATE()
Truncate Table #DBName
Insert Into #DBName (Name, RetentionPeriod, BackupPath)
Select DBName, BackupsToStore, BackupPath
From dbo.databaseBackup (noLock)
Where runBackup = 1
Select #MaxID = max(ID), #ID = 0 From #DBName
While #ID < #MaxID
Begin
Select #ID = min(ID) From #DBName Where ID > #ID
Select #Name = Name, #RetentionPeriod = RetentionPeriod, #Path = BackupPath
From #DBName
Where ID = #ID
If SUBSTRING(#Path, Len(#Path), 1) <> '\' Set #Path = #Path + '\'
Set #sql = 'Update #DBName Set DBSize= (Select Round(Sum(size) *' + CONVERT(varchar, #pageSize) + '/1024, 0) From ' + #Name + '.dbo.sysfiles (noLock)) Where Name = ''' + #Name + ''''
Exec (#sql)
Select #dbSize = DBSize From #DBName
--Exec #freeSpace = dbo.getDiskFreeSpace #drive = #Path
--If #freeSpace > #dbSize
--Begin
Set #eTimeStamp = REPLACE(REPLACE(CONVERT(varchar, #procDate, 113), ' ', '_'), ':', '-')
Set #sql = #Path + #Name + '_' + #eTimeStamp + '.bak'
Set #errMsg = 'OK'
Begin Try
SET #backupName = 'Objednavky backup by job ' + CONVERT(varchar, GETDATE(), 104) + ' ' + CONVERT(varchar, GETDATE(), 108);
Backup Database #Name To Disk = #sql
WITH NAME = #backupName;
-------mazanie backupu begin
Truncate Table #ExistingBackups
Set #sql = 'dir /B /OD ' + #Path + #Name + '_*.bak'
Insert #ExistingBackups Exec master..xp_cmdshell #sql
If Exists (Select 1 From #ExistingBackups Where PATINDEX('%File Not Found%', Name) > 0)
Truncate Table #ExistingBackups
Delete From #ExistingBackups Where Name IS NULL
Select #eID = 0
Select #eMaxID = Max(ID) - #RetentionPeriod From #ExistingBackups
While #eID < #eMaxID
Begin
Select #eID = Min(ID) From #ExistingBackups Where ID > #eID
Select #eName = Name From #ExistingBackups Where ID = #eID
Set #sql = 'del ' + #Path + #eName
Exec master..xp_cmdshell #sql
End
Truncate Table #ExistingBackups
-------mazanie backupu end
End Try
Begin Catch
Set #errMsg = #errMsg + '||' + CONVERT(varchar,ERROR_MESSAGE())
Set #errCount = #errCount + 1;
End Catch
--End
--Else
--Set #errMsg = 'Pln? disk (Vo?n? miesto: ' + CONVERT(varchar, #freeSpace) + ' MB, potrebn? aspo?: ' + CONVERT(varchar, #dbSize) + ' MB)'
Insert Into [dbo].[databaseBackup_log] ([Sklad_id], [DBName], [BackupDate], [Status]) Values (#Sklad, #Name, #procDate, Ltrim(Rtrim(CONVERT(varchar,#errMsg))))
End
Drop Table #DBName
Drop Table #ExistingBackups
IF #errCount > 0 BEGIN
RAISERROR (#errMsg, 16, 2) WITH SETERROR
END
RETURN 0;
END

Resources