데이터 베이스 MySQL 튜토리얼 Auditing SQL Server SQL Statements

Auditing SQL Server SQL Statements

Jun 07, 2016 pm 02:50 PM
server sql

“谁把我的表给删拉”,”谁删了整个表阿”…碰到这种棘手的情况,你如果没有预先做好准备,真的是头都要急炸了。那怎么能抓出这个”凶手”呢?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으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Hibernate 프레임워크에서 HQL과 SQL의 차이점은 무엇입니까? Hibernate 프레임워크에서 HQL과 SQL의 차이점은 무엇입니까? Apr 17, 2024 pm 02:57 PM

HQL과 SQL은 Hibernate 프레임워크에서 비교됩니다. HQL(1. 객체 지향 구문, 2. 데이터베이스 독립적 쿼리, 3. 유형 안전성), SQL은 데이터베이스를 직접 운영합니다(1. 데이터베이스 독립적 표준, 2. 복잡한 실행 파일) 쿼리 및 데이터 조작).

Oracle SQL의 나누기 연산 사용법 Oracle SQL의 나누기 연산 사용법 Mar 10, 2024 pm 03:06 PM

"OracleSQL의 나눗셈 연산 사용법" OracleSQL에서 나눗셈 연산은 일반적인 수학 연산 중 하나입니다. 데이터 쿼리 및 처리 중에 나누기 작업은 필드 간의 비율을 계산하거나 특정 값 간의 논리적 관계를 도출하는 데 도움이 될 수 있습니다. 이 문서에서는 OracleSQL의 나누기 작업 사용법을 소개하고 구체적인 코드 예제를 제공합니다. 1. OracleSQL의 두 가지 분할 연산 방식 OracleSQL에서는 두 가지 방식으로 분할 연산을 수행할 수 있습니다.

Oracle과 DB2의 SQL 구문 비교 및 ​​차이점 Oracle과 DB2의 SQL 구문 비교 및 ​​차이점 Mar 11, 2024 pm 12:09 PM

Oracle과 DB2는 일반적으로 사용되는 관계형 데이터베이스 관리 시스템으로, 각각 고유한 SQL 구문과 특성을 가지고 있습니다. 이 기사에서는 Oracle과 DB2의 SQL 구문을 비교 및 ​​차이점을 설명하고 구체적인 코드 예제를 제공합니다. 데이터베이스 연결 Oracle에서는 다음 문을 사용하여 데이터베이스에 연결합니다. CONNECTusername/password@database DB2에서 데이터베이스에 연결하는 문은 다음과 같습니다. CONNECTTOdataba

SQL의 ID 속성은 무엇을 의미합니까? SQL의 ID 속성은 무엇을 의미합니까? Feb 19, 2024 am 11:24 AM

SQL에서 ID란 무엇입니까? SQL에서 ID는 자동 증가 숫자를 생성하는 데 사용되는 특수 데이터 유형으로, 테이블의 각 데이터 행을 고유하게 식별하는 데 사용됩니다. ID 열은 일반적으로 기본 키 열과 함께 사용되어 각 레코드에 고유한 식별자가 있는지 확인합니다. 이 문서에서는 Identity를 사용하는 방법과 몇 가지 실제 코드 예제를 자세히 설명합니다. Identity를 사용하는 기본 방법은 테이블을 생성할 때 Identit을 사용하는 것입니다.

MyBatis 동적 SQL 태그의 Set 태그 기능에 대한 자세한 설명 MyBatis 동적 SQL 태그의 Set 태그 기능에 대한 자세한 설명 Feb 26, 2024 pm 07:48 PM

MyBatis 동적 SQL 태그 해석: Set 태그 사용법에 대한 자세한 설명 MyBatis는 풍부한 동적 SQL 태그를 제공하고 데이터베이스 작업 명령문을 유연하게 구성할 수 있는 탁월한 지속성 계층 프레임워크입니다. 그 중 Set 태그는 업데이트 작업에서 매우 일반적으로 사용되는 UPDATE 문에서 SET 절을 생성하는 데 사용됩니다. 이 기사에서는 MyBatis에서 Set 태그의 사용법을 자세히 설명하고 특정 코드 예제를 통해 해당 기능을 보여줍니다. Set 태그란 무엇입니까? Set 태그는 MyBati에서 사용됩니다.

Java는 MySQL 드라이버 인터셉터를 어떻게 사용하여 SQL 시간이 많이 소요되는 계산을 구현합니까? Java는 MySQL 드라이버 인터셉터를 어떻게 사용하여 SQL 시간이 많이 소요되는 계산을 구현합니까? May 27, 2023 pm 01:10 PM

배경: 회사의 요구 사항 중 하나는 회사의 기존 링크 추적 로그 구성 요소가 MySQL의 SQL 실행 시간 인쇄를 지원해야 한다는 것입니다. 링크 추적을 구현하는 일반적인 방법은 타사 프레임워크 또는 도구에서 제공하는 인터셉터 인터페이스 또는 필터 인터페이스를 구현하는 것입니다. MySQL도 예외는 아닙니다. 사실 MySQL은 MySQL에 의해 구동되는 인터셉터 인터페이스를 구현합니다. MySQL을 구체적으로 구현하는 채널에는 다양한 버전이 있고, 버전마다 인터셉터 인터페이스가 다르기 때문에 사용 중인 MySQL 드라이버의 버전에 따라 응답 인터셉터를 구현해야 합니다. 다음으로 MySQL 채널 5를 소개하겠습니다. 각각 6개 버전 구현. 여기서는 Statem을 구현하기 위한 예로 MySQL 채널 5.1.18 버전을 사용하여 MySQL5를 구현했습니다.

Windows 서버 백업을 설치, 제거 및 재설정하는 방법 Windows 서버 백업을 설치, 제거 및 재설정하는 방법 Mar 06, 2024 am 10:37 AM

WindowsServerBackup은 WindowsServer 운영 체제와 함께 제공되는 기능으로, 사용자가 중요한 데이터 및 시스템 구성을 보호하고 중소기업 및 대기업 수준의 기업에 완벽한 백업 및 복구 솔루션을 제공하도록 설계되었습니다. Server2022 이상을 실행하는 사용자만 이 기능을 사용할 수 있습니다. 이 문서에서는 WindowsServerBackup을 설치, 제거 또는 재설정하는 방법을 설명합니다. Windows Server 백업을 재설정하는 방법 서버 백업에 문제가 있거나 백업에 너무 오랜 시간이 걸리거나 저장된 파일에 액세스할 수 없는 경우 Windows Server 백업 설정을 재설정하는 것을 고려할 수 있습니다. Windows를 재설정하려면

SQL에서 5120 오류를 해결하는 방법 SQL에서 5120 오류를 해결하는 방법 Mar 06, 2024 pm 04:33 PM

해결 방법: 1. 로그인한 사용자에게 데이터베이스에 액세스하거나 운영할 수 있는 충분한 권한이 있는지 확인하고 해당 사용자에게 올바른 권한이 있는지 확인하십시오. 2. SQL Server 서비스 계정에 지정된 파일에 액세스할 수 있는 권한이 있는지 확인하십시오. 3. 지정된 데이터베이스 파일이 다른 프로세스에 의해 열렸거나 잠겼는지 확인하고 파일을 닫거나 해제한 후 쿼리를 다시 실행하십시오. .관리자로 Management Studio를 실행해 보세요.

See all articles