SMO基础

SMO基础

--王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com
--
原帖地址

过去几年我曾经写过一些关于使用DMO的文章,我也曾经在很多小项目上成功的使用了它。如果你有对象和集合的开发背景的话,DMO往往比试图去列出你需要用来查询的所有的系统表或视图以完成一个给定的任务更加直观。现在SQL2005的管理对象已经升级到和.Net架构一起使用来描述新的服务器了。我写我所遇到的知识,不是每个人去读的,这需要有良好的对象背景——可以在将来寻找更加详细的文章。对于现在,我希望你能粘贴这些代码到你的IDE然后运行看看它是怎么工作的。

第一件事是确保你安装了SMO。一个用来检查的很容易的方法是在IDE里选择工程、引用,看看是否有‘Microsoft.SQLServer.SMO’。如果你没看到,你需要运行SQL安装去添加它。你也需要安装Visual Studio 2005(任何一个版本)的一个拷贝。

今天我们试图去涉足SMO。我已经注释了代码希望对你的理解有一些帮助,但我想先讨论它。第一个真实的代码行包含了‘Oserver=new Smo.SQLServer(“localhost”)’。那是我们建立一个到服务器的信任连接(NT)的地方,逻辑上放在最前面——server对象将包含数据库而数据库将包含表,依此类推。到此非常类似DMO。

在DMO里你可以传各种标记给脚本方法去自定义输出,我从旧文章里摘录了一个示例。你能看到通过一起添加它们去获得一个值,我传了总共4个标记(指定的常量)。DMO内部将把它们解码成独立的值。


        'SQLDMOScript_AppendToFile=8192
        'SQLDMOScript_ObjectPermissions=2
        'SQLDMOScript_ToFileOnly=64
        'SQLDMOScript_PrimaryObject=4
        oView.Script 8192 + 2 + 64 + 4, "C:\DMO_Views_" & oDatabase.Name & ".sql"

SMO稍微做了一些改变。不是将不同的标记加在一起去传递它们了,我们将创建一个Options对象然后设置需要的属性。我不知道这是否比以前好,仅仅不同而已。为了给你一个它是怎样工作的印象我仅设置了一个属性ScriptDrops为True。当你查看输出的时候你可以看到它已经创建了一个drop database的语句。你可以通过改变它为False来试验看看忽略的drop,或者改变它的其他一些属性看看是怎样影响结果的。一旦配置好Options对象,我们把它作为参数传递给数据库脚本方法。

另一个不同的是DMO以字符串来返回或输出脚本。SMO不是直接那样做的,它把特定脚本需要的所有语句返回到一个集合里(可以考虑为一个超级数组)。为了得到所有的语句,我们不得不循环处理这个集合,用这种方法仅把它们输出到调试窗口,虽然你可以把它们写到一个文件里或仅仅执行它们。

更进一步你可以看看‘For Each oTable In’开头的那些代码。它演示了怎样从master数据库里的所有表中,找到那些以SPT_F开头的表,然后为这些表生成创建的脚本。注意此时我没有传递Options对象。它是一个可选择的选项。
下面是源代码,你可以在这里下载它们。接下来当我在我的机器上运行时在调试窗口会有一个输出拷贝。注意下面的代码将更改你机器的状态,所以如果要去尝试的话,请在那些容易恢复的本地实例上做试验。

Imports Microsoft.SqlServer.Management

Public Class Form1   

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        '6/13/06 Andy Warren/SQLServerCentral.com
        'SMO在SMO里演示脚本的示例代码 王成辉翻译整理
        Dim oServer As Smo.Server
        Dim Scripts As System.Collections.Specialized.StringCollection
        Dim Options As Smo.ScriptingOptions
        Dim oTable As Smo.Table
        Try

            '连接到本地缺省实例,假定用NT验证
            oServer = New Smo.Server("localhost")
          'options是告诉SMO怎样去生成对象脚本的标记,和DMO里传给options的比较类似
            Options = New Smo.ScriptingOptions
            '这将创建一个drop database语句,因为它的设置为True
            Options.ScriptDrops = True
            '现在我们将它指向一个我们知道的数据库,这里用master数据库。
              '它将返回一个TSQL语句的集合,这些语句能用来重建数据库(包括MDF/LDF,但并非所以的内容)。
          '这里也可以写到一个文件里,你可以去查看、执行等等。
            Scripts = oServer.Databases("master").Script(Options)
            '这将写到调试窗口
            For Each S As String In Scripts
                Debug.Print(S.ToString)
            Next

          '现在让我们看看一批对象的脚本,这里指所有以SPT_F开头的表。
              '对每一个表仅找那些满足条件的表去生成脚本字符串集合,然后就像刚才循环那样去写出单独的TSQL语句
            For Each oTable In oServer.Databases("master").Tables
                If oTable.Name.ToUpper Like "SPT_F*" Then
                    Scripts = oTable.Script
                    For Each S As String In Scripts
                        Debug.Print(S.ToString)
                    Next
                End If
            Next
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        Finally
            Options = Nothing
            oServer = Nothing
        End Try
    End SubEnd Class

--下面是产生的脚本

CREATE DATABASE [master] ON  PRIMARY
( NAME = N'master', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf' , SIZE = 4096KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
LOG ON
( NAME = N'mastlog', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\mastlog.ldf' , SIZE = 512KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
COLLATE SQL_Latin1_General_CP1_CI_AS
EXEC dbo.sp_dbcmptlevel @dbname=N'master', @new_cmptlevel=90
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [master].[dbo].[sp_fulltext_database] @action = 'disable'
end
ALTER DATABASE [master] SET ANSI_NULL_DEFAULT OFF
ALTER DATABASE [master] SET ANSI_NULLS OFF
ALTER DATABASE [master] SET ANSI_PADDING OFF
ALTER DATABASE [master] SET ANSI_WARNINGS OFF
ALTER DATABASE [master] SET ARITHABORT OFF
ALTER DATABASE [master] SET AUTO_CLOSE OFF
ALTER DATABASE [master] SET AUTO_CREATE_STATISTICS ON
ALTER DATABASE [master] SET AUTO_SHRINK OFF
ALTER DATABASE [master] SET AUTO_UPDATE_STATISTICS ON
ALTER DATABASE [master] SET CURSOR_CLOSE_ON_COMMIT OFF
ALTER DATABASE [master] SET CURSOR_DEFAULT  GLOBAL
ALTER DATABASE [master] SET CONCAT_NULL_YIELDS_NULL OFF
ALTER DATABASE [master] SET NUMERIC_ROUNDABORT OFF
ALTER DATABASE [master] SET QUOTED_IDENTIFIER OFF
ALTER DATABASE [master] SET RECURSIVE_TRIGGERS OFF
ALTER DATABASE [master] SET  DISABLE_BROKER
ALTER DATABASE [master] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
ALTER DATABASE [master] SET DATE_CORRELATION_OPTIMIZATION OFF
ALTER DATABASE [master] SET TRUSTWORTHY OFF
ALTER DATABASE [master] SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE [master] SET PARAMETERIZATION SIMPLE
ALTER DATABASE [master] SET  READ_WRITE
ALTER DATABASE [master] SET RECOVERY SIMPLE
ALTER DATABASE [master] SET  MULTI_USER
ALTER DATABASE [master] SET PAGE_VERIFY CHECKSUM 
ALTER DATABASE [master] SET DB_CHAINING ON
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
CREATE TABLE [dbo].[spt_fallback_db](
        [xserver_name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [xdttm_ins] [datetime] NOT NULL,
        [xdttm_last_ins_upd] [datetime] NOT NULL,
        [xfallback_dbid] [smallint] NULL,
        [name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [dbid] [smallint] NOT NULL,
        [status] [smallint] NOT NULL,
        [version] [smallint] NOT NULL
) ON [PRIMARY]

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON

CREATE TABLE [dbo].[spt_fallback_dev](
        [xserver_name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [xdttm_ins] [datetime] NOT NULL,
        [xdttm_last_ins_upd] [datetime] NOT NULL,
        [xfallback_low] [int] NULL,
        [xfallback_drive] [char](2) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
        [low] [int] NOT NULL,
        [high] [int] NOT NULL,
        [status] [smallint] NOT NULL,
        [name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [phyname] [varchar](127) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON

CREATE TABLE [dbo].[spt_fallback_usg](
        [xserver_name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [xdttm_ins] [datetime] NOT NULL,
        [xdttm_last_ins_upd] [datetime] NOT NULL,
        [xfallback_vstart] [int] NULL,
        [dbid] [smallint] NOT NULL,
        [segmap] [int] NOT NULL,
        [lstart] [int] NOT NULL,
        [sizepg] [int] NOT NULL,
        [vstart] [int] NOT NULL
) ON [PRIMARY]

DROP DATABASE [master]

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON

CREATE TABLE [dbo].[spt_fallback_db](
        [xserver_name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [xdttm_ins] [datetime] NOT NULL,
        [xdttm_last_ins_upd] [datetime] NOT NULL,
        [xfallback_dbid] [smallint] NULL,
        [name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [dbid] [smallint] NOT NULL,
        [status] [smallint] NOT NULL,
        [version] [smallint] NOT NULL
) ON [PRIMARY]

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON

CREATE TABLE [dbo].[spt_fallback_dev](
        [xserver_name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [xdttm_ins] [datetime] NOT NULL,
        [xdttm_last_ins_upd] [datetime] NOT NULL,
        [xfallback_low] [int] NULL,
        [xfallback_drive] [char](2) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
        [low] [int] NOT NULL,
        [high] [int] NOT NULL,
        [status] [smallint] NOT NULL,
        [name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [phyname] [varchar](127) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON

CREATE TABLE [dbo].[spt_fallback_usg](
        [xserver_name] [varchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [xdttm_ins] [datetime] NOT NULL,
        [xdttm_last_ins_upd] [datetime] NOT NULL,
        [xfallback_vstart] [int] NULL,
        [dbid] [smallint] NOT NULL,
        [segmap] [int] NOT NULL,
        [lstart] [int] NOT NULL,
        [sizepg] [int] NOT NULL,
        [vstart] [int] NOT NULL
) ON [PRIMARY]
虽有智慧,不如乘势;虽有鎡基,不如待时。
君子学以聚之,问以辨之,宽以居之,仁以行之。
独学而无友,则孤陋而寡闻。