2010-06-18 16 views
2

Je suis en train de copier sql db entre les serveurs utilisant la classe Smo.Transfer.Microsoft.SqlServer.Management.Smo.Transfer classe

Et c'est bien quand vous copiez une base de données absolument normale. Ça marche.

Mais que se passe-t-il si vos données sont incohérentes? Par exemple j'ai une fonction et il obtient la valeur d'une table et d'une colonne inexistante (quelqu'un a renommé la colonne et maintenant la fonction ne fonctionnerait pas). Mais si vous essayez de générer un script, il sera généré ok.

Mais le problème commence lorsque vous essayez réellement d'exécuter ce script. Le serveur SQL ne vous laissera pas créer la fonction, car il ne peut pas faire référence à une colonne inexistante.

Quelque chose de ce genre se produit avec la classe Transfer lorsque vous exécutez la méthode .TransferData().

Les questions sont. Est-il possible de sauter en quelque sorte la création d'objet (dans notre exemple la fonction) entièrement?

Comment faire pour attraper l'erreur, ignorer l'objet et laisser la méthode .TransferData() continuer son travail?

Répondre

2

Je voudrais d'abord prendre l'approche de la réparation des dépendances brisées. Ensuite, je voudrais adopter une approche visant à empêcher ces dépendances d'être brisées à l'avenir. L'effet serait que votre code de transfert commencerait à fonctionner, et probablement d'autres codes ou interactions avec le code db fonctionneraient mieux aussi.

Pour faire tout cela, vous devez connaître les dépendances brisées. J'ai quelque chose par ici quelque part. Si je le trouve, je le posterai. Je pense peut-être à Dependency Tracker 2 de RedGate? Comme je me rappelais, il n'était toujours pas dans la «zone» pour moi, aussi utile que possible, mais il pourrait encore faire le travail pour vous.

0

Il est impossible d'empêcher la méthode TransferData de s'arrêter à la première erreur. Cependant, il existe une solution de contournement. Vous pouvez générer à la place un script SQL et l'exécuter immédiatement - dans ce scénario, vous pouvez le forcer à poursuivre l'erreur:

$Transfer.Options.ScriptBatchTerminator = $true 
$ScriptFileName = $PSScriptRoot + '\\' + $DbName + '.sql' 
$Transfer.Options.FileName = $ScriptFileName 
$Transfer.Options.ToFileOnly = $true 
$Transfer.EnumScriptTransfer() 

Invoke-SqlCmd -InputFile $ScriptFileName -ServerInstance $SQLInstanceName -Database $TargetDbName -ErrorAction Continue 

Rappelez-vous simplement de mettre Options.ScriptBatchTerminator à true.