27/10/2010 17.43
Ciao a tutti, devo creare uno script che mi esporta struttura e dati delle tabelle di un database sql server 2008 r2: questo script poi dev'essere eseguito su sql server 2005 per ricreare i dati.
Lo script che segue esporta la struttura, ma non i dati
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$server = New-Object Microsoft.SqlServer.Management.Smo.Server("LOCALHOST\SQLEXPRESS")
$db = $server.Databases["MyDb"]
$filename = "d:\batch\MyScript.sql"
$scrp = new-object ('Microsoft.SqlServer.Management.Smo.Scripter')($server)
$options = New-Object ("Microsoft.SqlServer.Management.SMO.ScriptingOptions")
$options.FileName = $filename
$options.ToFileOnly = $true
$options.ScriptData = $false
$options.ScriptSchema = $true
$options.IncludeIfNotExists = $true
$options.ScriptDrops = $false
$scrp.Options = $options
$smoObjects = New-Object Microsoft.SqlServer.Management.Smo.UrnCollection
$Tables = $db.Tables
foreach($tb in $db.Tables)
{
If ($tb.IsSystemObject -eq $FALSE)
{
$smoObjects.Add($tb.Urn)
}
}
$scrp.Script($smoObjects)
Provando a settare $options.ScriptData = $true, per avere anche i dati, l'istruzione $scrp.Script($smoObjects) genera un'eccezione (come riporta MSDN).
Qualcuno sa dirmi se c'e' un modo per esportare anche i dati, oltre la struttura ?
Grazie
Marco
28/10/2010 17.05
Scusate se mi autorispondo, ma dopo varie ricerche ho trovato la soluzione, che vorrei condividere nel caso qualcuno abbia il mio stesso problema.
Per creare uno script completo di dati non va utilizzato il metodo Script, ma EnumScript di
'Microsoft.SqlServer.Management.Smo.Scripter'.
Ecco lo script funzionante che crea un file .sql per ogni tabella (non di sistema)
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$server = New-Object Microsoft.SqlServer.Management.Smo.Server("LOCALHOST\SQLEXPRESS")
$db = $server.Databases["MyDb"]
$Scripter=new-object ("Microsoft.SqlServer.Management.Smo.Scripter")($server)
$Scripter.Options.DriAll=$True
$Scripter.Options.IncludeHeaders=$False
$Scripter.Options.ToFileOnly=$True
$Scripter.Options.WithDependencies=$False
foreach ($Item in $db.Tables) {
If ($ItemIsSystemObject -eq $FALSE)
{
$Scripter.Options.FileName="D:\Batch\Sql\" + $Item.Schema + "_" + $Item.Name + ".sql"
$Scripter.Options.ScriptDrops=$False;
$Scripter.Options.ScriptData=$True;
$Scripter.Options.IncludeIfNotExists=$True;
$Scripter.Options.AppendToFile=$False
$Scripter.EnumScript($Item)
}
}
Marco
17/11/2010 13.05
Ciao Marco,
ti chiedo scusa per il ritardo con cui rispondo ma sto lavorando ad alcune fantastiche novità per la community... ;)
Che dire: grazie per il contributo!! In genere, comunque, per questa attività preferisco utilizzare un software come SQL Compare di RedGate o, ancora meglio, SQL Examiner di SQL Accessories perchè gestiscono anche gli aggiornamenti delle strutture e dei dati.
A presto.
Efran Cobisi
Solution developer, consultant and trainer
Microsoft MVP, MCT, MCSD for Microsoft .NET, MCTS: SQL Server 2005