Auditing SQL Server SQL Statements

WBOY
WBOYオリジナル
2016-06-07 14:50:241038ブラウズ

“谁把我的表给删拉”,”谁删了整个表阿”…碰到这种棘手的情况,你如果没有预先做好准备,真的是头都要急炸了。那怎么能抓出这个”凶手”呢?SQL Trace, SQL Profile,SQL Trigger,Extended Events等着伺候你呢,更别说CLR,Service Broker等重量级武器了

“谁把我的表给删拉”,”谁删了整个表阿”…碰到这种棘手的情况,你如果没有预先做好准备,真的是头都要急炸了。那怎么能抓出这个”凶手”呢?SQL Trace, SQL Profile,SQL Trigger,Extended Events等着伺候你呢,更别说CLR,Service Broker等重量级武器了,别急!

工具虽好,但是也得用得贴合场景才能发挥作用,要不然跟你的SQL Server抢IO,那就得不偿失了。比如高频的OLTP场合,你还用TRIGGER把大量的DML语句都写到当前数据库去,那不是给数据库增加一倍工作量么。当然控制好权限,做好测试也能保证你的数据安全。这不妨碍我们讨论auditing SQL。

SQL Profiler是基于SQL Trace的,而SQL Trace是会被更高版本的SQL Server给逐渐摒弃的,所以我们就只讨论一个就可以了。一开始我知道 SQL Profiler是可以可视化监控即时的SQL Server活动的,但是缺点是不能保存或者自动执行,需要人工干预。经过研究,它是可以自动保存截取结果的。

让我们认识下“源”:想要抓“破坏分子”,首先要知道“破环分子”的标示有哪些,漏抓,错抓,都是失手的表现。访问SQL SERVER的方式有很多种,有ADO.NET, JDBC, SQL SERVER Management Studio, ODBC等各种方法,也有 Ad-hoc SQL, Stored Procedure等表现形式,是否每一种的方式都有各自不同的格式呢?最好的方法就是针对每种方式都来做个例子验证下。

首先最简单的SSMS方式,我们将SQL Profiler限制到某一个数据库,lenistest4。 在SSMS里面输入:

<code class=" hljs rust"><span class="hljs-keyword">use</span> lenistest4

go</code>

SQL Profiler显示的是SQL:BatchCompleted。

这里写图片描述
这里与有没有go无关。当你选中一块SQL区域并执行,其中如果有go那就有关系了,比如:

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> sys.tables

<span class="hljs-keyword">go</span>

<span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">go</span></span></code>

这里写图片描述

这里一个go分割了一个batch。最后一个go没有意义,我们提交了一段代码,这段代码相当于是一个大batch,如果中间有go,那这个go 就代表了一个子batch。

那么用动态语句,会有什么Trace格式呢:

<code class=" hljs css"><span class="hljs-tag">declare</span> <span class="hljs-at_rule">@<span class="hljs-keyword">sqlstatement</span> <span class="hljs-function">nvarchar(max)</span> = N<span class="hljs-string">'select top 10 * from dbo.region'</span> </span>;

<span class="hljs-tag">exec</span> <span class="hljs-tag">sp_executesql</span> <span class="hljs-at_rule">@<span class="hljs-keyword">sqlstatement</span></span></code>

这里写图片描述

这里有SQL:Batch*, SQL:Stmt*,SP:Stmt, SQL:Stmt*代表的是一系列的SQL命令,比如declare, set等;SP:Stmt*代表了stored procedure的范围内语句。

<code class=" hljs vbnet"><span class="hljs-keyword">declare</span> @sqlstatement nvarchar(max) = N<span class="hljs-comment">'</span>

<span class="hljs-keyword">declare</span> @regionName varchar(<span class="hljs-number">20</span>) = <span class="hljs-comment">''China''</span>

<span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">where</span> regionName = @regionName<span class="hljs-comment">' ;</span>

exec sp_executesql @sqlstatement</code>

这里写图片描述
上面这段SQL,验证了SQL命令select和declare是不是都被看作是SP:Stmt* ? 其实在一个batch里面,SQL命令里面DML语句也是被当作Statement来处理的。

如果在动态SQL里面有go是不是也会有SP:Batch*? 我们接着往下看:

<code class=" hljs vbnet"><span class="hljs-keyword">declare</span> @sqlstatement nvarchar(max) = N<span class="hljs-comment">'</span>

<span class="hljs-keyword">declare</span> @regionName varchar(<span class="hljs-number">20</span>) = <span class="hljs-comment">''China''</span>

<span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">where</span> regionName = @regionName;

go

<span class="hljs-keyword">declare</span> @regionName2 varchar(<span class="hljs-number">20</span>) = <span class="hljs-comment">''England''</span>

<span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">where</span> regionName = @regionName2

<span class="hljs-comment">' ;</span>

exec sp_executesql @sqlstatement</code>

Msg 102, Level 15, State 1, Line 12

Incorrect syntax near ‘go’.

可以看到go是不能用在动态语句里面的。

为了验证SP:Stmt*是不是指的是存储过程里面的语句,我们先创建一个stored procedure,然后再执行它:

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">procedure</span> dbo.getRegionName

<span class="hljs-keyword">as</span>

<span class="hljs-keyword">begin</span>

<span class="hljs-keyword">declare</span> @regionName <span class="hljs-keyword">varchar</span>(<span class="hljs-number">20</span>) = <span class="hljs-string">'China'</span>

<span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">where</span> regionName = @regionName

<span class="hljs-keyword">declare</span> @regionNamex <span class="hljs-keyword">varchar</span>(<span class="hljs-number">20</span>) = <span class="hljs-string">'England'</span>

<span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">where</span> regionName = @regionNamex

<span class="hljs-keyword">end</span>

<span class="hljs-keyword">exec</span> dbo.getRegionName</span></code>

这里写图片描述
正是如此 !综上所述, SQL:Batch* , 这里的batch相当于是个scope,一个大的执行空间,里面的所有 SQL 语句都是statement,包括DML,DDL等一系列 T-SQL语句 ;而SP:Stmt*又是存储过程的执行空间,里面所有的 T-SQL语句都是statement。

下面看段c#调用这个stored procedure,看看trace是如何识别的:

<code class=" hljs vala"><span class="hljs-keyword">using</span> System;

<span class="hljs-keyword">using</span> System.Collections.Generic;

<span class="hljs-keyword">using</span> System.Linq;

<span class="hljs-keyword">using</span> System.Text;

<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">using</span> System.Data.SqlClient;

<span class="hljs-keyword">using</span> System.Data.SqlTypes;

<span class="hljs-keyword">using</span> System.Data;

<span class="hljs-class"><span class="hljs-keyword">namespace</span> <span class="hljs-title">AccessLenistest4DB</span>

{</span>

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>

    {</span>

        <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> Main(<span class="hljs-keyword">string</span>[] args)

        {

            SqlConnection<span class="hljs-constant"> ICONN </span>= <span class="hljs-keyword">new</span> SqlConnection(@<span class="hljs-string">"data source = (localhost);initial catalog = lenistest4 ;user id = sa; password = sas;"</span>);

            SqlCommand icmd = <span class="hljs-keyword">new</span> SqlCommand();

            icmd.Connection = ICONN;

            icmd.CommandType = System.Data.CommandType.StoredProcedure;

            icmd.CommandText = <span class="hljs-string">"dbo.getRegionName"</span>;

            SqlDataAdapter ida = <span class="hljs-keyword">new</span> SqlDataAdapter(icmd);

            DataSet localds = <span class="hljs-keyword">new</span> DataSet();

            <span class="hljs-keyword">try</span>

            {

                ICONN.Open();

                ida.Fill(localds);

            }

            <span class="hljs-keyword">catch</span>(SqlException se)

            {

                Console.Write(se.ToString());

            }

        }

    }

}</code>

这里写图片描述
这儿多了个RPC, remote procedure call。其他都一样,所以RPC可以看作是一种命名空间,用阿里区别访问协议。这里要区别的是我们调用的是stored procedure,所以会RPC。所以如果我们是用纯SQL来访问数据库,那会不会有 RPC标示呢:

<code class=" hljs vala"><span class="hljs-keyword">using</span> System;

<span class="hljs-keyword">using</span> System.Collections.Generic;

<span class="hljs-keyword">using</span> System.Linq;

<span class="hljs-keyword">using</span> System.Text;

<span class="hljs-keyword">using</span> System.Threading.Tasks;

<span class="hljs-keyword">using</span> System.Data.SqlClient;

<span class="hljs-keyword">using</span> System.Data.SqlTypes;

<span class="hljs-keyword">using</span> System.Data;

<span class="hljs-class"><span class="hljs-keyword">namespace</span> <span class="hljs-title">AccessLenistest4DB</span>

{</span>

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>

    {</span>

        <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> Main(<span class="hljs-keyword">string</span>[] args)

        {

            SqlConnection<span class="hljs-constant"> ICONN </span>= <span class="hljs-keyword">new</span> SqlConnection(@<span class="hljs-string">"data source = (localhost);initial catalog = lenistest4 ;user id = sa; password = sas;"</span>);

            SqlCommand icmd = <span class="hljs-keyword">new</span> SqlCommand();

            icmd.Connection = ICONN;

            icmd.CommandType = System.Data.CommandType.Text;

            icmd.CommandText = <span class="hljs-string">"select * from dbo.region"</span>;

            SqlDataAdapter ida = <span class="hljs-keyword">new</span> SqlDataAdapter(icmd);

            DataSet localds = <span class="hljs-keyword">new</span> DataSet();

            <span class="hljs-keyword">try</span>

            {

                ICONN.Open();

                ida.Fill(localds);

            }

            <span class="hljs-keyword">catch</span>(SqlException se)

            {

                Console.Write(se.ToString());

            }

        }

    }

}</code>

这里写图片描述
并没有RPC。 事实证明 RPC只出现在客户端语言调用存储过程的例子。

Trace的手段 :“破坏分子”的特征被识别了,接下来就是怎么去抓捕的手段问题了。可以有即时的GUI工具,比如SQL Profiler,Extended Event(SSMS自带),也可以用脚本去抓,并放在特定存储里面供稍后分析使用。

SQL Profiler 是即时的GUI工具很好用,可以保存结果,也可以自定义模板,缺点在于你必须开一个额外的窗口去跟踪,有时候数据量太大,还会影响传输,对多太SQL Server做监控就不怎么容易了,一个一个手工去开窗口,是不是很麻烦 ?

这里有Extended Events可以帮我们用脚本的形式去捕捉这些T-SQL语句,这里有个简单的例子:

  1. 通过 Extended Events ,我们可以监控一段时间内的的 SQL Completed 情况,简要介绍下:

1.1 Extended Events 概念:由一系列自动触发的 event 产生性能数据,经过 event engine 的收集,存放到指定的输出文件,以供后续的分析。

1.2 XE 涉及到的动态管理试图 : sys.dm_xe_packages; sys.dm_xe_objects;sys.dm_xe_sessions

1.3 基本用法:

2.3.1 创建一个 Event Session

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> event <span class="hljs-keyword">session</span> capture_sql_events

<span class="hljs-keyword">on</span> server

<span class="hljs-keyword">add</span> event sqlserver.sql_statement_completed

(

<span class="hljs-keyword">action</span>(sqlserver.sql_text)

)

<span class="hljs-keyword">add</span> target package0.event_file

(

<span class="hljs-keyword">set</span> filename = <span class="hljs-string">'E:\data_bu\capture_sql_events.xel'</span>, metadatafile = <span class="hljs-string">'E:\data_bu\capture_sql_event.xem'</span>

)

<span class="hljs-keyword">go</span></span></code>

2.3.2 启用这个 Event session 来收集数据

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">alter</span> event <span class="hljs-keyword">session</span> capture_sql_events

<span class="hljs-keyword">on</span> server

STATE = <span class="hljs-keyword">start</span>

<span class="hljs-keyword">go</span></span></code>

2.3.3 停用这个 Event session

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">alter</span> event <span class="hljs-keyword">session</span> capture_sql_events

<span class="hljs-keyword">on</span> server

state = stop

<span class="hljs-keyword">go</span></span></code>

2.3.4 修改一个 session 来增加或者删除对 Event 的监控

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">alter</span> event <span class="hljs-keyword">session</span> capture_sql_events <span class="hljs-keyword">on</span> server

<span class="hljs-keyword">add</span> event sqlserver.sql_batch_completed (<span class="hljs-keyword">action</span>(sqlserver.sql_text))

<span class="hljs-keyword">go</span></span></code>

2.3.5 查看正在运行的 Event Session

<code class=" hljs cs"><span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> sys.dm_xe_sessions

<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> sys.dm_xe_session_events</code>

2.3.6 查看收集到的统计数据

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">select</span> top <span class="hljs-number">10</span> * <span class="hljs-keyword">from</span> dbo.region

<span class="hljs-keyword">go</span>

<span class="hljs-keyword">select</span> * , <span class="hljs-keyword">cast</span>(event_data <span class="hljs-keyword">as</span> xml) <span class="hljs-keyword">as</span> event_data_xml

<span class="hljs-keyword">from</span> sys.fn_xe_file_target_read_file(<span class="hljs-string">'E:\data_bu\capture_sql_events*.xel'</span>,<span class="hljs-keyword">null</span>,<span class="hljs-keyword">null</span>,<span class="hljs-keyword">null</span>)

<span class="hljs-keyword">where</span> event_data <span class="hljs-keyword">like</span> N<span class="hljs-string">'%region%'</span></span></code>

从结果集我们可以看到,sql_statement_completed这个Event抓到的结果中,包含了Action中我们指定的内容,还包含了其他的一些统计信息:

<code class=" hljs xml"><span class="hljs-tag"><<span class="hljs-title">event</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"sql_statement_completed"</span> <span class="hljs-attribute">package</span>=<span class="hljs-value">"sqlserver"</span> <span class="hljs-attribute">timestamp</span>=<span class="hljs-value">"2016-05-06T03:29:48.868Z"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"duration"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"cpu_time"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"physical_reads"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"logical_reads"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>2<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"writes"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"row_count"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>6<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"last_row_count"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>6<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"line_number"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>1<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"offset"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"offset_end"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>62<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"statement"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>select top 10 * from dbo.region<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"parameterized_plan_handle"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span> /></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">action</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"sql_text"</span> <span class="hljs-attribute">package</span>=<span class="hljs-value">"sqlserver"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>select top 10 * from dbo.region

<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">action</span>></span>

<span class="hljs-tag"></<span class="hljs-title">event</span>></span></code>

我们在Action里面加入对database_name,和plan_handle的捕捉,可以从结果看到又多出来两个元素:

<code class=" hljs sql"><span class="hljs-operator"><span class="hljs-keyword">create</span> event <span class="hljs-keyword">session</span> capture_sql_events

<span class="hljs-keyword">on</span> server

<span class="hljs-keyword">add</span> event sqlserver.sql_statement_completed

(

<span class="hljs-keyword">action</span>(sqlserver.sql_text,sqlserver.database_name,sqlserver.plan_handle)

)

<span class="hljs-keyword">add</span> target package0.event_file

(

<span class="hljs-keyword">set</span> filename = <span class="hljs-string">'E:\data_bu\capture_sql_events.xel'</span>, metadatafile = <span class="hljs-string">'E:\data_bu\capture_sql_event.xem'</span>

)</span></code>
<code class=" hljs xml"><span class="hljs-tag"><<span class="hljs-title">event</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"sql_statement_completed"</span> <span class="hljs-attribute">package</span>=<span class="hljs-value">"sqlserver"</span> <span class="hljs-attribute">timestamp</span>=<span class="hljs-value">"2016-05-06T03:52:02.524Z"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"duration"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"cpu_time"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"physical_reads"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"logical_reads"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>2<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"writes"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"row_count"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>6<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"last_row_count"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>6<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"line_number"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>1<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"offset"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>0<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"offset_end"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>62<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"statement"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>select top 10 * from dbo.region<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">data</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"parameterized_plan_handle"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span> /></span>

<span class="hljs-tag"></<span class="hljs-title">data</span>></span>

<span class="hljs-tag"><<span class="hljs-title">action</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"plan_handle"</span> <span class="hljs-attribute">package</span>=<span class="hljs-value">"sqlserver"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>06002000448a700f00d62b7a0300000001000000000000000000000000000000000000000000000000000000<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">action</span>></span>

<span class="hljs-tag"><<span class="hljs-title">action</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"database_name"</span> <span class="hljs-attribute">package</span>=<span class="hljs-value">"sqlserver"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>lenistest4<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">action</span>></span>

<span class="hljs-tag"><<span class="hljs-title">action</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"sql_text"</span> <span class="hljs-attribute">package</span>=<span class="hljs-value">"sqlserver"</span>></span>

<span class="hljs-tag"><<span class="hljs-title">value</span>></span>select top 10 * from dbo.region

<span class="hljs-tag"></<span class="hljs-title">value</span>></span>

<span class="hljs-tag"></<span class="hljs-title">action</span>></span>

<span class="hljs-tag"></<span class="hljs-title">event</span>></span></code>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:Mysql中约束详解次の記事:JDBC优化