Suspended Invoke-SQLcmd Query - 正在使用的数据库

时间:2017-10-04 06:11:21

标签: sql-server powershell tsql

我正在尝试将GNAF(澳大利亚的位置数据集)导入新数据库的过程自动化。 我遇到的问题是,当我尝试数据库并重新创建它时,我得到一个错误,说数据库正在使用中:

Invoke-Sqlcmd : Cannot drop database "GNAF" because it is currently in use. At line:11 char:5
+     Invoke-Sqlcmd -Query "IF EXISTS (SELECT name FROM master.dbo.sysd ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand   Invoke-Sqlcmd : Database 'GNAF' already exists. Choose a different database name. At line:15 char:5
+     Invoke-Sqlcmd -Query "CREATE DATABASE GNAF" -serverinstance $Serv ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

在SSMS的活动监视器中显示:

enter image description here

这是被调用的函数:

function importQNAF {

$ScriptPath = "C:\Users\owain.esau\Scripts\PowerShell\SQL-Server\TRIS Database Anon\" # change to pwd for live
$QNAFpath1 = ( $ScriptPath + "GNAF\G-NAF\G-NAF AUGUST 2017\Standard\" )
$QNAFpath2 = ( $ScriptPath + "GNAF\G-NAF\G-NAF AUGUST 2017\Authority Code\" )
$GNAF_ImportData_Path = ( $ScriptPath + "\SQLScripts\GNAF_ImportData.sql" )

(Get-Content $GNAF_ImportData_Path).replace("Powershell To Change#1", $QNAFpath1) | Set-Content $GNAF_ImportData_Path
(Get-Content $GNAF_ImportData_Path).replace("Powershell To Change#2", $QNAFpath2) | Set-Content $GNAF_ImportData_Path

## Drop and Create Table
Invoke-Sqlcmd -Query "IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name ='GNAF')
                      BEGIN
                        ALTER DATABASE GNAF SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
                        DROP DATABASE GNAF;
                      END
                    ;" -serverinstance $ServerAddress;
Start-Sleep -s 5;
Invoke-Sqlcmd -Query "CREATE DATABASE GNAF" -serverinstance $ServerAddress;
Start-Sleep -s 5;

Invoke-Sqlcmd -InputFile ( $ScriptPath + "SQLScripts\GNAF_CreateTables.sql" ) -serverinstance $ServerAddress;

try {
    Invoke-Sqlcmd -InputFile ( $ScriptPath + "SQLScripts\GNAF_ImportData.sql" ) -serverinstance $ServerAddress -querytimeout 0;
} catch {
     if ($error -match  "Access is denied.") {
        Write-Host "[!] ERROR: Access denied to GNAF folder."
        Write-Host "----------------------------------------"
        Write-Host "You have two options: "
        Write-Host ""
        Write-Host "    1) Give MSSQLSERVER full access to" $ScriptPath
        Write-Host "    2) Copy the1 folder: " $ScriptPath"GNAF to the MSSQL Source folder (C:\Program Files\SQL Server)" 

        Do {
            switch(Read-Host "Please choose an action (1 or 2)") {
                1 {
                    $Acl = (Get-Item $ScriptPath).GetAccessControl('Access');
                    $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("NT SERVICE\MSSQLSERVER", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow");
                    $Acl.SetAccessRule($Ar);
                    Set-Acl $ScriptPath $Acl;
                    importQNAF;
                }
                2 { Write-Host "Not coded yet"; }
                default { "Invalid Entry, must be 1 or 2"; }
            }
        } Until ($choice -eq 1 -or $choice -eq 2)
    }
}

(Get-Content $ GNAF_ImportData_Path).replace($ QNAFpath1," Powershell To Change#1")| Set-Content $ GNAF_ImportData_Path    (Get-Content $ GNAF_ImportData_Path).replace($ QNAFpath2," Powershell To Change#2")| Set-Content $ GNAF_ImportData_Path } 我用来将数据实际导入SQL服务器的脚本几乎与此页面上的脚本相同:

https://www.rednotebluenote.com/2016/04/importing-psma-geocoded-national-address-file-g-naf-to-sql-server/

它直接在SSMS中正常工作。此外,我不认为我的错误匹配正在收集正确的错误,而是匹配所有错误。

---更新------------------------------------------- ---

当我在函数开始时重新启动MSSQLSERVER服务时,管理它以使其运行。

现在的问题是它超时:

Invoke-Sqlcmd : Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
BULK INSERT [MB_2011] FROM 'C:\Users\owain.esau\OneDrive\Scripts\PowerShell\SQL-Server\TRIS Database Anon\GNAF\G-NAF\G-NAF AUGUST 2017\Standard\ACT_MB_2011_psv.psv'  WITH ( FIELDTERMINATOR = '|', ROWTERMINATOR = 
'\n', FIRSTROW = 2, ROWS_PER_BATCH=100000, TABLOCK) 
At line:30 char:9
+         Invoke-Sqlcmd -InputFile ( $ScriptPath + "SQLScripts\GNAF_Imp ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
    + FullyQualifiedErrorId : SqlError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

在弹出此错误之前,它只运行约45秒,运行的实际脚本在SSMA中运行大约需要3到5分钟。

(该功能已更新一点)

1 个答案:

答案 0 :(得分:1)

您需要终止与数据库的任何现有的打开连接。

这是最简单的方法(它基本上会强制所有其他连接被杀死)

IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name ='GNAF')
  BEGIN
    ALTER DATABASE GNAF SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE GNAF;
  END
;