<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>SQL中国研发中心</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/sqlcrd/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/sqlcrd/feed.xml</link>
    <description>微软中国研发集团服务器与开发工具事业部SQL中国研发中心的博客。</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:25:18 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SQL数据库管理API简介</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/sqlapi</link>
      <pubDate>Tue, 24 Jul 2012 06:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2012/07/24/sqlapi/</guid>
      <description><![CDATA[SQL 数据库管理 API 可以编程方式访问与通过 Windows Azure 平台管理门户执行的相同管理操作，来管理 Windows Azure SQL服务器。使用 SQL 数据库管理 API...]]></description>
      <content:encoded><![CDATA[<p>SQL 数据库管理 API 可以编程方式访问与通过 Windows Azure 平台管理门户执行的相同管理操作，来管理 Windows Azure SQL服务器。使用 SQL 数据库管理 API 可以管理每个订阅的 SQL Database 服务器以及与每台服务器关联的防火墙规则。这有助于自动化应用程序的数据库支持，而无需直接与管理门户进行交互。</p>
<p>数据库管理 API 是一个 REST API。所发送的操作请求通过 SSL 进行加密，并使用 X.509 证书对其进行身份验证。可以通过 Internet 从可以发送 HTTPS 请求和接收 HTTPS 响应的任何应用程序发出这些请求。请求将发送到使用以下基本 URL 的端口 8443 上的 SQL Database 数据库管理服务：<a href="https://management.database.windows.net:8443">https://management.database.windows.net:8443</a></p>
<p>这个blog介绍了以编程方式 (使用 Visual Studio 2012 RC 中的 HttpClient) 创建一个Windows Azure SQL 数据库服务器，设置管理密码，并创建防火墙规则。我们可以使用如下步骤：</p>
<ol>
<li>准备访问数据库管理 API 的客户端证书。</li>
<li>设置相应的HTTP请求标头，如版本号等。</li>
<li>创建数据库服务器</li>
<ol>
<li>定义请求数据的 .net 对象</li>
<li>发送请求，并接收服务器响应数据</li>
<li>将响应数据转换为 .net (如C#) 的相应对象</li>
<li>从对象中读取信息</li>
</ol>
<li>设置管理密码</li>
<li>创建防火墙规则</li>
<li>连接到新创建的数据库服务器</li>
</ol>
<h2>1、准备客户端证书</h2>
<p>数据库管理 API 需要基于证书的相互身份验证。我们需要首先将公钥证书（.cer）文件与订阅相关联，方法是使用 Windows Azure 平台管理门户将该证书上载到 Windows Azure 中订阅的证书存储区。然后，将匹配的私钥证书（.pfx）文件附加到数据库管理 API 请求中。</p>
<p>有关证书创建，可以参考 <a href="http://msdn.microsoft.com/zh-cn/library/windowsazure/gg551722.aspx">如何创建管理证书</a> 以及 <a href="http://msdn.microsoft.com/zh-cn/library/windowsazure/gg432987.aspx">如何为角色创建证书</a>。例如，可以使用<a href="http://msdn.microsoft.com/zh-cn/library/bfsktky3.aspx">MakeCert工具</a>，具体命令可参考 <a href="http://blogs.msdn.com/b/jmeier/archive/2010/06/16/how-to-enable-ssl-on-windows-azure.aspx">Step 1 - Create and Install a test certificate</a> 。</p>
<p>进而我们可以获得 .cer 文件（包含公钥） 和 .pfx 文件 （包含私钥和公钥，私钥保护密码由用户指定），可以使用管理门户将公钥证书 （.cer 文件）上载到 Windows Azure中订阅的证书存储区，如：</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/4834.1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/4834.1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/4834.1.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/4834.1.png" /></a></p>
<p>之后，可以使用 System.Net.Http.WebRequestHandler 和 System.Security.Cryptography.X509Certificate2 .NET 类将私钥 (.pfx) 文件与安全请求相关联。</p>
<p>如以下代码片段，其中参数certFilename 和certPassword 分别是 .pfx 文件的全路径文件名和私钥保护密码 （私钥和密码不与请求一起发送；它们仅用于对请求进行验证）：</p>
<pre class="scroll"><code class="csharp">WebRequestHandler webRequestHandler = new WebRequestHandler();<br /> webRequestHandler.ClientCertificateOptions = ClientCertificateOption.Manual;<br /> webRequestHandler.ClientCertificates.Add(<br /> new X509Certificate2(certFilename, certPassword));</code></pre>
<h2>2、设置相应的HTTP请求标头</h2>
<p>HttpClient可用于发送 Http 请求，并用于接收 Http 响应。如下代码片段生成一个HttpClient实例，并设置访问 API 的版本信息：</p>
<pre class="scroll"><code class="csharp">this.httpClient = new HttpClient(webRequestHandler);<br />this.httpClient.DefaultRequestHeaders.Add("x-ms-version", "1.0");</code></pre>
<p>完整代码片段如下：</p>
<pre class="scroll"><code class="csharp">public class SqlRestApiClient<br />{<br /> private const string ServerUri = "https://management.database.windows.net:8443/{0}/servers";<br /> private const string FirewallUri = ServerUri + "/{1}/firewallrules";<br /> private readonly string subscriptionId;<br /> private readonly HttpClient httpClient;<br /> private readonly XmlMediaTypeFormatter xmlFormatter;<br /> private readonly IEnumerable&lt;XmlMediaTypeFormatter&gt; xmlFormatters;<br /> <br /> public SqlRestApiClient(string certFilename, string certPassword, string subscriptionId)<br /> {<br /> WebRequestHandler webRequestHandler = new WebRequestHandler();<br /> webRequestHandler.ClientCertificateOptions = ClientCertificateOption.Manual;<br /> webRequestHandler.ClientCertificates.Add(<br /> new X509Certificate2(certFilename, certPassword));<br /> <br /> this.httpClient = new HttpClient(webRequestHandler);<br /> this.httpClient.DefaultRequestHeaders.Add("x-ms-version", "1.0");<br /> <br /> this.xmlFormatter = new XmlMediaTypeFormatter()<br /> {<br /> UseXmlSerializer = true,<br /> };<br /> this.xmlFormatters = new XmlMediaTypeFormatter[] { xmlFormatter };<br /> this.subscriptionId = subscriptionId;<br /> }<br />}</code></pre>
<h2>3、创建数据库服务器</h2>
<h3>定义请求数据的 .net 对象</h3>
<p>定义请求数据 .Net 对象 ServerRequest如下：</p>
<pre class="scroll"><code class="csharp"> [XmlRoot(ElementName = "Server",<br /> Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]<br /> public class ServerRequest<br /> {<br /> public string AdministratorLogin { get; set; }<br /> public string AdministratorLoginPassword { get; set; }<br /> public string Location { get; set; }<br /> }<br /></code></pre>
<h3>发送请求并接收服务器响应数据</h3>
<p>设置枚举服务器的url，其中需要指定 Windows Azure 的订阅ID （参数：subscriptionId）；构建请求数据：</p>
<pre class="scroll"><code class="csharp"> string url = string.Format(ServerUri, this.subscriptionId);<br /> var request = new ServerRequest()<br /> {<br /> AdministratorLogin = adminName,<br /> AdministratorLoginPassword = adminPwd,<br /> Location = location,<br /> };<br /></code></pre>
<p>设置Xml媒体类型序列化器，然后发送HTTP POST请求，并读取响应正文。</p>
<pre class="scroll"><code class="csharp"> HttpResponseMessage response = await this.httpClient<br /> .PostAsync&lt;ServerRequest&gt;(url, request, this.xmlFormatter);</code></pre>
<h3>将响应数据转换为 .net (如C#) 的相应对象</h3>
<p>我们可以定义 .net 对象ServerName如下：</p>
<pre class="scroll"><code class="csharp"> [XmlRoot(ElementName = "ServerName",<br /> Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]<br /> public class CreateServerResponse<br /> {<br /> [XmlText]<br /> public string ServerName { get; set; } <br /> }</code></pre>
<p>将响应正文数据转换为 C# 对象：</p>
<pre class="scroll"><code class="csharp"> CreateServerResponse server = await response.Content<br /> .ReadAsAsync&lt;CreateServerResponse&gt;(this.xmlFormatters);</code></pre>
<h3>从对象中读取信息</h3>
<p>例如我们可以读取 server.ServerName 信息，如下：</p>
<pre class="scroll"><code class="csharp"> Console.WriteLine("ServerName: {0}", server.ServerName);<br /></code></pre>
<p>创建SQL数据库服务器的完整代码片段如下：</p>
<pre class="scroll"><code class="csharp"> async public Task CreateServer(string adminName, string adminPwd, string location)<br /> {<br /> string url = string.Format(ServerUri, this.subscriptionId);<br /> var request = new ServerRequest()<br /> {<br /> AdministratorLogin = adminName,<br /> AdministratorLoginPassword = adminPwd,<br /> Location = location,<br /> };<br /> <br /> HttpResponseMessage response = await this.httpClient<br /> .PostAsync&lt;ServerRequest&gt;(url, request, this.xmlFormatter);<br /> <br /> if (!response.IsSuccessStatusCode)<br /> {<br /> this.ErrorHandler(response);<br /> return;<br /> }<br /> <br /> CreateServerResponse server = await response.Content<br /> .ReadAsAsync&lt;CreateServerResponse&gt;(this.xmlFormatters);<br /> <br /> Console.WriteLine("ServerName: {0}", server.ServerName);<br /> }<br /> <br /> private async void ErrorHandler(HttpResponseMessage response)<br /> {<br /> Console.WriteLine("Caught HttpResponseException");<br /> Error error = await response.Content<br /> .ReadAsAsync&lt;Error&gt;(this.xmlFormatters);<br /> Console.WriteLine(<br /> "Code: {0}, Message: {1}, Severity: {2}, State: {3}",<br /> error.Code,<br /> error.Message,<br /> error.Severity,<br /> error.State);<br /> }<br /></code></pre>
<p>其中Error定义如下：</p>
<pre class="scroll"><code class="csharp"> [XmlRoot(Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]<br /> public class Error<br /> {<br /> public uint Code { get; set; }<br /> public string Message { get; set; }<br /> public uint Severity { get; set; }<br /> public uint State { get; set; }<br /> }</code></pre>
<p>调用方式如下：</p>
<pre class="scroll"><code class="csharp"> SqlRestApiClient sqlRestApiClient = new SqlRestApiClient(<br /> "windows_azure_tools.pfx",<br /> "certPassword",<br /> "c4a83956-af86-4606-8881-d12c0ae12ea6");<br /> await sqlRestApiClient.CreateServer("adm1", "Pa$$word123$$", "North Central US"); </code></pre>
<p>例如，输出如下：</p>
<pre class="scroll"><code class="csharp">ServerName: ux5zdppgom</code></pre>
<p>也可以登录Windows Azure管理门户查看新创建的SQL数据库服务器：</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/3005.2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/3005.2.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/3005.2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/3005.2.png" /></a></p>
<h2>4、设置管理密码</h2>
<p>在前面创建SQL数据库服务器时我们设置了管理员帐户名称和密码，过后我们可使用&ldquo;设置服务器管理员密码&rdquo; REST API重新设置 SQL 数据库服务器的管理密码。</p>
<p>我们可以定义重置密码请求的对象如下：</p>
<pre class="scroll"><code class="csharp"> [XmlRoot(ElementName = "AdministratorLoginPassword",<br /> Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]<br /> public class AdministratorLoginPasswordRequest<br /> {<br /> [XmlText]<br /> public string AdministratorLoginPassword { get; set; }<br /> }</code></pre>
<p>重置密码方法如创建SQL服务器类似。先设定请求的Url，创建请求消息，然后发送请求，接收响应数据。</p>
<p>设置管理密码的代码片段如下：</p>
<pre class="scroll"><code class="csharp"><br /> async public Task ResetPassword(string serverName, string password)<br /> {<br /> string url = string.Format(ServerUri + "/{1}?op=ResetPassword",<br /> this.subscriptionId,<br /> serverName);<br /> var request = new AdministratorLoginPasswordRequest()<br /> {<br /> AdministratorLoginPassword = password,<br /> };<br /> <br /> HttpResponseMessage response = await this.httpClient<br /> .PostAsync(url, request, this.xmlFormatter);<br /> <br /> if (response.IsSuccessStatusCode)<br /> {<br /> Console.WriteLine(<br /> "server: {0}, password {1} is reset successfully",<br /> serverName,<br /> password);<br /> }<br /> else<br /> {<br /> this.ErrorHandler(response);<br /> }<br /> }</code></pre>
<p>调用方式如下：</p>
<pre class="scroll"><code class="csharp">await sqlRestApiClient.ResetPassword("ux5zdppgom", "Pa$word123$");</code></pre>
<p>输出如下：</p>
<pre class="scroll"><code class="csharp">server: ux5zdppgom, password Pa$word123$ is reset successfully</code></pre>
<h2>5、创建防火墙规则</h2>
<pre></pre>
<h3>为服务器创建防火墙规则</h3>
<p>默认情况下，新创建的SQL服务器禁止来自客户端的访问。我们可以为服务器创建防火墙规则，以允许来之客户端，或/和允许从与 Windows Azure 相关的应用程序和服务连接到服务器。</p>
<p>防火墙规则对象可定义如下：</p>
<pre class="scroll"><code class="csharp">[XmlRoot(ElementName = "FirewallRule",<br /> Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]<br /> public class FirewallRuleRequest<br /> {<br /> public string StartIpAddress { get; set; }<br /> public string EndIpAddress { get; set; }<br /> }</code></pre>
<p>使用类似设置管理密码的流程，一个不同之处是：我们需要发送HTTP PUT请求，而不是POST请求。代码片段如下：</p>
<pre class="scroll"><code class="csharp">async public Task CreateFirewallRule(string serverName, string ruleName, string startIp, string endIp)<br /> {<br /> string url = string.Format(FirewallUri + "/{2}",<br /> this.subscriptionId,<br /> serverName,<br /> ruleName);<br /> var request = new FirewallRuleRequest()<br /> {<br /> StartIpAddress = startIp,<br /> EndIpAddress = endIp,<br /> };<br /> <br /> HttpResponseMessage response = await this.httpClient<br /> .PutAsync(url, request, this.xmlFormatter);<br /> <br /> if (response.IsSuccessStatusCode)<br /> {<br /> Console.WriteLine("rule: {0} [{1} - {2}] written successfully",<br /> ruleName,<br /> startIp,<br /> endIp);<br /> }<br /> else<br /> {<br /> this.ErrorHandler(response);<br /> }<br /> }</code></pre>
<p>调用方式如下：</p>
<pre class="scroll"><code class="csharp">await sqlRestApiClient.CreateFirewallRule("ux5zdppgom", "rule1", "0.0.0.0", "0.0.0.0");</code></pre>
<p>输出如下：</p>
<pre class="scroll"><code class="csharp">rule: rule1 [0.0.0.0 - 0.0.0.0] written successfully</code></pre>
<p>其中起始和结束 IP 地址设置为 0.0.0.0 的防火墙规则允许从与 Windows Azure 相关的应用程序和服务连接到服务器。</p>
<h3>使用 IP 检测为服务器创建防火墙规则</h3>
<p>我们还可以使用 IP 检测为服务器创建防火墙规则。当用户由于地址转换、代理服务器等原因不知道自己的外部 IP 地址时，这可能会有用。方法与如上类似，先定义一个IpAddress对象：</p>
<pre class="scroll"><code class="csharp">[XmlRoot(ElementName = "IpAddress",<br /> <br /> Namespace = "http://schemas.microsoft.com/sqlazure/2010/12/")]<br /> public class IpAddressResponse<br /> {<br /> [XmlText]<br /> public string IpAddress { get; set; }<br /> }</code></pre>
<p>代码如下：</p>
<pre class="scroll"><code class="csharp">async public Task CreateFirewallRuleWithClientIp(string serverName, string ruleName)<br /> <br /> {<br /> string url = string.Format(FirewallUri + "/{2}?op=AutoDetectClientIP",<br /> this.subscriptionId,<br /> serverName,<br /> ruleName);<br /> <br /> var requestMessage = new HttpRequestMessage();<br /> HttpResponseMessage response = await this.httpClient<br /> .PostAsync(url, requestMessage.Content);<br /> <br /> if (!response.IsSuccessStatusCode)<br /> {<br /> this.ErrorHandler(response);<br /> return;<br /> }<br /> <br /> IpAddressResponse ip = await response.Content<br /> .ReadAsAsync&lt;IpAddressResponse&gt;(this.xmlFormatters);<br /> <br /> Console.WriteLine("rule: {0} added with client ip: {1}",<br /> ruleName,<br /> ip.IpAddress);<br /> }</code></pre>
<p>调用方式可以为：</p>
<pre class="scroll"><code class="csharp">await sqlRestApiClient.CreateFirewallRuleWithClientIp("ux5zdppgom", "rule2");</code></pre>
<p>输出如下：</p>
<pre class="scroll"><code class="csharp">rule: rule2 added with client ip: 116.96.128.226</code></pre>
<h2>6、连接到新创建的数据库服务器</h2>
<p>我们可以使用SQL Server Management Studio (SSMS) 连接到如上新创建的SQL数据库服务器。</p>
<p>输入服务器名称，验证方式选择为：SQL Server Authentication，然后输入用户名和密码。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/5672.3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/5672.3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/5672.3.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/5672.3.png" border="0" alt="" /></a></p>
<p>点击连接，连接成功后我们可以看到：</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/7382.4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/7382.4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/7382.4.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/7382.4.png" border="0" alt="" /></a></p>
<p>有关SQL Database 数据库管理 API的更多信息，可以<a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg715283">参考msdn中相应内容</a> 。</p>
<p>软件开发工程师&nbsp; 苏从勇</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/33/29/40/AccessSqlRestApi.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-33-29-40/AccessSqlRestApi.zip">AccessSqlRestApi.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>扩展事件在Denali CTP3里的新UI（二）</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/denali-ctp3ui</link>
      <pubDate>Tue, 08 Nov 2011 22:28:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/11/08/denali-ctp3ui/</guid>
      <description><![CDATA[在前面一篇博文里我们介绍了如何使用扩展事件（XEvent）在Denali CTP3里的新UI创建和修改XEvent...]]></description>
      <content:encoded><![CDATA[<p>在前面一篇博文里我们介绍了如何使用扩展事件（XEvent）在Denali CTP3里的新UI创建和修改XEvent session，本文我们将介绍如何用新UI来显示和分析数据，我们将试图找到一个workload中平均开销最大的query。</p>
<p>在Object Explorer里右键点击前文创建的blogtest session，选择Watch Live Data，如图1所示，这将在SSMS里打开一个新的Live Data窗口，这时我们可以执行我们的workload，workload可以是应用程序的运行，也可以是一段SQL的执行，或者重播Profiler记录的SQL Trace，这里我们在SSMS的另一个窗口执行创建Northwind数据库的instnwnd.sql来模拟一个workload。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/3704.image_4ADB8CF3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/3704.image_5F00_4ADB8CF3.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/6825.image_thumb_4FDDCAA2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/6825.image_5F00_thumb_5F00_4FDDCAA2.png" width="335" height="380" /></a></p>
<p align="center">图1 启动Live Data窗口</p>
<p>当instnwnd.sql执行完毕后，先前打开的Live Data窗口会出现很多行数据，这些就是blogtest session所记录的sql_statement_starting和sql_statement_completed事件，这时可以点击工具栏上的Stop Data Feed按钮（工具栏第二个按钮），这样可以避免和workload无关的事件继续被Live Data窗口显示，如图2 所示。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/8081.image_3BE4380C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/8081.image_5F00_3BE4380C.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/0636.image_thumb_27123F8C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/0636.image_5F00_thumb_5F00_27123F8C.png" width="558" height="427" /></a></p>
<p align="center">图2 Live Data窗口</p>
<p>你的Live Data窗口可能只有2个列，name和timestamp，这是仅有的2个所有扩展事件共有的列，你可以选择工具栏上的Choose Columns&hellip;按钮添加/删除需要显示的列，我增加了3个列database_name，duration和statement，如图3所示。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/7802.image_56147B63.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/7802.image_5F00_56147B63.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/1220.image_thumb_1AE09F98.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/1220.image_5F00_thumb_5F00_1AE09F98.png" width="558" height="369" /></a></p>
<p align="center">图3 选择列</p>
<p>我们要找到Northwind数据库里平均执行时间最长的query，首先我们可以过滤不必要的事件，前文曾提到过Predicate可以在SQL Server端避免不需要的事件被产生，我们同时也支持客户端的过滤器，这可以帮助你做各种分析。点击工具栏上的Filters&hellip;按钮，这将打开Filters对话框，这里我们设置两个条件name=sql_statement_completed And database_name=Northwind，如图4所示。为了避免输入错误，你可以从事件列表里拷贝粘帖，你还可以右键点击某个Cell然后选择Filter by this Value，这将自动为你添加一个子句并And到原有条件上。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/7802.image_5FACC3CC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/7802.image_5F00_5FACC3CC.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/3386.image_thumb_08D45C0B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/3386.image_5F00_thumb_5F00_08D45C0B.png" width="522" height="333" /></a></p>
<p align="center">图4 Filter对话框</p>
<p>过滤掉不必要的事件后我们按照statement来做分组，点击工具栏上的Grouping&hellip;按钮，把statement移动到右边，点击OK，如图5所示。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/4747.image_4DA0803F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/4747.image_5F00_4DA0803F.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/4331.image_thumb_0506916E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/4331.image_5F00_thumb_5F00_0506916E.png" width="489" height="393" /></a></p>
<p align="center">图5 Grouping对话框</p>
<p>分组的目的是为了计算每个分组上duration的平均值，下面可以点击工具栏上的Aggregation&hellip;按钮，我们在duration上选择AVG，然后选择在duration(AVG)上按降序排序，如图6所示。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/5824.image_3C6CA29C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/5824.image_5F00_3C6CA29C.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/7065.image_thumb_36B188F6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/7065.image_5F00_thumb_5F00_36B188F6.png" width="366" height="458" /></a></p>
<p align="center">图6 Aggregation对话框</p>
<p>这样duration平均值最大的分组将被显示在第一行，我执行instnwnd.sql的workload里duration最大的分组是INSERT "Order Details" VALUES(10444,17,31.2,10,0)，它的duration是134206微秒，如图7所示。这样我们就找到了平均开销最大的query。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/0624.image_6E179A24.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/0624.image_5F00_6E179A24.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/3252.image_thumb_320B586F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/3252.image_5F00_thumb_5F00_320B586F.png" width="558" height="427" /></a></p>
<p align="center">图7 开销最大的query</p>
<p>前文在创建blogtest session时增加了event_file的target，如果你打开SQL Server所在机器的Log目录（比如C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Log），你会发现一堆blogtest*.xel，你可以双击任何一个文件在SSMS里打开和Live Data类似的窗口，也可以通过SSMS的File|Open|Merge Extended Event Files&hellip;菜单在同一窗口里打开多个文件，后面的数据分析和Live Data窗口是一样的。</p>
<p>软件开发工程师 徐进</p>]]></content:encoded>
    </item>
    <item>
      <title>扩展事件在Denali CTP3里的新UI（一）</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/denali-ctp3ui-2</link>
      <pubDate>Tue, 08 Nov 2011 22:19:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/11/08/denali-ctp3ui-2/</guid>
      <description><![CDATA[去年年底时我曾经写过一篇介绍扩展事件（XEvent）在Denali CTP1里新功能的博文，在CTP1中我们提供了一个Object Model和一个简单的UI，在不久前发布的Denali...]]></description>
      <content:encoded><![CDATA[<p>去年年底时我曾经写过一篇介绍扩展事件（XEvent）在Denali CTP1里新功能的<a href="http://blogs.msdn.com/b/sqlcrd/archive/2010/12/23/xevent-feature-in-sql-denali-ctp1.aspx">博文</a>，在CTP1中我们提供了一个Object Model和一个简单的UI，在不久前发布的<a href="http://www.microsoft.com/sqlserver/en/us/future-editions.aspx">Denali CTP3</a>里我们对XEvent的UI做了更好的支持，本文将进行介绍。</p>
<p>首先我们提供了一个功能强大的对话框用于创建/修改SQL Server里的XEvent Session，你可以在Object Explorer里右键点击Extended Events下的Sessions节点选择New Session&hellip;来新建一个Session，如图1所示。这将打开新建Session对话框，这个对话框有4个页面，分别是General、Events、Data Storage （Targets）、Advanced页面，下面我们一一介绍。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/2313.image_670EC382.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/2313.image_5F00_670EC382.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/0827.image_thumb_3E23AE79.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/0827.image_5F00_thumb_5F00_3E23AE79.png" width="389" height="412" />&nbsp;</a></p>
<p align="center">图1 新建Session</p>
<p>第一个General页面里你可以输入Session的名字，选择一些选项，比如Session是否和SQL Server一起启动，Session创建成功后是否立即启动该Session等等。我们支持与Profiler里模板类似的概念，只要选择一个模板，Event（包括Action和Predicate）和Target以及某些选项就自动选择好了，但是在CTP3里只有一个Standard模板，这个模板所选择的事件和Profiler里的Standard模板相对应。你也可以把自己创建的Session作为模板保存起来以备后用，保存模板只需要右键点击某个Session然后选择Export Session&hellip;即可。这里我们输入blogtest，并选择&rdquo;Start the event session immediately after session creation&rdquo;让blogtest在创建成功后立即启动，如图2所示。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/1817.image_7C3CC92A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/1817.image_5F00_7C3CC92A.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/2577.image_thumb_5A04BDA4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/2577.image_5F00_thumb_5F00_5A04BDA4.png" width="558" height="396" /></a></p>
<p align="center">图2 General页面</p>
<p>点击左边的Select a page列表里的Events切换到Events页面，这个页面是最复杂的，也是UI能够给你提供最大帮助的地方。你首先看到它分为左右两部分，左边是事件库，所有在SQL Server里注册的扩展事件都列在这里，右边是你选择的事件。在事件的选择上我们做了很多工作来帮助您：1. 你可以点击抬头排序，默认是按事件名排序；2. 可以输入关键字进行过滤，比如图3中我们输入sql_，所有名字含有sql_字样的事件都被列了出来并且高亮显示，过滤可以作用在事件名称上，也可以在事件的名称和描述上，或者事件所含的Fields上，你可以点击事件库右上方的ComboBox切换，所有的过滤都有高亮显示；3. 在Category和Channel上我们实现了和Excel类似的过滤过能，你可以点击Channel右边的下拉箭头选择只看Analytic channel的事件。</p>
<p>找到你需要的事件后，双击它或者点击两部分中间的&gt;按钮加入选择，在这里我们选择了sql_statement_starting和sql_statement_completed事件。你可能注意到了有两个小图标（闪电和漏斗）显示在已选择事件的列表中，下面会介绍。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/5618.image_1ED0E1D9.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/5618.image_5F00_1ED0E1D9.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/1805.image_thumb_406D0AAA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/1805.image_5F00_thumb_5F00_406D0AAA.png" width="558" height="356" /></a></p>
<p align="center">图3 在Events页面里选择事件</p>
<p>点击Events页面右上方的Configure按钮，页面将会滑动，事件库被隐藏，而配置事件的页面将出现，如图4所示，当然你点击Select可以回到刚才的页面。你会看到闪电和漏斗图标分别出现在了右边配置页面的Actions标签和Filter标签上，闪电代表的是该事件上有多少Global Fields（Actions）关联，漏斗代表该事件有没有Filter（Predicate）关联。</p>
<p>Action是指在发生事件的时刻可以读取的环境数据，比如event_sequence可以为所有事件排序，Profiler里每个事件都含有EventSequence列，而在XEvent里则被作为Action来实现了。</p>
<p>Predicate可以减少不必要的事件收集，比如我可以配置sql_statement_starting事件的Predicate为database_name=&rsquo;Northwind&rsquo;，那么发生在其他数据库的sql_statement_starting事件就不会被该Session所收集，Profiler可以为所有事件设置一个Column Filter，而XEvent支持为每个Event设置各自独立不同的Predicate，有兴趣可以参考MSDN里扩展事件对Action和Predicate的介绍。Event Fields标签列出所有该Event的列，某些Event会把一些开销比较大的列作为可选的列，你可以点击前面的CheckBox选择是否收集该列数据，比如sql_statement_starting的statement列就可以被取消选择。</p>
<p>你可以同时选择多个Event并选择/取消Action或配置Filter，在这里我们为sql_statement_starting和sql_statement_completed事件选择database_name action，不添加Filter并保持Event Fields默认值。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/7268.image_52D55B5F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/7268.image_5F00_52D55B5F.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/1817.image_thumb_225ED6E9.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/1817.image_5F00_thumb_5F00_225ED6E9.png" width="558" height="371" /></a></p>
<p align="center">图4 在Events页面里配置事件</p>
<p>第三个页面是Data Storage页面，在这个页面里可以选择为Session添加不同的Target，这里我们选择event_file target并保持默认配置。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/7652.image_06D9D4E6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/7652.image_5F00_06D9D4E6.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/3630.image_thumb_3D67802A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/3630.image_5F00_thumb_5F00_3D67802A.png" width="558" height="356" /></a></p>
<p align="center">图5 Data Storage页面</p>
<p>最后一个页面是Advanced页面，这是可以设置控制Session行为的高级选项。有一个选项需要特别注意，&rdquo;Maximum dispatch latency&rdquo;，它描述了事件从被触发到写入到Target最长的等待时间，默认值是30秒，如果你使用和Profiler client-side tracing类似的Live Monitoring功能，你可能会希望把它改小，这样事件被触发后可以尽快地显示在SSMS里，但需要注意到是改小它会增加SQL Server的开销，这里我们把它改成5秒。</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/1805.image_21E27E27.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/1805.image_5F00_21E27E27.png"><img style="display: inline; background-image: none;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/metablogapi/6266.image_thumb_66AEA25B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59-metablogapi/6266.image_5F00_thumb_5F00_66AEA25B.png" width="558" height="352" /></a></p>
<p align="center">图6 Advanced页面</p>
<p>点击OK，blogtest session将会被创建成功并显示在Object Explorer里，在Session被创建后，你可以在Object Explorer里右键点击该Session并选择Properties，这将打开和创建Session相同的对话框，进行修改后点击OK即可完成。</p>
<p>右键点击blogtest选择&rdquo;Watch Live Data&rdquo;，这将打开前面提到的Live Monitoring功能，我们将会在后续的博文里继续介绍它。</p>
<p>软件开发工程师 徐进</p>]]></content:encoded>
    </item>
    <item>
      <title>利用Contained Database和DAC来开发基于SQL Server "Denali"和SQL Azure之上的应用程序</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/contained-databasedacsql-server-denalisql-azure</link>
      <pubDate>Mon, 17 Oct 2011 23:46:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/10/17/contained-databasedacsql-server-denalisql-azure/</guid>
      <description><![CDATA[大家好！
在刚刚结束的Microsoft TechEd China 2011中，我们在分会的一个小时里为大家讲解并演示了如何利用Contained Database和DAC来开发基于SQL...]]></description>
      <content:encoded><![CDATA[<p>大家好！</p>
<p>在刚刚结束的Microsoft TechEd China 2011中，我们在分会的一个小时里为大家讲解并演示了如何利用Contained Database和DAC来开发基于SQL Server "Denali"和SQL Azure之上的应用程序。为了能够和更多的开发人员和DBA介绍和分享CDB及DAC，并提供相关资源和工具下载的链接，我们特撰文如下，希望有所帮助。</p>
<p><strong>背景</strong></p>
<p>让应用程序的数据层可以在本地SQL Server服务器、私有云、共有云之间方便的部署、移动、升级和管理，正在迅速成为当前云时代的关键技术之一。SQL Server &ldquo;Denali&rdquo; 的新增功能&mdash;&mdash;包含的数据库Contained Database (CDB) 和数据层应用DAC正是为了满足这一需求而研发并推出的。这两项技术在一起所提供的功能，将SQL Server应用程序的开发、部署、和不同环境之间的移动完全流程化了，让开发人员和DBA能够淋漓发挥，游刃有余。</p>
<p><strong>进展</strong></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/0434.1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/0434.1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/0434.1.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/0434.1.png" /></a></p>
<p><strong>亮点简述</strong></p>
<ul>
<li>包含的数据库Contained Database (CDB)：排序规则和安全认证已经可以内置在CDB中；</li>
<li>数据层应用DAC：BACPAC既包含数据库的元信息，也包含数据；原地升级；可以防止篡改；</li>
<li>代码名为&ldquo;Juneau&rdquo;的SQL Server开发工具：基于Visual Studio 2010，可以从现有数据库中提取信息新建项目；智能感知（IntelliSense）；可深层验证；版本化build；可声明目标平台，定义服务器选择策略；界面友好直观；</li>
<li>导出导入工具：广泛支持SQL Server 2000（仅支持导出）、2005、2008、2008 R2、SQL Server Denali及SQL Azure。</li>
</ul>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6746.2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6746.2.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6746.2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6746.2.png" /></a></p>
<p>相关资源及下载：</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ff929071(v=sql.110).aspx">微软MSDN 英文介绍 &ldquo;包含的数据库&rdquo;</a></li>
<li><a href="http://www.sqlazurelabs.com/importexport.aspx">SQL数据库导入导出工具</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ff381683(SQL.100).aspx">微软技术白皮书 英文《SQL Server 2008 R2 中的数据层应用程序》</a></li>
<li><a href="http://msdn.microsoft.com/en-us/data/gg427686">SQL Server开发工具"Juneau"</a></li>
<li><a href="http://social.microsoft.com/forums/zh-CN/sqlserverzhchs">微软MSDN 中文 SQL Server论坛</a></li>
</ul>
<p>最后，为了让更多的开发人员和DBA了解CDB及DAC，我们会在10月24日进行一个同样内容的网络直播，详细信息和注册请参考<a href="http://technet.microsoft.com/zh-cn/hh506399">http://technet.microsoft.com/zh-cn/hh506399</a> 。</p>
<p>谢谢大家！</p>
<p>微软SQL Server产品组　刘劲浩，刘春雨</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Migration Assistant简介（二）</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/sql-server-migration-assistant</link>
      <pubDate>Tue, 07 Jun 2011 01:58:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/06/07/sql-server-migration-assistant/</guid>
      <description><![CDATA[在前一篇博文里我们介绍了使用SSMA for Oracle...]]></description>
      <content:encoded><![CDATA[<p>在<a href="http://blogs.msdn.com/b/sqlcrd/archive/2011/05/31/sql-server-migration-assistant-1.aspx">前一篇博文</a>里我们介绍了使用SSMA for Oracle 5.0做Oracle数据库迁移之前的评估，本文中我们将介绍如何做Schema迁移和数据迁移。</p>
<p>首先我们需要连接目标数据库，点击工具条上的Connect to SQL Server，输入Server name，在Database里输入HR，如图1所示。如果你的SQL Server里不存在HR数据库，点击Connect后SSMA会提示错误，问你是否创建HR数据库，选择Yes。HR数据库创建后SSMA可能会提示SQL Server Agent未运行，这仅在使用服务器端数据迁移时才会用到，默认情况下我们使用的是客户端数据迁移，所以可以点击Continue忽略。&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1004.SSMA01.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1004.SSMA01.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1004.SSMA01.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/449x356/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1004.SSMA01.png" border="0" /></a></p>
<p>图1 连接到SQL Server服务器</p>
<p>连接上SQL Server服务器后我们就可以迁移Schema了，这里的Schema指数据以外的数据库定义，比如表结构、视图定义、存储过程等等。右键单击Oracle Metadata Explorer里的HR数据库，选择Convert Schema，如图2所示。SSMA运行一段时间后会在最下方的Output栏里显示转换是否有错误、警告或信息。这时你可以展开SQL Server Metadata Explorer里HR数据库的dbo schema，在Procedures文件夹下会发现ADD_JOB_HISTORY等存储过程，Tables文件夹下会发现COUNTRIES等表，说明Schema的迁移已经成功。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1778.SSMA02.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1778.SSMA02.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1778.SSMA02.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/305x318/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1778.SSMA02.png" border="0" /></a></p>
<p>图2 转换Schema</p>
<p>如果这时你使用SQL Server客户端工具SQL Server Management Studio或者Visual Studio的Server Explorer查看SQL Server上的HR数据库，你会发现找不到前面所说的存储过程、表或者视图。这是因为Convert Schema菜单项只是在SSMA的Project里进行了转换，并未转换到数据库。这么设计为了让你可以在同步到SQL Server之前再做些其他修改，比如REGIONS表里的REGION_ID列在Oracle里是NUMBER类型，它被SSMA转换成了最安全的float(53)类型，如果你知道REGION_ID就是个整形，你可以把它修改为int类型，当然你最好对COUNTRIES表的REGION列也做同样的修改。</p>
<p>在确认Schema迁移没有问题后，你可以同步到SQL Server数据库了，在SQL Server Metadata Explorer里右键点击HR数据库，选择Synchronize with Database，如图3所示。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/0456.SSMA03.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/0456.SSMA03.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/0456.SSMA03.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/307x198/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/0456.SSMA03.png" border="0" /></a></p>
<p>图3 同步HR数据库到SQL Server</p>
<p>这时可能会再次弹出SQL Server连接对话框和SQL Server Agent未运行的警告，确认后会显示Synchronize with the Database对话框，如图4所示。对话框里列出了SQL Server数据库和SSMA的树结构的差别，可以选择Hide Equal Objects来过滤掉两边相同的对象。由于我们连接的是新创建的HR数据库，所以左侧显示的都是 [Not Found] 状态，如果你之前做过同步这里会显示不同的状态，这里我们点击OK继续。等待右下角的进度条走完，留意主窗口Output栏是否报错，没有报错的话SQL Server里的对象应该已经创建好了。&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/3225.SSMA04.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/3225.SSMA04.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/3225.SSMA04.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x469/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/3225.SSMA04.png" border="0" /></a></p>
<p>图4 Synchronize with the Database对话框</p>
<p>再次使用SQL Server Management Studio或者Visual Studio来查看HR数据库中的对象，会发现一些$SSMA打头的表或者存储过程等，这些是迁移一些特殊对象（比如Oracle的Sequence对象）所创建出来的辅助对象。</p>
<p>在成功迁移了Schema之后，我们就可以来进行迁移的最后一步：数据迁移。有了SSMA的帮助数据迁移也非常简单，右键点击Oracle Metadata Explorer里的HR数据库，选择Migrate Data，如图5所示。SSMA会再次提示Oracle和SQL Server的连接信息，如果之前做过数据迁移可能会有数据覆盖的警告信息，如果有点击Continue继续。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2781.SSMA05.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/2781.SSMA05.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2781.SSMA05.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/309x314/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/2781.SSMA05.png" border="0" /></a></p>
<p>图5 数据迁移</p>
<p>如果你的数据库数据比较多，SSMA会运行较长一段时间，在这过程中你可以随时点击工具栏上的Stop按钮来停止数据迁移。迁移结束后，SSMA会有一个数据迁移报告，如图6所示。该报告描述了迁移过程中那些表的数据被成功迁移，多少行数据被迁移以及耗时多少等等。&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6283.SSMA06.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6283.SSMA06.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6283.SSMA06.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x354/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6283.SSMA06.png" border="0" /></a></p>
<p>图6 数据迁移报告</p>
<p>本文简单介绍了如何使用SSMA for Oracle 5.0来帮助我们把一个Oracle数据库迁移到SQL Server数据库，包括迁移评估、Schema迁移以及数据迁移。</p>
<p>软件开发工程师 徐进</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server Migration Assistant简介（一）</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/sql-server-migration-assistant-2</link>
      <pubDate>Mon, 30 May 2011 20:31:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/05/30/sql-server-migration-assistant-2/</guid>
      <description><![CDATA[SQL Server Migration Assistant（简称SSMA）是由微软发布的帮助客户更容易地从Oracle/Sybase/MySQL/Access迁移到SQL Server以及SQL...]]></description>
      <content:encoded><![CDATA[<p>SQL Server Migration Assistant（简称SSMA）是由微软发布的帮助客户更容易地从Oracle/Sybase/MySQL/Access迁移到SQL Server以及SQL Azure的一个工具集，几周前我们刚刚发布了<a href="http://blogs.msdn.com/b/ssma/archive/2011/04/28/sql-server-migration-assistant-v5-0-is-now-available.aspx">SSMA 5.0</a>版本，该版本支持了最新的代号为Denali的SQL Server的CTP版本，并且增加了对SQL Azure迁移的支持。下表说明了SSMA 5.0所支持的迁移矩阵：</p>
<table width="612" cellpadding="0" cellspacing="0" border="0" class="MsoNormalTable">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; height: 33.65pt;">
<td width="78" style="width: 58.5pt; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext 1.0pt; mso-border-top-alt: solid windowtext .5pt; background: #CCC0DA; padding: 0in 5.4pt 0in 5.4pt; height: 33.65pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">Migrating From</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="138" style="width: 103.5pt; border: solid windowtext 1.0pt; border-left: none; mso-border-top-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext 1.0pt; mso-border-right-alt: solid windowtext 1.0pt; background: #CCC0DA; padding: 0in 5.4pt 0in 5.4pt; height: 33.65pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">Using SSMA Tool</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="204" style="width: 153.0pt; border: solid windowtext 1.0pt; border-left: none; mso-border-top-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext 1.0pt; mso-border-right-alt: solid windowtext 1.0pt; background: #D8E4BC; padding: 0in 5.4pt 0in 5.4pt; height: 33.65pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">To SQL Server <br />(2005, 2008, 2008 R2, &ldquo;Denali&rdquo;)</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="192" style="width: 2.0in; border: solid windowtext 1.0pt; border-left: none; mso-border-top-alt: solid windowtext .5pt; mso-border-bottom-alt: solid windowtext 1.0pt; mso-border-right-alt: solid windowtext 1.0pt; background: #D8E4BC; padding: 0in 5.4pt 0in 5.4pt; height: 33.65pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">To SQL Azure</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 1; height: 15.7pt;">
<td width="78" style="width: 58.5pt; border: solid windowtext 1.0pt; border-top: none; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">Sybase</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="138" style="width: 103.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt;"><a href="http://go.microsoft.com/?linkid=9771006"><span style="mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: blue; mso-font-kerning: 0pt; text-decoration: none; text-underline: none;">SSMA for Sybase</span></a></span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="204" style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic;</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="192" style="width: 2.0in; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic; (New in SSMA 5.0)</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 2; height: 15.7pt;">
<td width="78" style="width: 58.5pt; border: solid windowtext 1.0pt; border-top: none; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">Oracle</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="138" style="width: 103.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt;"><a href="http://go.microsoft.com/?linkid=9771004"><span style="mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: blue; mso-font-kerning: 0pt; text-decoration: none; text-underline: none;">SSMA for Oracle</span></a></span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="204" style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic;</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="192" style="width: 2.0in; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;"></td>
</tr>
<tr style="mso-yfti-irow: 3; height: 15.7pt;">
<td width="78" style="width: 58.5pt; border: solid windowtext 1.0pt; border-top: none; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">MySQL</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="138" style="width: 103.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt;"><a href="http://go.microsoft.com/?linkid=9771005"><span style="mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: blue; mso-font-kerning: 0pt; text-decoration: none; text-underline: none;">SSMA for MySQL</span></a></span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="204" style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic;</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="192" style="width: 2.0in; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic;</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 4; mso-yfti-lastrow: yes; height: 15.7pt;">
<td width="78" style="width: 58.5pt; border: solid windowtext 1.0pt; border-top: none; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">Access</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="138" style="width: 103.5pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="left"><span style="font-size: 11.0pt;"><a href="http://go.microsoft.com/?linkid=9771007"><span style="mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: blue; mso-font-kerning: 0pt; text-decoration: none; text-underline: none;">SSMA for Access</span></a></span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="204" style="width: 153.0pt; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic;</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
<td width="192" style="width: 2.0in; border-top: none; border-left: none; border-bottom: solid windowtext 1.0pt; border-right: solid windowtext 1.0pt; padding: 0in 5.4pt 0in 5.4pt; height: 15.7pt;">
<p class="MsoNormal" align="center"><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; mso-ascii-font-family: Calibri; mso-fareast-font-family: SimSun; mso-hansi-font-family: Calibri; mso-bidi-font-family: Calibri; color: black; mso-font-kerning: 0pt;">&radic;</span><span style="font-size: 11.0pt; mso-bidi-font-size: 12.0pt; font-family: SimSun; mso-bidi-font-family: SimSun; color: #333333; mso-font-kerning: 0pt;"><o:p></o:p></span></p>
</td>
</tr>
</tbody>
</table>
<p>这里我们选择SSMA for Oracle 5.0为例介绍一下SSMA如何帮助您从Oracle迁移到SQL Server 2008 R2。首先我们从<a href="http://go.microsoft.com/?linkid=9771004">这里</a>下载SSMA for Oracle 5.0的压缩包，解压缩后有两个exe文件，SSMA for Oracle 5.0.exe是工具的安装包，SSMA for Oracle 5.0 Extension Pack.exe必须安装在SQL Server 2008 R2所在服务器，用来创建一些辅助运行需要的数据库表和存储过程等。</p>
<p>首次运行SSMA for Oracle需要一个License，如图1所示，你可以点击链接，然后根据提示填写个人信息后免费申请，下载保存之后返回这个对话框选择你保存License的目录然后点击Refresh License按钮即可运行SSMA for Oracle了。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6254.SSMA01.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6254.SSMA01.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6254.SSMA01.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6254.SSMA01.png" border="0" /></a></p>
<p>图1&nbsp; License Management对话框</p>
<p>在主窗口File菜单中选择New Project&hellip;菜单项将显示图2所示的对话框，输入项目的名字，选择SQL Server 2008作为迁移的目标数据库版本。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2425.SSMA02.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/2425.SSMA02.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2425.SSMA02.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/2425.SSMA02.png" /></a></p>
<p>图2&nbsp; New Project对话框</p>
<p>我们将使用Oracle XE的HR schema为例（下文称之为HR数据库以避免歧义，但其实Oracle并没有SQL Server数据库类似的概念）。SSMA为提高性能，缺省情况下不加载某些示例数据库（包括HR数据库），这个缺省设置可以通过Project Settings来修改，选择Tools菜单的Project Settings菜单项，在弹出的对话框里点击General再选择Loading System Objects，然后勾选HR，如图3所示。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/5037.SSMA03.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/5037.SSMA03.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/5037.SSMA03.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/5037.SSMA03.png" /></a></p>
<p>图3 Project Settings对话框</p>
<p>然后我们连接Oracle服务器，点击工具条上的Connect to Oracle，输入Server名称、SID和用户名/密码，如图4所示。连接后会有个警告对话框告诉你hr用户没有足够的权限。由于我们只需要迁移HR数据库，这里可以点击Continue忽略它。如果你的Oracle服务器上有很多数据库，数据加载可能需要比较长的时间，请耐心等待</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/8078.SSMA04.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/8078.SSMA04.png"><img height="261" width="458" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/8078.SSMA04.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/8078.SSMA04.png" /></a></p>
<p>图4 连接到Oracle服务器</p>
<p>连接上Oracle后我们首先评估一下迁移HR数据库会不会碰到问题，如果碰到问题大约需要多长时间来解决。评估并不需要连接目标SQL Server，只需要在左上方的树里展开Oracle服务器名称，然后展开Schemas，右键点击HR并选择Create Report，如图5所示。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6136.SSMA05.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6136.SSMA05.png"><img height="343" width="340" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6136.SSMA05.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/6136.SSMA05.png" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/8738.SSMA05.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/8738.SSMA05.png"></a></p>
<p>图5 评估HR数据库</p>
<p>SSMA运行一段时间后会打开一个评估报告的对话框，如图6所示。这个评估报告很有用，里面会列出HR数据库里各种对象（包括函数、包、存储过程、表和视图等）能够成功迁移的比例，你可以在左边的树里选择你需要查看的某个对象，比如存储过程，比较Oracle的PL/SQL语法和迁移后的TSQL语法。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1033.SSMA06.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1033.SSMA06.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1033.SSMA06.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1033.SSMA06.png" /></a></p>
<p>图6 评估报告</p>
<p>图7是一个包含有错误的评估报告，当包含错误时，SSMA会估算手工做转换大约需要多少时间，这样你就可以使用评估报告来帮助你做数据库迁移的时间规划。</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1452.SSMA07.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1452.SSMA07.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1452.SSMA07.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-97-59/1452.SSMA07.png" border="0" /></a></p>
<p>图7 一个包含错误的评估报告</p>
<p>（未完待续）</p>
<p>软件开发工程师 徐进</p>]]></content:encoded>
    </item>
    <item>
      <title>StreamInsight手札（五）——使用EventFlowDebugger调试事件流</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/streaminsighteventflowdebugger</link>
      <pubDate>Fri, 15 Apr 2011 00:48:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/04/15/streaminsighteventflowdebugger/</guid>
      <description><![CDATA[StreamInsight提供了EventFlowDebugger以方便用户进行事件流调试。这一工具拥有直观的图形化界面，支持即时调试和日志调试，支持跟踪和回溯。
本文将介绍EventFlowDeb...]]></description>
      <content:encoded><![CDATA[<p>StreamInsight提供了EventFlowDebugger以方便用户进行事件流调试。这一工具拥有直观的图形化界面，支持即时调试和日志调试，支持跟踪和回溯。</p>
<p>本文将介绍EventFlowDebugger基本使用方法。</p>
<p>EventFlowDebugger分为在线模式和离线模式两种使用方法。在线模式下，用户连接到StreamInsight服务器，在线进行调试，或者录制某一段时间的事件流供离线模式使用。离线模式下，用户通过加载Trace文件对事件流进行调试。</p>
<p>下面对其主要功能进行介绍。</p>
<p><strong>连接到服务器（在线）</strong></p>
<p>在线模式需要用户连接到一个正在运行的StreamInsight服务器。</p>
<p>StreamInsight服务器有两种，嵌入服务器和远程服务器：</p>
<ul>
<li><span lang="ZH-CN">嵌入服务器（</span><span>Embedded Server</span><span lang="ZH-CN">）：<span style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">var </span><span style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #333333; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">cepServerEmbedded = </span><span style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">Server</span><span style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #333333; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">.Create();</span></span></li>
<li><span lang="ZH-CN">远程服务器（Remote Server）：<span style="FONT-FAMILY: 'Courier New'; COLOR: blue; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">var </span><span style="FONT-FAMILY: 'Courier New'; COLOR: #333333; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">cepServerRemote = </span><span style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">Server</span><span style="FONT-FAMILY: 'Courier New'; COLOR: #333333; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'">.Connect(<span style="color: #a31515;">"</span></span><span style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #a31515; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">http://servername/StreamInsight"</span><span style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; COLOR: #333333; FONT-SIZE: 10pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">);</span></span></li>
</ul>
<div></div>
<p>如果使用远程服务器，则用户可以直接连接远程服务器的地址。如果程序使用嵌入服务器，则需要在程序中添加如下代码：&nbsp;</p>
<p class="MsoNormal"><span style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 9.5pt">ServiceHost</span><span style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 9.5pt"> _dvHost = <span style="COLOR: blue">null</span>;<br /></span><span style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 9.5pt">IManagementService</span><span style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 9.5pt"> _service = <span style="COLOR: blue">null</span>;<br /></span><span style="FONT-FAMILY: 'Courier New'; COLOR: #2b91af; FONT-SIZE: 9.5pt">IManagementService</span><span style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 9.5pt"> proxy = server.CreateManagementService();<br /></span><span style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 9.5pt">_service = proxy;<br /></span><span style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 9.5pt">_dvHost = <span style="COLOR: blue">new</span> <span style="COLOR: #2b91af">ServiceHost</span>(proxy);<br /><br /></span><span style="font-family: 'Courier New'; color: #2b91af; font-size: 9.5pt;">WSHttpBinding</span><span style="font-family: 'Courier New'; font-size: 9.5pt;"> binding = <span style="color: blue;">new</span> <span style="color: #2b91af;">WSHttpBinding</span>(<span style="color: #2b91af;">SecurityMode</span>.Message);<br /></span><span style="font-family: 'Courier New'; font-size: 9.5pt;">binding.Security.Message.ClientCredentialType = <span style="color: #2b91af;">MessageCredentialType</span>.Windows;<br /></span><span style="font-family: 'Courier New'; font-size: 9.5pt;">binding.MaxReceivedMessageSize = 4655360;<br /></span><span style="font-family: 'Courier New'; font-size: 9.5pt;">_dvHost.AddServiceEndpoint(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">IManagementService</span>), binding, <span style="color: #a31515;">"<span style="background: yellow; mso-highlight: yellow;">http://localhost:8080</span>"</span>);<br /></span><span style="font-family: 'Courier New'; font-size: 9.5pt;">_dvHost.Open();<o:p></o:p></span></p>
<p>同时需要添加引用Microsoft.ComplexEventProcessing.ManagementService.dll，输入加亮部分地址就可以连接嵌入服务器了。</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/8004.sinotes51.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/8004.sinotes51.png" border="0" /></p>
<p><strong>连接到服务器的几种常见错误</strong></p>
<p><strong>错误1</strong></p>
<p><span style="font-family: 'Courier New'; color: #333333; font-size: 10pt; mso-fareast-font-family: 'Times New Roman';">HTTP could not register URL http://+:8001/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details).</span><span style="font-family: 'Courier New'; color: #333333; font-size: 10pt;"><o:p></o:p></span></p>
<p>这个错误是由于用户对访问的URL没有权限。解决方法如下：</p>
<ol>
<li>
<div class="MsoListParagraphCxSpFirst"><span style="font-family: 'Courier New'; color: #333333; font-size: 10pt; mso-fareast-font-family: 'Times New Roman';">netsh http add urlacl url=http://</span><span style="font-family: 'Courier New'; color: #333333; font-size: 10pt;">localhost</span><span style="font-family: 'Courier New'; color: #333333; font-size: 10pt; mso-fareast-font-family: 'Times New Roman';">:8090/MyStreamInsightServer user=&lt;domain\userid&gt;</span></div>
</li>
<li>
<div class="MsoListParagraphCxSpFirst"><span style="font-family: 'Courier New'; color: #333333; font-size: 10pt; mso-fareast-font-family: 'Times New Roman';">net localgroup StreamInsightUsers$Default /ADD SOMEDOMAIN\someuser<o:p></o:p></span></div>
</li>
</ol>
<p><strong>错误2</strong></p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1464.sinotes52.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/1464.sinotes52.png" border="0" /></p>
<p>一般是URL地址不正确或者StreamInsight程序没有运行。</p>
<p><strong>错误3</strong></p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/8640.sinotes53.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/8640.sinotes53.png" border="0" /></p>
<p>&nbsp;一般是由于StreamInsight程序没有运行。</p>
<p><strong>错误4</strong></p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6165.sinotes54.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/6165.sinotes54.png" border="0" /><br />&nbsp;<br />一般是由于用户没有添加到正确的组。注意检查如下几个用户组：StreamInsightUsers$***, Performance Log Users</p>
<p><strong>错误5</strong></p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/6371.sinotes55.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/6371.sinotes55.png" border="0" /></p>
<p>这个错误一般是由于用户程序中有断点。</p>
<p><strong>显示查询（在线和离线）</strong></p>
<p>在通过在线模式连接服务器或者离线模式打开trace文件后，用户可以查看查询的图形化界面：</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2772.sinotes56.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/2772.sinotes56.png" border="0" /></p>
<p>在线模式下，用户可以通过菜单上的&ldquo;开始录制&rdquo;和&ldquo;停止录制&rdquo;录制一段时间的事件流。也可以采用Trace.cmd start &lt;文件名&gt;.etl和Trace.cmd stop &lt;文件名&gt;.etl来录制。</p>
<p><strong>事件流分析（在线和离线）</strong></p>
<p>用户可以通过如下菜单来实现对事件流的调试：</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1016.sinotes57.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/1016.sinotes57.PNG" border="0" /><br />&nbsp;&nbsp; <br />重播菜单可以通过但不模式从头开始一步一步调试事件流的变化，也可以直接跳转到用户设置的断点。寻根分析（Root Cause Analysis）可以找出指定事件的事件源。演化分析（Event Propagation Analysis）可以更重指定事件之后的所有演变。通过多个菜单的综合运用，用户就可以找出事件流中的异常事件数据，并进行更进一步的分析。</p>
<p>更多信息，请参见：</p>
<p><a href="http://technet.microsoft.com/zh-cn/library/ff518532.aspx">http://technet.microsoft.com/zh-cn/library/ff518532.aspx</a></p>
<p>软件测试工程师 金晶</p>]]></content:encoded>
    </item>
    <item>
      <title>StreamInsight手札（四）——使用IEnumerable接口创建StreamInsight程序</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/streaminsightienumerablestreaminsight</link>
      <pubDate>Tue, 12 Apr 2011 00:59:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/04/12/streaminsightienumerablestreaminsight/</guid>
      <description><![CDATA[本文将介绍如何利用IEnumerable接口创建StreamInsight应用程序。
IEnumerable与IObservable最大的区别在于IEnumerable是采用Pull模式获取数据，而...]]></description>
      <content:encoded><![CDATA[<p>本文将介绍如何利用IEnumerable接口创建StreamInsight应用程序。</p>
<p>IEnumerable与IObservable最大的区别在于IEnumerable是采用Pull模式获取数据，而IObservable则是用Push模式推送数据。</p>
<p>用户首先通过IEnumerable.GetEnumerator来获得数据源的Enumerator，然后通过调用IEnumerator.MoveNext和IEnumerator.Current来获取数据。StreamInsight的输入输出通过一个数据队列连接。输入适配器获得数据，并调用Enqueue将数据放入队列，输出适配器循环检测队列是否为空，如果不是空队列，则调用Dequeue将数据取出。</p>
<p>在HelloInsight程序基础上，可以通过如下修改来实现IEnumerable接口。</p>
<p>1、获取输入数据源的Enumerator（HelloPointInput.cs）：</p>
<div class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><!--?xml:namespace prefix = o /--><o:o:p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; COLOR: blue; FONT-SIZE: 9.5pt">public</span><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"> HelloPointInput(<span style="COLOR: #2b91af">HelloInputConfig</span> config)<!--?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /--><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt">{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>_config = config;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><o:p>&nbsp;</o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">var</span> streamReader = <span style="COLOR: blue">new</span> <span style="COLOR: #2b91af">StreamReader</span>(config.fileName);<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>strings = <span style="COLOR: blue">new</span> <span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: blue">string</span>&gt;();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">while</span> (!streamReader.EndOfStream)<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>strings.Add(streamReader.ReadLine());<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>stringEnumerator = strings.GetEnumerator();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>streamReader.Close();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt">}<o:p></o:p></span></p>
</o:o:p></span></div>
<div>
<p>2、读取Enumerator中的数据，并放入队列。注意判断队满的情况（HelloPointInput.cs）：</p>
</div>
<div class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><o:o:p></o:o:p></span></div>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; COLOR: blue; FONT-SIZE: 9.5pt">private</span><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"> <span style="COLOR: blue">void</span> ProduceEvents()<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt">{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">while</span> (AdapterState != AdapterState.Stopping)<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">if</span> (<span style="BACKGROUND: yellow; mso-highlight: yellow">stringEnumerator.MoveNext()</span>)<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">try</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">var</span> line = stringEnumerator.Current;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">var</span> pendingEvent = CreateInsertEvent();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pendingEvent.StartTime = <span style="COLOR: #2b91af">DateTime</span>.Now;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pendingEvent.Payload = <span style="COLOR: blue">new</span> <span style="COLOR: #2b91af">HelloPayload</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>str = line<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>};<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>EnqueueOperationResult result;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><o:p>&nbsp;</o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="BACKGROUND: yellow; mso-highlight: yellow">result = Enqueue(<span style="COLOR: blue">ref</span> pendingEvent);</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="BACKGROUND: yellow; COLOR: blue; mso-highlight: yellow">if</span><span style="BACKGROUND: yellow; mso-highlight: yellow"> (result == EnqueueOperationResult.Full)</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: #2b91af">Thread</span>.Sleep(1000);<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: green">//Ready();</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">return</span>;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="BACKGROUND: yellow; mso-highlight: yellow">EnqueueCtiEvent(<span style="COLOR: #2b91af">DateTime</span>.Now);</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: #2b91af">Thread</span>.Sleep(1000);<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">catch</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: green">//error handling should go here</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">else</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">break</span>;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>Stopped();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt">}<o:p></o:p></span></p>
<p>注意：在IEnumerator模式下，CTI事件是必须的，否则不会产生数据输出。</p>
<p>3、循环读取队列中的数据，并进行输出处理（HelloPointOutput.cs）：</p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; COLOR: blue; FONT-SIZE: 9.5pt">private</span><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"> <span style="COLOR: blue">void</span> ConsumeEvents()<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt">{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>PointEvent&lt;<span style="COLOR: #2b91af">HelloPayload</span>&gt; currEvent;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>DequeueOperationResult result;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><o:p>&nbsp;</o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">while</span> (AdapterState != AdapterState.Stopping)<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="BACKGROUND: yellow; mso-highlight: yellow">result = Dequeue(<span style="COLOR: blue">out</span> currEvent);</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><o:p>&nbsp;</o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">if</span> (<span style="BACKGROUND: yellow; mso-highlight: yellow">result == DequeueOperationResult.Empty</span>)<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Ready();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">return</span>;<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">else</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: blue">if</span> (currEvent.EventKind == EventKind.Insert)<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="COLOR: #2b91af">Console</span>.WriteLine(<span style="COLOR: #a31515">"Output: "</span> +<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>currEvent.Payload.str<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>);<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><o:p>&nbsp;</o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="BACKGROUND: yellow; mso-highlight: yellow">ReleaseEvent(<span style="COLOR: blue">ref</span> currEvent);</span><o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><o:p>&nbsp;</o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>Stopped();<o:p></o:p></span></p>
<p style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; TEXT-AUTOSPACE: ; mso-layout-grid-align: none" class="MsoNormal"><span style="FONT-FAMILY: Consolas; FONT-SIZE: 9.5pt">}<o:p></o:p></span></p>
<p>4、运行程序</p>
<p>建立测试文件：</p>
<p><img border="0" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2451.sinotes41.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/2451.sinotes41.png" /></p>
<p>将输入数据源指向测试文件的存储地址。运行程序，得到如下输出：</p>
<p><img border="0" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/2248.sinotes42.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/2248.sinotes42.png" />&nbsp;</p>
<div>软件测试工程师 金晶</div>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/15/24/11/HelloInsight.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-15-24-11/HelloInsight.zip">HelloInsight.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>StreamInsight手札（三）——使用IObservable接口创建StreamInsight程序</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/streaminsightiobservablestreaminsight</link>
      <pubDate>Tue, 12 Apr 2011 00:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/04/12/streaminsightiobservablestreaminsight/</guid>
      <description><![CDATA[本文将介绍如何利用IObservable接口创建StreamInsight应用程序。
Observer是.net Framework...]]></description>
      <content:encoded><![CDATA[<p>本文将介绍如何利用IObservable接口创建StreamInsight应用程序。</p>
<p>Observer是.net Framework 4中引入的开发模式。<a href="http://msdn.microsoft.com/en-us/library/dd783449.aspx">IObserver&lt;T&gt;</a>和<a href="http://msdn.microsoft.com/en-us/library/dd990377.aspx">IObservable&lt;T&gt;</a>接口为基于推送的通知提供通用机制，也称为观察者设计模式。IObservable&lt;T&gt; 接口表示发送通知（提供程序）的类；IObserver&lt;T&gt; 接口表示接收通知（观察器）的类。</p>
<p>在下列应用场景下，适合采用Observable模式：</p>
<ol>
<li>历史数据查询。对有限长的大数据集进行临时的查询。</li>
<li>Ad hoc查询。对数据进行一系列交互的ad hoc查询。</li>
<li>内嵌于用户程序。StreamInsight内嵌于用户应用程序之中。</li>
</ol>
<p>使用这种开发模型，开发者只需要：</p>
<ol>
<li>实现IObservable接口</li>
<li>实现IObserver接口</li>
<li>绑定到查询</li>
</ol>
<p>下面将用示例代码来说明.。</p>
<p>1、安装Reactive Extension for .Net 4：&nbsp;</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1638.sinotes31.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/1638.sinotes31.png" border="0" /></p>
<p>2、新建一个工程，注意选择.net framework 4.0。</p>
<p>3、添加如下引用。System.CoreEx和System.Reactive在C:\Program Files\Microsoft Cloud Programmability\Reactive Extensions\v1.0.2856.0\Net4\目录下。</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/1565.sinotes32.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/1565.sinotes32.png" border="0" /></p>
<p>定义事件Payload：</p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">namespace</span><span style="font-family: Consolas; font-size: 9.5pt;"> HelloInsightObservable<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">HelloPayload</span><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">public</span> <span style="color: blue;">int</span> value { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">}<o:p></o:p></span></p>
<p>
<p>5、定义InputObservable类实现Iobservable接口</p>
</p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">public</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">class</span> <span style="color: #2b91af;">InputObservable</span> : <span style="color: #2b91af;">IObservable</span>&lt;<span style="color: blue;">int</span>&gt;</span><o:p></o:p></p>
<p>这个类需要实现Subscribe方法：</p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">public</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: #2b91af;">IDisposable</span> Subscribe(<span style="color: #2b91af;">IObserver</span>&lt;<span style="color: blue;">int</span>&gt; observer)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">if</span> (observer != <span style="color: blue;">null</span> &amp;&amp; !<span style="color: blue;">this</span>.observers.Contains(observer))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">this</span>.observers.Add(observer);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">return</span> observer <span style="color: blue;">as</span> <span style="color: #2b91af;">IDisposable</span>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">}<o:p></o:p></span></p>
<p>
<p>我们还需要在这个类里模拟输入。我们定义了一个Timer，当定时器时间到时，调用定时器的回调函数生成一个随机整数，并调用observer的OnNext方法推送数据。</p>
</p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">private</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: blue;">void</span> GenerateInput(<span style="color: blue;">object</span> _)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> observer <span style="color: blue;">in</span> observers)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">int</span> value = random.Next(100);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"Random generated data {0} : {1}"</span>, generatedNumber, value);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnNext(value);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>generatedNumber++;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">if</span> (generatedNumber &gt;= dataNumber)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnCompleted();<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>timer.Change(<span style="color: #2b91af;">Timeout</span>.Infinite, timeSpan);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">return</span>;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>timer.Change(timeSpan, timeSpan);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">}<o:p></o:p></span></p>
<p>
<p>6、将Observable类作为CEP引擎的输入。</p>
<p>在Main函数中添加如下代码。注意加亮部分的代码，这里与适配器方式的程序不同的是，没有插入CTI事件。</p>
</p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">var</span><span style="font-family: Consolas; font-size: 9.5pt;"> inputObservable = <span style="color: blue;">new</span> <span style="color: #2b91af;">InputObservable</span>(10);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">using</span><span style="font-family: Consolas; font-size: 9.5pt;"> (<span style="color: blue;">var</span> server = Server.Create(<span style="color: #a31515;">"DefaultInstance"</span>))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">var</span> application = server.CreateApplication(<span style="color: #a31515;">"Observable Application"</span>);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="background-color: #ffff00;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">var</span> stream = inputObservable.ToPointStream(application,<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="background-color: #ffff00;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>e =&gt; PointEvent.CreateInsert(<span style="color: #2b91af;">DateTime</span>.Now, <span style="color: blue;">new</span> <span style="color: #2b91af;">HelloPayload</span> { value = e }),<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="background-color: #ffff00;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>AdvanceTimeSettings.StrictlyIncreasingStartTime,<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="background-color: #ffff00;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #a31515;">"Observable Stream"</span>);<o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">var</span> query = <span style="color: blue;">from</span> e <span style="color: blue;">in</span> stream<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">where</span> e.value &gt; 50<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: blue;">select</span> e;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">}</span><o:p></o:p></p>
<p>
<p>7、定义OutputObserver类实现Iobserver接口。</p>
</p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">class</span><span style="font-family: Consolas; font-size: 9.5pt;"> <span style="color: #2b91af;">OutputObserver</span> : <span style="color: #2b91af;">IObserver</span>&lt;<span style="color: #2b91af;">HelloPayload</span>&gt;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> OnCompleted()<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"Stopping query..."</span>);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> OnError(<span style="color: #2b91af;">Exception</span> e)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"Unexpected error occured"</span>);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> OnNext(<span style="color: #2b91af;">HelloPayload</span> payload)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af;">Console</span>.WriteLine(<span style="color: #a31515;">"DataOutput: {0}"</span>, payload.value);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;"><span style="mso-spacerun: yes;">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">}<o:p></o:p></span></p>
<p><span style="font-family: Consolas;">8、将OutputObserver绑定到query。</span></p>
<p><span style="font-family: Consolas;">在main函数中添加如下代码：</span></p>
<p><span style="font-family: Consolas;">
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">var</span><span style="font-family: Consolas; font-size: 9.5pt;"> outputObserver = <span style="color: blue;">new</span> <span style="color: #2b91af;">OutputObserver</span>();<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; color: blue; font-size: 9.5pt;">var</span><span style="font-family: Consolas; font-size: 9.5pt;"> outputObservable = query.ToObservable();<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Consolas; font-size: 9.5pt;">outputObservable.Subscribe(outputObserver);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="background-color: #ffff00;"><span style="font-family: Consolas; color: #2b91af; font-size: 9.5pt;">Console</span><span style="font-family: Consolas; font-size: 9.5pt;">.ReadLine();<o:p></o:p></span></span></p>
<p>Subscribe函数执行后，就会开始接收数据输入，并调用OnNext方法输出。注意最后一句话的作用是让程序继续运行直至数据输入完成，Observable调用Observer的OnComplete方法，或者用户中途通过输入任意字符停止Observer。</p>
<p>9、程序运行的结果如下：</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/97/59/7128.sinotes33.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-97-59/7128.sinotes33.png" border="0" /></p>
<span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">
<p>
<p>软件测试工程师 金晶</p>
</p>
</span></span></span></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/15/23/95/HelloInsight.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-15-23-95/HelloInsight.zip">HelloInsight.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>利用SQL Server 2008迁移助手完成从Oracle到SQL Server的迁移——视频教学</title>
      <link>https://docs.microsoft.com/archive/blogs/sqlcrd/sql-server-2008oraclesql-server</link>
      <pubDate>Mon, 11 Apr 2011 22:41:50 GMT</pubDate>
      <dc:creator><![CDATA[Qi Samuel Zhang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sqlcrd/2011/04/11/sql-server-2008oraclesql-server/</guid>
      <description><![CDATA[讲师：&nbsp;资深项目经理 &nbsp;王清越
你有Oracle数据库要迁移到SQL Server吗？微软提供了一个免费的工具来帮你做数据库迁移。我们会讨论迁移到
SQL...]]></description>
      <content:encoded><![CDATA[<p>
<p class="MsoNormal"><span>讲师：&nbsp;资深项目经理 &nbsp;王清越</span></p>
<p class="MsoNormal"><span lang="ZH-CN">你有</span>Oracle<span lang="ZH-CN">数据库要迁移到</span>SQL Server<span lang="ZH-CN">吗？微软提供了一个免费的工具来帮你做数据库迁移。我们会讨论迁移到</span>
SQL Server<span lang="ZH-CN">的好处，和如何用</span>SQL
Server<span lang="ZH-CN">迁移助理（</span>SSMA）<span lang="ZH-CN">来自动做数据库迁移。我们会演示如何用</span>SQL Server<span lang="ZH-CN">迁移助理来迁移数据库模式和</span>PL/SQL<span lang="ZH-CN">程序等。我们一起探讨</span>SQL Server<span lang="ZH-CN">迁移助理（</span>SSMA）<span lang="ZH-CN">如何为你节省数据库迁移的时间和成本。</span></p>
</p>
<p>[View:http://wm.microsoft.com/ms/china/technet/howtovideo/sqlserver2008/20110317_SSMAforOracle.wmv]</p>
<p><span>如果有什么问题，请直接通过评论提出。</span></p>]]></content:encoded>
    </item>
  </channel>
</rss>