Auditing SQL Server SQL Statements
“谁把我的表给删拉”,”谁删了整个表阿”…碰到这种棘手的情况,你如果没有预先做好准备,真的是头都要急炸了。那怎么能抓出这个”凶手”呢?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语句,这里有个简单的例子:
- 通过 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>

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

HQL and SQL are compared in the Hibernate framework: HQL (1. Object-oriented syntax, 2. Database-independent queries, 3. Type safety), while SQL directly operates the database (1. Database-independent standards, 2. Complex executable queries and data manipulation).

"Usage of Division Operation in OracleSQL" In OracleSQL, division operation is one of the common mathematical operations. During data query and processing, division operations can help us calculate the ratio between fields or derive the logical relationship between specific values. This article will introduce the usage of division operation in OracleSQL and provide specific code examples. 1. Two ways of division operations in OracleSQL In OracleSQL, division operations can be performed in two different ways.

Oracle and DB2 are two commonly used relational database management systems, each of which has its own unique SQL syntax and characteristics. This article will compare and differ between the SQL syntax of Oracle and DB2, and provide specific code examples. Database connection In Oracle, use the following statement to connect to the database: CONNECTusername/password@database. In DB2, the statement to connect to the database is as follows: CONNECTTOdataba

What is Identity in SQL? Specific code examples are needed. In SQL, Identity is a special data type used to generate auto-incrementing numbers. It is often used to uniquely identify each row of data in a table. The Identity column is often used in conjunction with the primary key column to ensure that each record has a unique identifier. This article will detail how to use Identity and some practical code examples. The basic way to use Identity is to use Identit when creating a table.

Interpretation of MyBatis dynamic SQL tags: Detailed explanation of Set tag usage MyBatis is an excellent persistence layer framework. It provides a wealth of dynamic SQL tags and can flexibly construct database operation statements. Among them, the Set tag is used to generate the SET clause in the UPDATE statement, which is very commonly used in update operations. This article will explain in detail the usage of the Set tag in MyBatis and demonstrate its functionality through specific code examples. What is Set tag Set tag is used in MyBati

WindowsServerBackup is a function that comes with the WindowsServer operating system, designed to help users protect important data and system configurations, and provide complete backup and recovery solutions for small, medium and enterprise-level enterprises. Only users running Server2022 and higher can use this feature. In this article, we will explain how to install, uninstall or reset WindowsServerBackup. How to Reset Windows Server Backup If you are experiencing problems with your server backup, the backup is taking too long, or you are unable to access stored files, then you may consider resetting your Windows Server backup settings. To reset Windows

Solution: 1. Check whether the logged-in user has sufficient permissions to access or operate the database, and ensure that the user has the correct permissions; 2. Check whether the account of the SQL Server service has permission to access the specified file or folder, and ensure that the account Have sufficient permissions to read and write the file or folder; 3. Check whether the specified database file has been opened or locked by other processes, try to close or release the file, and rerun the query; 4. Try as administrator Run Management Studio as etc.

How to use SQL statements for data aggregation and statistics in MySQL? Data aggregation and statistics are very important steps when performing data analysis and statistics. As a powerful relational database management system, MySQL provides a wealth of aggregation and statistical functions, which can easily perform data aggregation and statistical operations. This article will introduce the method of using SQL statements to perform data aggregation and statistics in MySQL, and provide specific code examples. 1. Use the COUNT function for counting. The COUNT function is the most commonly used
