为什么Invoke-SqlCmd可以工作,但是Ado.Net不针对处于“还原”状态的数据库?

时间:2019-03-18 02:24:53

标签: ado.net smo invoke-sqlcmd

这是Ado.Net代码(用Powershell编写):

function ExecuteSqlQuery(
    [parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$ConnectionString,
    [parameter(Mandatory=$true)]
    [string]$Query,
    $QueryTimeout = 30)
{
    $SqlConnection = New-Object System.Data.SqlClient.SqlConnection                
    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand
    $SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
    try 
    {
        $SqlConnection.ConnectionString = $ConnectionString 
        $SqlConnection.Open()

        $SqlCmd.CommandTimeout = $QueryTimeout
        $SqlCmd.CommandText = $Query
        $SqlCmd.Connection = $SqlConnection

        $DataSet = New-Object System.Data.DataSet
        $SqlAdapter.SelectCommand = $SqlCmd        
        [void]$SqlAdapter.Fill($DataSet)

        $res = $null
        if ($DataSet.Tables.Count)
        {
            $res = $DataSet.Tables[$DataSet.Tables.Count - 1]
        }
        $res
    }
    finally 
    {
        $SqlAdapter.Dispose()
        $SqlCmd.Dispose()
        $SqlConnection.Dispose()
    }
}

还有另一个代码可以执行以下操作:

  1. 使用SMO Restore.SqlRestore方法恢复数据库,该数据库处于正在恢复... 状态
  2. 然后应用一些Sql代码

Sql代码为:

IF 'RESTORING' = (select state_desc from sys.databases where name = '" + $dbname + "')
    restore database [" + $dbname + "] with recovery

ALTER DATABASE [" + $dbname + "] SET RECOVERY Simple WITH NO_WAIT
declare @shrinklogfile varchar(MAX)= N'
use [" + $dbname + "] 
declare @logfilename VARCHAR (MAX) = (select name  from [$dbname].sys.database_files where type_desc=''LOG'')
DBCC shrinkfile(@logfilename,0,truncateonly)
'
exec (@shrinklogfile)

-- get latest backup_finish_date to know the time database is restored to
;WITH LastRestores AS
(
    SELECT
        DatabaseName = [d].[name],
        [d].[create_date],
        [d].[compatibility_level],
        [d].[collation_name],
        r.*,
        RowNum = ROW_NUMBER() OVER (PARTITION BY d.Name ORDER BY r.[restore_date] DESC)
    FROM master.sys.databases d 
    LEFT OUTER JOIN msdb.dbo.[restorehistory] r ON r.[destination_database_name] = d.Name
)
SELECT coalesce(stop_at,restore_date) 
FROM [LastRestores] 
WHERE [RowNum] = 1 and DatabaseName = '" + $dbname + "'

我不知道为什么原始代码将数据库保留在“正在还原...”状态,然后使用Sql代码完成还原。但这是

无论如何,如果使用Invoke-SqlCmd执行步骤2中的Sql代码,那么一切都很好。但是,如果我使用上述基于Ado.Net的函数运行相同的代码,则在尝试打开与数据库的连接时会失败。

那么,Invoke-SqlCmd如何做到这一点,以及可以在上面的Ado.Net代码中进行哪些更改以使其正常工作?

0 个答案:

没有答案