SqlPubwiz има много ограничени опции в сравнение с генерирането на скрипт в SSMS. За разлика от тях наличните опции със SMO почти напълно съвпадат с тези в SSMS, което предполага, че вероятно дори е същият код. (Надявам се, че MS не го е написала два пъти!) Има няколко примера в MSDN като този, които показват таблици на скриптове като отделни обекти. Въпреки това, ако искате всичко да се скриптира правилно с "пълна" схема, която включва "DRI" (Декларативна референтна цялост) обекти като външни ключове, тогава скриптирането на таблици поотделно не работи правилно с зависимостите. Открих, че е необходимо да събера всички URN и да ги предам на скриптера като масив. Този код, модифициран от примера, работи за мен (въпреки че смея да твърдя, че бихте могли да го подредите и коментирате малко повече):
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Sdk.Sfc;
// etc...
// Connect to the local, default instance of SQL Server.
Server srv = new Server();
// Reference the database.
Database db = srv.Databases["YOURDBHERE"];
Scripter scrp = new Scripter(srv);
scrp.Options.ScriptDrops = false;
scrp.Options.WithDependencies = true;
scrp.Options.Indexes = true; // To include indexes
scrp.Options.DriAllConstraints = true; // to include referential constraints in the script
scrp.Options.Triggers = true;
scrp.Options.FullTextIndexes = true;
scrp.Options.NoCollation = false;
scrp.Options.Bindings = true;
scrp.Options.IncludeIfNotExists = false;
scrp.Options.ScriptBatchTerminator = true;
scrp.Options.ExtendedProperties = true;
scrp.PrefetchObjects = true; // some sources suggest this may speed things up
var urns = new List<Urn>();
// Iterate through the tables in database and script each one
foreach (Table tb in db.Tables)
{
// check if the table is not a system table
if (tb.IsSystemObject == false)
{
urns.Add(tb.Urn);
}
}
// Iterate through the views in database and script each one. Display the script.
foreach (View view in db.Views)
{
// check if the view is not a system object
if (view.IsSystemObject == false)
{
urns.Add(view.Urn);
}
}
// Iterate through the stored procedures in database and script each one. Display the script.
foreach (StoredProcedure sp in db.StoredProcedures)
{
// check if the procedure is not a system object
if (sp.IsSystemObject == false)
{
urns.Add(sp.Urn);
}
}
StringBuilder builder = new StringBuilder();
System.Collections.Specialized.StringCollection sc = scrp.Script(urns.ToArray());
foreach (string st in sc)
{
// It seems each string is a sensible batch, and putting GO after it makes it work in tools like SSMS.
// Wrapping each string in an 'exec' statement would work better if using SqlCommand to run the script.
builder.AppendLine(st);
builder.AppendLine("GO");
}
return builder.ToString();