我通过右键单击数据库,通过任务菜单中的生成脚本手动生成脚本。
现在我的问题是通过c#代码生成该脚本......
我的问题是
是否可以通过c#代码生成?
给我一些提示以便完成?
等待您宝贵的建议和命令。
答案 0 :(得分:18)
正如已经提到过的,你使用SMO来做这个,这是一个使用C#来编写数据库脚本的例子,我提到了一些选项,但是正如它在@David Brabant的帖子中,你可以指定值很多选择。
public string ScriptDatabase()
{
var sb = new StringBuilder();
var server = new Server(@"ServerName");
var databse = server.Databases["DatabaseName"];
var scripter = new Scripter(server);
scripter.Options.ScriptDrops = false;
scripter.Options.WithDependencies = true;
scripter.Options.IncludeHeaders = true;
//And so on ....
var smoObjects = new Urn[1];
foreach (Table t in databse.Tables)
{
smoObjects[0] = t.Urn;
if (t.IsSystemObject == false)
{
StringCollection sc = scripter.Script(smoObjects);
foreach (var st in sc)
{
sb.Append(st);
}
}
}
return sb.ToString();
}
这个link可以帮助您获取和编写存储过程脚本
答案 1 :(得分:5)
您可以使用sql smo基本实现SQL Server企业管理器中的所有可用功能。有一个很好的教程here。
修改:在PowerShell中使用SMO的示例
function SQL-Script-Database
{
<#
.SYNOPSIS
Script all database objects for the given database.
.DESCRIPTION
This function scripts all database objects (i.e.: tables, views, stored
procedures, and user defined functions) for the specified database on the
the given server\instance. It creates a subdirectory per object type under
the path specified.
.PARAMETER savePath
The root path where to save object definitions.
.PARAMETER database
The database to script (default = $global:DatabaseName)
.PARAMETER DatabaseServer
The database server to be used (default: $global:DatabaseServer).
.PARAMETER InstanceName
The instance name to be used (default: $global:InstanceName).
.EXAMPLE
SQL-Script-Database c:\temp AOIDB
#>
param (
[parameter(Mandatory = $true)][string] $savePath,
[parameter(Mandatory = $false)][string] $database = $global:DatabaseName,
[parameter(Mandatory = $false)][string] $DatabaseServer = $global:DatabaseServer,
[parameter(Mandatory = $false)][string] $InstanceName = $global:InstanceName
)
try
{
if (!$DatabaseServer -or !$InstanceName)
{ throw "`$DatabaseServer or `$InstanceName variable is not properly initialized" }
$ServerInstance = SQL-Get-Server-Instance $DatabaseServer $InstanceName
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
$s = New-Object Microsoft.SqlServer.Management.Smo.Server($ServerInstance)
$db = $s.databases[$database]
$objects = $db.Tables
$objects += $db.Views
$objects += $db.StoredProcedures
$objects += $db.UserDefinedFunctions
$scripter = New-Object ('Microsoft.SqlServer.Management.Smo.Scripter') ($s)
$scripter.Options.AnsiFile = $true
$scripter.Options.IncludeHeaders = $false
$scripter.Options.ScriptOwner = $false
$scripter.Options.AppendToFile = $false
$scripter.Options.AllowSystemobjects = $false
$scripter.Options.ScriptDrops = $false
$scripter.Options.WithDependencies = $false
$scripter.Options.SchemaQualify = $false
$scripter.Options.SchemaQualifyForeignKeysReferences = $false
$scripter.Options.ScriptBatchTerminator = $false
$scripter.Options.Indexes = $true
$scripter.Options.ClusteredIndexes = $true
$scripter.Options.NonClusteredIndexes = $true
$scripter.Options.NoCollation = $true
$scripter.Options.DriAll = $true
$scripter.Options.DriIncludeSystemNames = $false
$scripter.Options.ToFileOnly = $true
$scripter.Options.Permissions = $true
foreach ($o in $objects | where {!($_.IsSystemObject)})
{
$typeFolder=$o.GetType().Name
if (!(Test-Path -Path "$savepath\$typeFolder"))
{ New-Item -Type Directory -name "$typeFolder"-path "$savePath" | Out-Null }
$file = $o -replace "\[|\]"
$file = $file.Replace("dbo.", "")
$scripter.Options.FileName = "$savePath\$typeFolder\$file.sql"
$scripter.Script($o)
}
}
catch
{
Util-Log-Error "`t`t$($MyInvocation.InvocationName): $_"
}
}
答案 2 :(得分:3)
基于@Sami答案
我创建了这个简单函数,它将为您的数据库生成所有脚本(表,视图,存储过程,用户和UserDefinedFunctions)
C:\ Program Files \ Microsoft SQL Server \ 100 \ SDK \ Assemblies是 正确的文件夹位置(或C:\ Program Files(x86)\ Microsoft SQL 64位系统上的Server \ 100 \ SDK \ Assemblies)。
您需要添加对以下内容的引用:
Microsoft.SqlServer.ConnectionInfo.dll
Microsoft.SqlServer.Smo.dll
Microsoft.SqlServer.Management.Sdk.Sfc.dll
Microsoft.SqlServer.SqlEnum.dll
第二:使用此功能
public static string ScriptDatabase()
{
// For Me Server is ".\SQLExpress" You may have changed
Server myServer = new Server(@".\SQLExpress");
Scripter scripter = new Scripter(myServer);
//Databas1 is your database Name Thats Changable
Database myAdventureWorks = myServer.Databases["MyDBName"];
/* With ScriptingOptions you can specify different scripting
* options, for example to include IF NOT EXISTS, DROP
* statements, output location etc*/
ScriptingOptions scriptOptions = new ScriptingOptions();
scriptOptions.ScriptDrops = true;
// scriptOptions.ScriptData = true;
scriptOptions.ScriptSchema = true;
scriptOptions.IncludeIfNotExists = true;
string scrs = "";
string tbScr = "";
foreach (Table myTable in myAdventureWorks.Tables)
{
/* Generating IF EXISTS and DROP command for tables */
StringCollection tableScripts = myTable.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script + "\n\n";
/* Generating CREATE TABLE command */
tableScripts = myTable.Script();
foreach (string script in tableScripts)
tbScr += script + "\n\n";
}
foreach (StoredProcedure mySP in myAdventureWorks.StoredProcedures)
{
/* Generating IF EXISTS and DROP command for StoredProcedures */
StringCollection tableScripts = mySP.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script + "\n\n";
/* Generating CREATE StoredProcedure command */
tableScripts = mySP.Script(scriptOptions);
foreach (string script in tableScripts)
tbScr += script + "\n\n";
}
foreach (View myView in myAdventureWorks.Views)
{
/* Generating IF EXISTS and DROP command for Views */
StringCollection tableScripts = myView.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script + "\n\n";
/* Generating CREATE Views command */
tableScripts = myView.Script(scriptOptions);
foreach (string script in tableScripts)
tbScr += script+"\n\n";
}
foreach (Microsoft.SqlServer.Management.Smo.User user in myAdventureWorks.Users)
{
/* Generating IF EXISTS and DROP command for Users */
StringCollection tableScripts = user.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script+"\n\n";
/* Generating CREATE Users command */
tableScripts = user.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script + "\n\n";
}
foreach (Microsoft.SqlServer.Management.Smo.UserDefinedFunction userF in myAdventureWorks.UserDefinedFunctions)
{
/* Generating IF EXISTS and DROP command for UserDefinedFunctions */
StringCollection tableScripts = userF.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script + "\n\n";
/* Generating CREATE UserDefinedFunction command */
tableScripts = userF.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script + "\n\n";
}
// For WinForms
return (scrs + "\n\n" + tbScr);
//For Console
//Console.WriteLine(scrs + "\n\n" + tbScr);
}
答案 3 :(得分:2)
我刚刚使用上面的答案编写了一个命令行程序,用于在c#中执行此操作 我想我会在上面的答案上稍微扩展一下。
如果要输出数据以及需要使用的模式:
scripter.EnumScript(something);
//instead of
scripter.Script(something);
脚本方法只是检查IncludeData选项并在设置时抛出异常,但是你必须在google上找出正确使用的方法!有趣的API设计!
数据库中的相关列表如下:
database.Tables
database.Schemas
database.Views
database.StoredProcedures
database.UserDefinedFunctions
database.Users
database.Roles
database.Sequences
虽然这可能并不详尽。
摆脱系统对象
这些对象中的列表都是IEnumerable but not IEnumerable<T>
的自定义类型,因此您无法对它们执行linq。这也意味着你必须找出它们中的类型并使用foreach的隐式转换来将它们取出。我以前从未在c#中使用过它,但我猜这些东西可能是针对框架2的。
他们中的很多人也有名为IsSystemObject的属性,但这并没有实现接口。起初,看起来摆脱所有系统对象真的很痛苦,但是你可以通过设置以下选项一次性剔除它们:
options.AllowSystemObjects = false;
除了角色之外的所有内容都适用于那些必须手动执行系统操作的人:
foreach (DatabaseRole role in database.Roles)
{
if(role.IsFixedRole)
continue;
list.Add(role);
}
添加输出对象
我使用的过程是创建 UrnCollection ,然后将不同的列表添加到集合中。像这样:
var list = new UrnCollection();
foreach (Schema schema in database.Schemas)
list.Add(schema.Urn);
//... more of these
scripter.EnumScript(list);
选项强>
从那里你需要弄清楚要设置什么选项来重新创建你需要的输出。需要注意的一些事项:
有关如何获取外键等的更多信息,请参阅this post。
健康警告
我开始将此视为复制数据库的一种方式,因为我认为备份和恢复不会做我想要的。经过很长一段路程并遇到很多问题后,我进行了一些重新评估并找到了backup and restore is a lot simpler for that use case。
答案 4 :(得分:1)
希望它可以指导你和即将到来的人。
您必须在项目中添加以下四个引用,以包含以下必需的命名空间
添加参考
Reference Microsoft.SqlServer.Smo.dll
命名空间
using System.Data.SqlClient;
using System.Collections.Specialized;
using Microsoft.SqlServer.Management.Smo;
现在在任何功能或按钮点击事件中使用以下代码
// For Me Server is ".\SQLExpress" You may have changed
Server myServer = new Server(@".\SQLExpress");
Scripter scripter = new Scripter(myServer);
//Databas1 is your database Name Thats Changable
Database myAdventureWorks = myServer.Databases["Database1"];
/* With ScriptingOptions you can specify different scripting
* options, for example to include IF NOT EXISTS, DROP
* statements, output location etc*/
ScriptingOptions scriptOptions = new ScriptingOptions();
scriptOptions.ScriptDrops = true;
scriptOptions.IncludeIfNotExists = true;
string scrs = "";
string tbScr = "";
foreach (Table myTable in myAdventureWorks.Tables)
{
/* Generating IF EXISTS and DROP command for tables */
StringCollection tableScripts = myTable.Script(scriptOptions);
foreach (string script in tableScripts)
scrs += script;
/* Generating CREATE TABLE command */
tableScripts = myTable.Script();
foreach (string script in tableScripts)
tbScr += script;
}
// For WinForms
MessageBox.Show(scrs + "\n\n" + tbScr);
//For Console
//Console.WriteLine(scrs + "\n\n" + tbScr);
它涉及http://www.mssqltips.com/sqlservertip/1833/generate-scripts-for-database-objects-with-smo-for-sql-server/答案(上文)David Brabant和上面的SO链接
使用代码块2。现在你也可以使用其他人
我找不到myserver,但在上面的代码中也解决了。