我在MSSQL服务器中有sp - 代码如下。当我从作业或SSMS运行它时运行正常。但我需要使用ADODB从VB6应用程序运行它。
我的VB6代码:
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)
问题是:当数据库备份差不多完成时 - 大约90 +%,cmd.State从Executing更改为Closed并且VB6代码继续执行(此时它等待sp完成)。但是备份之后有很多代码从未以这种方式运行(旧的备份删除,...)。我意识到MSSQL数据库上的“上次数据库备份”属性没有设置,在表msdb.dbo.backupset中没有我的备份行。但是硬盘还有很好的可恢复备份。
当我在调试中停止程序5分钟时,sp正常运行以结束并且一切正常。此备份代码是应用程序运行中的最后一个代码,程序结束后程序关闭所有连接和退出。我添加了等待VB6代码,它有助于一些服务器,但许多其他服务器仍然有同样的问题。
我认为主要问题是为什么MSSQL服务器将控制流返回到VB6代码并且sp尚未完成。
由于
sp代码:
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