Suspended Invoke-SQLcmd Query – Base de données en cours d'utilisation

J'essaie d'automatiser le process d'import de GNAF (jeu de données de localization pour l'Australie) dans une nouvelle database. Le problème que je rencontre est que lorsque j'essaie de recréer la database, j'obtiens une erreur indiquant que la database est en cours d'utilisation:

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 

Dans le moniteur d'activité pour SSMS, cela indique:

entrez la description de l'image ici

C'est la fonction appelée:

 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 (Obtenir-Contenu $ GNAF_ImportData_Path) .replace ($ QNAFpath2, "Powershell To Change # 2") | Set-Content $ GNAF_ImportData_Path} Le script que j'utilise pour importer réellement datatables dans le server SQL est presque identique à celui que l'on trouve sur cette page:

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

Cela fonctionne correctement dans SSMS. De plus, je ne pense pas que mon erreur corresponde à la bonne erreur, mais plutôt à toutes les erreurs.

— Mettre à jour ———————————————-

Géré pour l'exécuter lorsque je redémarre le service MSSQLSERVER au début de la fonction.

Le problème est maintenant que cela expire:

 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 

Il ne fonctionne que pendant environ 45 secondes avant que cette erreur n'apparaisse, le script en cours d'exécution dure environ 3 à 5 minutes dans SSMA.

(La fonction a été mise à jour un peu)

Vous devez terminer toutes les connections ouvertes existantes à la database.

Voici la méthode la plus simple (elle force fondamentalement toutes les autres connections à être détruites)

 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 ;