Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
如何解决在运行 SQL Server 的服务器之间移动数据库时的权限问题

思路:
1,账号:利用链接1脚本生成,主要是为了sid,以保证用用户数据库的一样
   注:链接1脚本支持sqlserver2005以上版本
2,权限:备份或附加数据库后,因为步骤1中的sid已经在新服务器上创立,故权限会自动匹配上。
 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58

为防止正式环境数据库被篡改,但又要保证可以正常查询处理问题,可以将账号的数据库访问权限设置为db_datareader
数据库权限:单独设置的优先,如给了一账号只读权限,若别开一张表给于此账号写权限,那么单独设置的写权限优先级最高。
注:db_datareader没有存储过程访问权限,若想全开,如下:

GRANT EXEC TO datareader
GRANT ALTER TO datareader
 

固定数据库角色
db_owner 数据库所有者

db_accessadmin 数据库访问管理员

db_securityadmin 数据库安全管理员

db_ddladmin 数据库 DDL 管理员

db_backupoperator 数据库备份操作员

db_datareader 数据库数据读取者

db_datawriter 数据库数据写入者

db_denydatareader 数据库拒绝数据读取者

db_denydatawriter 数据库拒绝数据写入者

固定服务器角色 描述
sysadmin 在 SQL Server 中进行任何活动。该角色的权限跨越所有其它固定服务器角色。

serveradmin 配置服务器范围的设置,关闭服务器。

setupadmin 添加和删除链接服务器,并执行某些系统存储过程(如 sp_serveroption)。

securityadmin 管理服务器登录和 CREATE DATABASE 权限,还可以读取错误日志和更改密码。。

processadmin 管理在 SQL Server 实例中运行的进程。

dbcreator 创建、改变和除去数据库。

diskadmin 管理磁盘文件。

bulkadmin 执行 BULK INSERT 语句。

固定数据库角色的权限


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
1,数据文件等于CPU的数量数,不过要小于等于8
   Tempdb文件数量为cpu数目一半,不过大小要相等,否则自增长可能会发生在最大的文件上,(参考微软数据库支持组的:Tempdb怎么会成为性能瓶颈)
   文件大小可设置大一些如1G,自增长设置为1G,不要设置成百分比,数据会对不齐
   log文件不用,因为是顺序写,写满一个文件再写再一个
2,更改默认端口
3,如果条件允许(有3或3个以上的物理盘) ,日志和数据文件应该位于不同的磁盘
4,禁用SA
5,建立定时运行索引维护,以降低索引碎片,降低表空间。【索引维护1-索引碎片整理】

禁用sa用户.
create login [admin_sql] from windows;
go
sp_addsrvrolemember [admin_sql],sysadmin
go
ALTER LOGIN [sa] DISABLE
GO

根据cpu数目,更改tempdb数据文件,日志文件。
USE master
DECLARE @i int,@s varchar(4000),@c int
set @i=1
select @c=cpu_count from sys.dm_os_sys_info --给变量赋值,获取cpu数目
while (@i<@c/2 and @i<8)
begin
--获取创建tempdb文件的脚本
set 
@s=
'alter database tempdb add file (name=tempdev'
+convert(varchar,@i)
+',filename=''d:\SQLData\tempdev'   --文件存放路径命名规则:如果是2块盘,次要数据文件放在d盘,其余不变.
+convert(varchar,@i)
+'.ndf'',SIZE = 1024000KB , FILEGROWTH = 512000KB )'
--执行脚本
exec(@s)
set @i=@i+1
end

--修改日志文件 ,数据文件的初始配置
ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'tempdev', SIZE = 102400KB , FILEGROWTH = 102400KB)
GO
ALTER DATABASE [tempdb] MODIFY FILE ( NAME = N'templog', SIZE = 1024000KB , FILEGROWTH = 102400KB)
GO

参考:SQL Server中的高可用性(2)—-文件与文件组


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58

Method 1:

EXEC MASTER..xp_fixeddrives

GO

 

Method 2:

SELECT DISTINCT DB_NAME(dovs.database_idDBName,

mf.physical_name PhysicalFileLocation,

dovs.logical_volume_name AS LogicalName,

dovs.volume_mount_point AS Drive,

CONVERT(INT,dovs.available_bytes/1048576.0AS FreeSpaceInMB

FROM sys.master_files mf

CROSS APPLY sys.dm_os_volume_stats(mf.database_idmf.FILE_IDdovs

ORDER BY FreeSpaceInMB ASC

GO

引自:SQL SERVER – Disk Space Monitoring – Detecting Low Disk Space on Server


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
DECLARE @s VARCHAR(50)
SET @s = '42:1:550'


SELECT PARSENAME(replace(@s,':','.'),3),PARSENAME(replace(@s,':','.'),2),PARSENAME(replace(@s,':','.'),1)
//PARSENAME:返回指定位置的对象,对象以.分开




Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
 
加密
ALTER  PROCEDURE [dbo].[MyProce]
(
@TranType VARCHAR(50)
)
with encryption
AS
IF @TranType='select'
BEGIN 
SELECT '111'
END 
RETURN

解密

--exec dbo.sp_windbi$decrypt 'MyProce',0 

Create PROCEDURE [dbo].[sp_windbi$decrypt]  
(@procedure sysname = NULL, @revfl int = 1)  
AS  
/**//*  
王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com  
调用形式为:  
exec dbo.sp__windbi$decrypt @procedure,0  
如果第二个参数使用1的话,会给出该存储过程的一些提示。  
--版本4.0  修正存储过程过长解密出来是空白的问题  
*/  
SET NOCOUNT ON  
IF @revfl = 1  
BEGIN  
PRINT '警告:该存储过程会删除并重建原始的存储过程。'  
PRINT ' 在运行该存储过程之前确保你的数据库有一个备份。'  
PRINT ' 该存储过程通常应该运行在产品环境的一个备份的非产品环境下。'  
PRINT ' 为了运行这个存储过程,将参数@refl的值更改为0。'  
RETURN 0  
END  
DECLARE @intProcSpace bigint, @t bigint, @maxColID smallint,@procNameLength int  
select @maxColID = max(subobjid) FROM  
sys.sysobjvalues WHERE objid = object_id(@procedure)  
--select @maxColID as 'Rows in sys.sysobjvalues'  
select @procNameLength = datalength(@procedure) + 29  
DECLARE @real_01 nvarchar(max)  
DECLARE @fake_01 nvarchar(max)  
DECLARE @fake_encrypt_01 nvarchar(max)  
DECLARE @real_decrypt_01 nvarchar(max),@real_decrypt_01a nvarchar(max)  
declare @objtype varchar(2),@ParentName nvarchar(max)  
select @real_decrypt_01a = ''  
--提取对象的类型如是存储过程还是函数,如果是触发器,还要得到其父对象的名称  
select @objtype=type,@parentname=object_name(parent_object_id)  
from sys.objects where [object_id]=object_id(@procedure)  
-- 从sys.sysobjvalues里提出加密的imageval记录  
SET @real_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =  
object_id(@procedure) and valclass = 1 order by subobjid)  
  
--创建一个临时表  
create table #output ( [ident] [int] IDENTITY (1, 1) NOT NULL ,  
[real_decrypt] NVARCHAR(MAX) )  
--开始一个事务,稍后回滚  
BEGIN TRAN  
--更改原始的存储过程,用短横线替换  
if @objtype='P'  
  SET @fake_01='ALTER PROCEDURE '+ @procedure +' WITH ENCRYPTION AS select 1  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'  
else if @objtype='FN'  
  SET @fake_01='ALTER FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/ END'  
else if @objtype='V'  
  SET @fake_01='ALTER view '+ @procedure +' WITH ENCRYPTION AS select 1 as col  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'  
else if @objtype='TR'  
  SET @fake_01='ALTER trigger '+ @procedure +' ON '+@parentname+'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'  
EXECUTE (@fake_01)  
--从sys.sysobjvalues里提出加密的假的  
SET @fake_encrypt_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =  
object_id(@procedure) and valclass = 1 order by subobjid )  
if @objtype='P'  
  SET @fake_01='Create PROCEDURE '+ @procedure +' WITH ENCRYPTION AS select 1  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'  
else if @objtype='FN'  
  SET @fake_01='CREATE FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/ END'  
else if @objtype='V'  
  SET @fake_01='Create view '+ @procedure +' WITH ENCRYPTION AS select 1 as col  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'  
else if @objtype='TR'  
  SET @fake_01='Create trigger '+ @procedure +' ON '+@parentname+'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)  
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'  
--开始计数  
SET @intProcSpace=1  
--使用字符填充临时变量  
SET @real_decrypt_01 = replicate(cast('A'as nvarchar(max)), (datalength(@real_01) /2 ))  
--循环设置每一个变量,创建真正的变量  
--每次一个字节  
SET @intProcSpace=1  
--如有必要,遍历每个@real_xx变量并解密  
WHILE @intProcSpace<=(datalength(@real_01)/2)  
BEGIN  
--真的和假的和加密的假的进行异或处理  
SET @real_decrypt_01 = stuff(@real_decrypt_01, @intProcSpace, 1,  
NCHAR(UNICODE(substring(@real_01, @intProcSpace, 1)) ^  
(UNICODE(substring(@fake_01, @intProcSpace, 1)) ^  
UNICODE(substring(@fake_encrypt_01, @intProcSpace, 1)))))  
SET @intProcSpace=@intProcSpace+1  
END  
  
  
--通过sp_helptext逻辑向表#output里插入变量  
insert #output (real_decrypt) select @real_decrypt_01  
--select real_decrypt AS '#output chek' from #output --测试  
-- -------------------------------------  
--开始从sp_helptext提取  
-- -------------------------------------  
declare @dbname sysname  
,@BlankSpaceAdded int  
,@BasePos int  
,@CurrentPos int  
,@TextLength int  
,@LineId int  
,@AddOnLen int  
,@LFCR int --回车换行的长度  
,@DefinedLength int  
,@SyscomText nvarchar(max)  
,@Line nvarchar(255)  
Select @DefinedLength = 255  
SELECT @BlankSpaceAdded = 0 --跟踪行结束的空格。注意Len函数忽略了多余的空格  
CREATE TABLE #CommentText  
(LineId int  
,Text nvarchar(255) collate database_default)  
--使用#output代替sys.sysobjvalues  
DECLARE ms_crs_syscom CURSOR LOCAL  
FOR SELECT real_decrypt from #output  
ORDER BY ident  
FOR READ ONLY  
--获取文本  
SELECT @LFCR = 2  
SELECT @LineId = 1  
OPEN ms_crs_syscom  
FETCH NEXT FROM ms_crs_syscom into @SyscomText  
WHILE @@fetch_status >= 0  
BEGIN  
SELECT @BasePos = 1  
SELECT @CurrentPos = 1  
SELECT @TextLength = LEN(@SyscomText)  
WHILE @CurrentPos != 0  
BEGIN  
--通过回车查找行的结束  
SELECT @CurrentPos = CHARINDEX(char(13)+char(10), @SyscomText,  
@BasePos)  
--如果找到回车  
IF @CurrentPos != 0  
BEGIN  
--如果@Lines的长度的新值比设置的大就插入@Lines目前的内容并继续  
While (isnull(LEN(@Line),0) + @BlankSpaceAdded +  
@CurrentPos-@BasePos + @LFCR) > @DefinedLength  
BEGIN  
SELECT @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) +  
@BlankSpaceAdded)  
INSERT #CommentText VALUES  
( @LineId,  
isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText,  
@BasePos, @AddOnLen), N''))  
SELECT @Line = NULL, @LineId = @LineId + 1,  
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0  
END  
SELECT @Line = isnull(@Line, N'') +  
isnull(SUBSTRING(@SyscomText, @BasePos, @CurrentPos-@BasePos + @LFCR), N'')  
SELECT @BasePos = @CurrentPos+2  
INSERT #CommentText VALUES( @LineId, @Line )  
SELECT @LineId = @LineId + 1  
SELECT @Line = NULL  
END  
ELSE  
--如果回车没找到  
BEGIN  
IF @BasePos <= @TextLength  
BEGIN  
--如果@Lines长度的新值大于定义的长度  
While (isnull(LEN(@Line),0) + @BlankSpaceAdded +  
@TextLength-@BasePos+1 ) > @DefinedLength  
BEGIN  
SELECT @AddOnLen = @DefinedLength -  
(isnull(LEN(@Line),0) + @BlankSpaceAdded)  
INSERT #CommentText VALUES  
( @LineId,  
isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText,  
@BasePos, @AddOnLen), N''))  
SELECT @Line = NULL, @LineId = @LineId + 1,  
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded =  
0  
END  
SELECT @Line = isnull(@Line, N'') +  
isnull(SUBSTRING(@SyscomText, @BasePos, @TextLength-@BasePos+1 ), N'')  
if LEN(@Line) < @DefinedLength and charindex(' ',  
@SyscomText, @TextLength+1 ) > 0  
BEGIN  
SELECT @Line = @Line + ' ', @BlankSpaceAdded = 1  
END  
END  
END  
END  
FETCH NEXT FROM ms_crs_syscom into @SyscomText  
END  
IF @Line is NOT NULL  
INSERT #CommentText VALUES( @LineId, @Line )  
select Text from #CommentText order by LineId  
CLOSE ms_crs_syscom  
DEALLOCATE ms_crs_syscom  
DROP TABLE #CommentText  
-- -------------------------------------  
--结束从sp_helptext提取  
-- -------------------------------------  
--删除用短横线创建的存储过程并重建原始的存储过程  
ROLLBACK TRAN  
DROP TABLE #output  
go  


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
WITH [Waits] AS
    (SELECT
        [wait_type],
        [wait_time_ms] / 1000.0 AS [WaitS],
        ([wait_time_ms] – [signal_wait_time_ms] ) / 1000.0 AS [ResourceS],
        [signal_wait_time_ms] / 1000.0 AS [SignalS],
        [waiting_tasks_count] AS [WaitCount],
        100.0 * [wait_time_ms] / SUM ( [wait_time_ms]) OVER() AS [Percentage],
        ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC ) AS [RowNum]
    FROM sys.dm_os_wait_stats
    WHERE [wait_type] NOT IN (
        N'CLR_SEMAPHORE',    N'LAZYWRITER_SLEEP',
        N'RESOURCE_QUEUE',   N'SQLTRACE_BUFFER_FLUSH',
        N'SLEEP_TASK',       N'SLEEP_SYSTEMTASK',
        N'WAITFOR',          N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
        N'CHECKPOINT_QUEUE', N'REQUEST_FOR_DEADLOCK_SEARCH',
        N'XE_TIMER_EVENT',   N'XE_DISPATCHER_JOIN',
        N'LOGMGR_QUEUE',     N'FT_IFTS_SCHEDULER_IDLE_WAIT',
        N'BROKER_TASK_STOP', N'CLR_MANUAL_EVENT',
        N'CLR_AUTO_EVENT',   N'DISPATCHER_QUEUE_SEMAPHORE',
        N'TRACEWRITE',       N'XE_DISPATCHER_WAIT',
        N'BROKER_TO_FLUSH',  N'BROKER_EVENTHANDLER',
        N'FT_IFTSHC_MUTEX',  N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
        N'DIRTY_PAGE_POLL', &nbsp; N'SP_SERVER_DIAGNOSTICS_SLEEP')
    )
SELECT
    [W1]. [wait_type] AS [WaitType],
    CAST ([W1]. [WaitS] AS DECIMAL( 14, 2 )) AS [Wait_S],
    CAST ([W1]. [ResourceS] AS DECIMAL( 14, 2 )) AS [Resource_S],
    CAST ([W1]. [SignalS] AS DECIMAL( 14, 2 )) AS [Signal_S],
    [W1]. [WaitCount] AS [WaitCount],
    CAST ([W1]. [Percentage] AS DECIMAL( 4, 2 )) AS [Percentage],
    CAST (([W1]. [WaitS] / [W1]. [WaitCount]) AS DECIMAL (14, 4)) AS [AvgWait_S],
    CAST (([W1]. [ResourceS] / [W1]. [WaitCount]) AS DECIMAL (14, 4)) AS [AvgRes_S],
    CAST (([W1]. [SignalS] / [W1]. [WaitCount]) AS DECIMAL (14, 4)) AS [AvgSig_S]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
    ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1]. [RowNum], [W1].[wait_type] , [W1] .[WaitS],
    [W1]. [ResourceS], [W1].[SignalS] , [W1] .[WaitCount], [W1].[Percentage]
HAVING SUM ([W2] .[Percentage]) – [W1].[Percentage] < 95 ; — percentage threshold
GO
 
you can very easily come up with a way to persist the results every few hours or every day and do some time-series analysis to figure out trends or automatically spot problems as they start to happen. You can also use Performance Dashboard to see these graphically in 2005 and Data Collector in 2008. On SQL Server 2000 you can use DBCC SQLPERF (N’waitstats’).
 
这个sql可以用来产看95%以上的等待。

–查看等待类型对应的sql

if exists (select * from sys.objects where object_id = object_id(N'[dbo].[get_statements_from_waiter_list]') and OBJECTPROPERTY(object_id, N'IsProcedure') = 1) 
    drop procedure [dbo].[get_statements_from_waiter_list] 
go 
 
create proc get_statements_from_waiter_list (@wait_type nvarchar(60)=NULL) 
as 
select  
        r.wait_type 
        ,r.wait_time 
        ,SUBSTRING(qt.text,r.statement_start_offset/2,  
            (case when r.statement_end_offset = -1  
            then len(convert(nvarchar(max), qt.text)) * 2  
            else r.statement_end_offset end -r.statement_start_offset)/2)  
        as query_text 
        ,qt.dbid, dbname=db_name(qt.dbid) 
        ,qt.objectid 
        ,r.sql_handle 
        ,r.plan_handle 
FROM sys.dm_exec_requests r 
cross apply sys.dm_exec_sql_text(r.sql_handle) as qt 
where r.session_id > 50 
  and r.wait_type = isnull(upper(@wait_type),r.wait_type) 
go 
 
exec get_statements_from_waiter_list 
DBCC SQLPERF (N'sys.dm_os_wait_stats' , CLEAR );用来清空等待信息
作者对经常碰到的等待类型做出了解释:
CXPACKET:在并发查询中,某个线程等待其他线程完成时出现。可以使用cost threshold for parallelism,max degree of parallelism2个参数的配置,或者设置资源调控器来减少等待的发送,但往往不是解决问题的根本方法。
这意味着
•发生了并行操作
•发生了并行执行,或是并行执行中的一个worker被阻塞
不要望文生义
•不要将服务器级别的MAXDOP设置为1,也就是禁用并行
当您配置的 MAXDOP 值时,请遵循以下准则。

SQL Server 2005 及更高版本

  • 对于使用超过八个处理器的服务器,请使用下列配置:

    MAXDOP = 8
  • 对于使用 8 个或更少的处理器的服务器,请使用下列配置:

    MAXDOP = 0 到N



    注意在此配置中, N表示处理器的数目。
  • 对于具有 NUMA 配置的服务器,MAXDOP 不应超过分配给每个 NUMA 节点的 Cpu 的数量。
  • 对于已启用超线程的服务器,MAXDOP 值不应超过物理处理器的数量。
  • 对于服务器具有 NUMA 配置和启用超线程后,MAXDOP 值不应超过每个 NUMA 节点的物理处理器的数目。
 
更多分析症状和解决方案-PAGEIOLATCH_XX
•是否存在PAGEIOLATCH_SH等待,这意味着大范围SCAN
•同时也观察一下ACCESS_METHODS_DATASET_PARENTLatch和ACCESS_METHODS_SCAN_RANGE_GENERATOR LATCH
•检查导致CXPACKET的请求来查看执行计划是否合理
•其中某个并行线程执行时间过长(也就是其中某个线程不是由于CXPACKET阻塞)
可能的原因
•仅仅是由于发生了并行
•由于缺少聚集索引或是不准确的执行计划导致扫描
•过期的统计信息
•Distinct结果集无法预估执行计划,导致不合适执行计划,从而产生CXPACKET等待,解决办法是临时表(王成辉)
如果的确是问题
•确保统计信息是最新的,并且存在适当的索引
•设置查询的MAXDOP
•考虑MAXDOP=NUMA的物理CPU核数
•在考虑到负载类型(混合)的前提下,再设置实例的MAXDOP
•考虑设置将”cost threshold parallelism”的值设置的更高
 
 
PAGEIOLATCH_XX:从磁盘读入到内存时发送,不一定是io问题,可能是执行计划问题。或者内存压力问题。
这意味着:
•等待页由磁盘被读取到
•最常见的是SH和EX
•SH意味着页被用于读取
•EX意味着页会被修改
避免望文生义
•不要直接判断是IO系统和IO通道的问题
更多分析
•决定哪个表/索引被读取(通过DBCC Page)
•使用sys.dm_io_virtual_file_stats和Avg Disk Secs/Read性能计数器判断IO
•对应的CXPACKET等待,是否存在并行扫描
•通过执行计划查看并行扫描
•通过执行计划查看是否存在隐式转换(可能导致扫描)
•通过Page Life Expectancy查看是否存在缓存区内存压力
创建非聚集索引来减少扫描
更新统计信息
将受影响的数据转移到更快的IO子系统
考虑增加内存
 
 
ASYNC_NETWORK_IO:通常在sql server等待客户端取走数据时发送,客户端生产大量数据,导致取数据很慢,往往是程序设计不合理造成。
这意味着
•SQL Server等待客户端获取数据的ACK反馈
避免望文生义
•不要简单认为是网络延迟
•只有再考虑其他所有因素之后,再考虑是不是网络延迟
更多分析
•分析客户端程序
•分析网络延迟
解决方案
•客户端程序RBAR(Row-By-Agonizing-Row)
•分析网络硬件,TCP配置等
 
 
WRITELOG:日志管理系统等待日志刷新到磁盘时发送。往往说明io子系统的问题,1.把符合分散到多个数据库上或者缩小长事务。可以使用sys.dm_io_virtual_file_stats检查日志的io问题
这意味着
•等待将日志块flush到日志
避免望文生义
•不要一开始就以为是IO问题
•不要直接增加日志文件
更多分析
•查看sys.dm_io_virtual_file_stats
•查看LOGBUFFER等待,看是否存在对日志缓冲区的争抢
•查看日志所在磁盘的磁盘等待队列
•查看事务的平均大小
•查看是否有大量的页分裂(页分裂会导致大量日志)
将日志转移到更快的IO系统(一定要和数据分开)
增加事务的大小来避免大量日志写入(比如说批量写入)
删除没用的非聚集索引,来避免日志开销
修改索引键或使用填充哎减少页分裂
修改程序架构,将负载分布到多个数据库或服务器
 
MSQL_XP: sql server等待扩展存储过程完成时发送,检查扩展存储过程代码
LCK_M_XX:线程等待锁的分配,说明线程堵塞
这意味着:
•由于另一个线程对某个资源加锁,该线程不能对资源加不兼容的锁
避免望文生义
•不要以为锁是Root Cause
更多分析
•通过sys.dm_os_waiting_tasks来找到最开始被阻塞的线程,而阻塞该线程的原因可能是IO、网络、内存等
•使用阻塞进程报表来捕捉等待信息
解决方案基于最开始被阻塞进程的等待类型
一个查范围更新或扫描造成的锁升级
•如果可能,使用分区锁
•尝试创建索引,使得扫描变为非聚集索引查找
•将大批量更新事务分解成多个小事务
•尝试使用不同的隔离等级或是快照隔离
•避免不必要的锁
读写不应该互相阻塞,可以尝试修改隔离等级或使用乐观并发
其它阻止事务释放锁的情况,寻找基本原因
 
IO_COMPLETION:等待io完成时出现,往往说明io问题
SOS_SCHEDULER_YIELD:在等待spinlock时发现可能会浪费很多cpu因此,线程确定自动让出cpu
这意味着
•线程用完4毫秒的时间片,主动放弃CPU
•存在旋锁
避免望文生义
•不一定是CPU问题(CPU问题往往体现在长Runnable队列或大量signal wait)
更多分析
•通过执行计划查看是否存在大量扫描
•查看等待类型
注意:该方式没有Resource_wait等待类型,因此一些查询等待类型的语句可能无法捕获
•无法在sys.dm_os_waiting_tasks中看到
 
PAGELATCH_XX:在访问page时出现(buf闩)的等待。可能是热点页,GAM,SGAM,PFS可能会引起这个问题
这意味着
•等待访问内存中的数据文件页
•常见的是SH和EX
•SH意味着页将被读取
•EX意味着页会被修改
避免望文生义
•不要额PAGEIOLATCH_XX混淆
•不意味着需要增加IO和内存
更多分析
•找出等待页的类型
 
 
SELECT TOP 50 * 
FROM sys.dm_os_waiting_tasks
 
SELECT wt.session_id, wt.wait_type, wt.wait_duration_ms
, s.name AS schema_name
, o.name AS object_name
, i.name AS index_name
FROM sys.dm_os_buffer_descriptors bd
JOIN (
    SELECT  session_id, wait_type,wait_duration_ms,resource_description,
PARSENAME(replace(resource_description,':','.'),1) database_id,
PARSENAME(replace(resource_description,':','.'),2) file_id,PARSENAME(replace(resource_description,':','.'),3)page_id
    FROM sys.dm_os_waiting_tasks
    WHERE wait_type LIKE 'PAGELATCH%'
)wt
ON bd.database_id = wt.database_id
AND bd.file_id = wt.file_id
AND bd.page_id = wt.page_id
JOIN sys.allocation_units au ON bd.allocation_unit_id = au.allocation_unit_id
JOIN sys.partitions p ON au.container_id = p.partition_id
JOIN sys.indexes i ON  p.index_id = i.index_id AND p.object_id = i.object_id
JOIN sys.objects o ON i.object_id = o.object_id
JOIN sys.schemas s ON o.schema_id = s.schema_id
 
处理方法:http://sqlcat.com/sqlcat/b/technicalnotes/archive/2009/09/22/resolving-pagelatch-contention-on-highly-concurrent-insert-workloads-part-1.aspx
 
最经典的TempDB争抢
•添加TempDB文件
•4个起,如果还有争抢,再增加4个
•启用跟踪标记1118
•减少TempDB的使用(比如说减少临时表)
•减少临时表的使用,不要显式的drop掉临时表(非BOOT页TempDB争抢)(高继伟)
过多的页分裂
•修改索引键(经典的GUID)
•避免更新太长的记录
•使用填充因子
插入递增表产生插入热点
•使用随机或组合键并结合填充因子来减少页分裂
•修改程序架构,插入分布到多个表、数据库、服务器中
 
 
 
 
BACKUPXX:
可能是
•BACKUPBUFFER
•BACKUPIO
•BACKUPTHREAD
这意味着
•等待数据或是数据的缓存
•读取数据库文件
•第三种通常是由于数据或磁盘的填0初始化
更多分析
•第一种,备份是基于慢速的的IO系统或网络,或是远程服务器的IO系统缓慢
•数据文件所在的IO系统缓慢
•会产生PREEMPTIVE_OS_WRITEFILEGATHER等待
 
OLEDB
这意味着
•使用了OLE DB机制
避免望文生义
•不要直接猜想是因为使用了链接服务器
更多分析
•等待OLE DB的查询是什么
•如果使用了链接服务器,那么什么导致了链接服务器的延时
可能的解决方案
•DBCC CHECKDB这类内部使用了OLEDB的命令
•很多DMV内部使用了OLEDB,因此可能是一些监测工具导致的问题
•低性能的链接服务器
 
 
LATCH_XX:非buf闩的等待(闩分为2种,buf闩和非buf闩,SQL Server 2008内部剖析与故障分析一书的6.6中有详细介绍)
PREEMPTIVE_XX:切换到抢占模式通过windows调度做相关操作时出现的等待
PREEMPTIVE_OS_XX
这意味着
•线程直接调用OS
•线程切换到抢占式调度模式
•线程的状态是RUNNING,而不是SUSPENDED
更多分析
•SQL Server 2012中有194个该类事件
•这类事件文档非常少
•一个小技巧,在MSDN搜索PREEMPTIVE_OS_XX中的XX部分,这部分内容其实就是WINDOWS API
可能的解决方案
•要基于不同种类的等待类型来判断
 
PREEMPTIVE_OS_CREATEFILE
这意味着
•线程会调用Windows来创建文件
•如果使用了FileStream,当FileStream创建新的NTFS文件时,可能会导致该问题
更多分析
•查看不断增长的等待时间
可能的解决方案
•承载FileStream的IO性能不行
•使用FileStream的IO负载过重
•参考WIN32 API:http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
 
PREEMPTIVE_OS_WRITEFILEGATHER
这意味着
•线程会调用Windows来写入文件
避免望文生义
•不要只认为是IO问题
更多分析
•正在进行的数据库操作
•比如说还原数据库,数据库文件的创建、增长和自动增长
可能的解决办法
•在还原数据库或日志增长时对日志填零初始化
•对数据文件填零初始化
•启用快速文件初始化
•在进行数据库还原时,不要删除现有的文件
•参考WIN32 API:http://msdn.microsoft.com/en-us/library/windows/desktop/aa365749(v=vs.85).aspx
 
PREEMPTIVE_OS_WRITEFILEGATHER
这意味着
•一个线程调用Windows来等待同步对象的改变
•通常和NETWORK_IO以及ASYNC_NETWORK_IO一起出现
更多分析
•按照ASYNC_NETWORK_IO处理方式处理
•查看是否存在事务日志复制
可能的解决方案
•ASYNC_NETWORK_IO
•当APP服务器和数据库服务器在同一台时,使用共享内存
•当和NETWORK_IO一起时,很可能是事务日志复制
 
PREEMPTIVE_OS_DBMIRRORXX
示例
•DBMIRROR_EVENT_QUEUE
•DBMIRROR_SEND
•DBMIRRORING_CMD
•DBMIRROR_DBR_MUTEX
这意味着
•等待镜像资源
避免望文生义
•不要仅仅直接移除镜像或选择高性能模式
更多分析
•分析DBMIRROR_DBR_MUTEX的平均等待时间
可能的原因
•如果DBMIRROR_DBR_MUTEX的等待时间过多,则可能是由于镜像的数据库过多,或太多需要镜像的内容
•可能是由于常见的系统瓶颈
 
SQLTRACE_XX
这意味着
•线程等待写入SQLTRACE文件
避免望文生义
•不一定非要停止SQLTRACE
更多分析
•使用sys.traces和sys.fn_trace_geteventinfo是否跟踪了一些非常频繁的事件
•分析跟踪文件所在所在的IO
可能的原因
•跟踪捕获了太多的事件
•行集没有快速消费结果集
•第三方产品在扫描跟踪
 
LATCH_XX
这意味着
•存在非页闩锁
更多分析
•使用sys.dm_os_latch_stats来分析哪一个闩锁等待时间过长
•和其它同时发生的等待类型结合查看
•比如说CXPACKET和LATCH_EX与ACCESS_METHODs_SCAN_RANGE_GENERATOR往往意味着存在大量扫描
可能的解决方案
•这类锁是没有文档支持的,需要自行Google
•接下来探讨几页常见的锁
•微软白皮书:http://sqlcat.com/sqlcat/b/whitepapers/archive/2011/07/05/diagnosing-and-resolving-latch-contention-on-sql-server.aspx
 
 
THREADPOOL:等待可用的workthreads
DBMIRROR_DBM_MUTEX:发送buffer时出现的等待,可能是镜像回话过多
RESOUCE_SEMAPHORE:查询语句等待分配内存时出现,可能是查询语句过大或者需求的内存过大。
MSQL_DG: sql server等待分布式查询完成时出现,说明分布式查询有问题
RESOUCE_SEMAPHORE_QUERY_COMPLIE:过大的并发编译,主要是重编译和无缓冲plan造成
MSSEARCH:全文查询等待
 
参考:Wait statistics, or please tell me where it hurtd 
waitstats,latch,spinlock相关文章
等待类型bol
 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58

一、merge
1,利用merge不用再写update…insert,可以直接合并。
2,可以将更改的结果与更改前的结果输出
3,在sqlserver2008后引用。
4,源表中不能有重复的记录

参考:
MERGE (Transact-SQL)
SQL Server中的Merge关键字

二、output,在插入,更新,删除时记录

DELETE Sales.ShoppingCartItem
OUTPUT DELETED.* 
WHERE ShoppingCartID = 20621;

OUTPUT 子句 (Transact-SQL)


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
修改SQLServer默认端口
1,在TCP/IP协议属性的全部侦听为“是”时,修改IPALL的端口即可
2,在TCP/IP协议属性的全部侦听为“否”时,单独设置每个IP的端口
 
默认情况下:
TCP/IP协议属性的全部侦听值为“是”
意为:在IP地址的配置中,由IPALL统管一切,
IP地址中的TCP端口、活动、启用都是无效的,只要配置上IP,都会启用的,端口是IPALL配置的端口
即:IP地址中只配置IP地址。
 
当将TCP/IP协议属性的全部侦听值为“否”时
在IP地址的配置中,自己配置自己的,决定自己的端口,是否启用等。
 
注:SQL Server 数据库引擎可以侦听同一 IP 地址的多个端口,端口以逗号分隔的格式列出:1433,1500,1501。本字段最多允许 2047 个字符。
若要配置单个 IP 地址以侦听多个端口,还必须将“TCP/IP 属性”对话框的“协议”选项卡上的“全部侦听”参数设置为“否”。
 
静态端口与动态端口
SQL Server 的默认实例侦听端口 1433 的传入连接。可以出于安全性原因或根据客户端应用程序的请求来更改该端口。
默认情况下,命名实例(包含 SQL Server Express)被配置为侦听动态端口。若要配置静态端口,请将“TCP 动态端口”框保留为空,并在“TCP 端口”框中提供一个可用的端口号。
 
动态端口

如果未启用动态端口,则为空。若要使用动态端口,请设置为 0。
对于“IPAll”,将显示所用动态端口的端口号。
如果某个 SQL Server 实例已配置为侦听动态端口,则在启动时,该实例将检查操作系统中的可用端口,并为该端口打开一个端点。传入连接必须指定要连接的端口号。
由于每次启动 SQL Server 时端口号都可能会改变,因此 SQL Server 提供 SQL Server Browser 服务监视端口,
并将传入连接指向该实例的当前端口。使用动态端口会增加通过防火墙连接 SQL Server 的复杂性,因为重新启动 SQL Server 时端口号可能会改变,从而需要更改防火墙设置。
若要避免通过防火墙连接的问题,请将 SQL Server 配置为使用静态端口。

 
 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
Service Broker:多服务器单信息传递,大小写敏感
组成:
Message:信内容,为便于区分保证唯一性,信息的前缀用域名好一些。
Contracts:信头,组合message及message由哪边发送,发起者或者接收者
Queue:信封,收到的信息存储的位置

建立方式:
1,定义 SERVICE:将上面三者组合
2,信息发送:
BEGIN TRY
 BEGIN TRANSACTION;
  DECLARE @ch UNIQUEIDENTIFIER
  DECLARE @msg NVARCHAR(MAX);

  BEGIN DIALOG CONVERSATION @ch
   FROM SERVICE [InitiatorService]
   TO SERVICE 'TargetService'
   ON CONTRACT [http://ssb.csharp.at/SSB_Book/c03/HelloWorldContract]
   WITH ENCRYPTION = OFF;

  SET @msg = 
   '<HelloWorldRequest>
     Klaus Aschenbrenner
   </HelloWorldRequest>';

  SEND ON CONVERSATION @ch MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/RequestMessage] (@msg);
 COMMIT
END TRY
BEGIN CATCH
 ROLLBACK TRANSACTION
END CATCH
GO
3,接收信息
--***********************************************************************************
--*  Retrieve the sent message from the queue "TargetQueue" with a WAITFOR statement
--***********************************************************************************
DECLARE @cg UNIQUEIDENTIFIER
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE @messagebody XML;

BEGIN TRY
 BEGIN TRANSACTION;

  WAITFOR (
   RECEIVE TOP (1)
    @cg = conversation_group_id,
    @ch = conversation_handle,
    @messagetypename = message_type_name,
    @messagebody = CAST(message_body AS XML)
   FROM TargetQueue
  ), TIMEOUT 60000

  IF (@@ROWCOUNT > 0)
  BEGIN
   PRINT 'Conversation group: ' + CAST(@cg AS NVARCHAR(MAX))
   PRINT 'Conversation handle: ' + CAST(@ch AS NVARCHAR(MAX))
   PRINT 'Message type: ' + @messagetypename
   PRINT 'Message body: ' + CAST(@messagebody AS NVARCHAR(MAX))
  END

 COMMIT
END TRY
BEGIN CATCH
 ROLLBACK TRANSACTION
END CATCH
GO
4,监控对列
CREATE EVENT NOTIFICATION PoisonMessageNotification ON QUEUE TargetQueue
FOR Broker_Queue_Disabled
TO SERVICE 'PoisonMessageNotifyService', 'current database'
GO


---------------------------明细
USE master;

IF EXISTS (SELECT * FROM sys.databases WHERE name = 'Chapter3_HelloWorldSvc')
BEGIN
	PRINT 'Dropping database ''Chapter3_HelloWorldSvc''';
	DROP DATABASE Chapter3_HelloWorldSvc;
END
GO

CREATE DATABASE Chapter3_HelloWorldSvc
GO

USE Chapter3_HelloWorldSvc
GO

--*********************************************
--*  Create the message type "RequestMessage"
--*********************************************
CREATE MESSAGE TYPE
[http://ssb.csharp.at/SSB_Book/c03/RequestMessage]
VALIDATION = NONE
GO

--*********************************************
--*  Create the message type "ResponseMessage"
--*********************************************
CREATE MESSAGE TYPE
[http://ssb.csharp.at/SSB_Book/c03/ResponseMessage]
VALIDATION = NONE
GO

--*********************************************
--*  Show the created message types
--*********************************************
SELECT * FROM sys.service_message_types 
GO

--************************************************
--*  Changing the validation of the message types
--************************************************
ALTER MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/RequestMessage]
VALIDATION = WELL_FORMED_XML
GO

ALTER MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/ResponseMessage]
VALIDATION = WELL_FORMED_XML
GO

--************************************************
--*  Create the contract "HelloWorldContract"
--************************************************
CREATE CONTRACT [http://ssb.csharp.at/SSB_Book/c03/HelloWorldContract]
(
	[http://ssb.csharp.at/SSB_Book/c03/RequestMessage] SENT BY INITIATOR,
	[http://ssb.csharp.at/SSB_Book/c03/ResponseMessage] SENT BY TARGET
)
GO

--*************************************************************
--*  Getting some information about the newly created contract
--*************************************************************
SELECT 
	sc.name AS 'Contract', 
	mt.name AS 'Message type', 
	cm.is_sent_by_initiator,
	cm.is_sent_by_target,
	mt.validation
FROM sys.service_contract_message_usages cm 
	INNER JOIN sys.service_message_types mt ON cm.message_type_id = mt.message_type_id
	INNER JOIN sys.service_contracts sc ON sc.service_contract_id = cm.service_contract_id
GO

--********************************************************
--*  Create the queues "InitiatorQueue" and "TargetQueue"
--********************************************************
CREATE QUEUE InitiatorQueue
WITH STATUS = ON
GO

CREATE QUEUE TargetQueue
WITH STATUS = ON
GO

--*************************************************************
--*  Getting some information about the newly created queues
--*************************************************************
SELECT * FROM sys.service_queues
GO

--************************************************************
--*  Create the queues "InitiatorService" and "TargetService"
--************************************************************
CREATE SERVICE InitiatorService
ON QUEUE InitiatorQueue 
(
	[http://ssb.csharp.at/SSB_Book/c03/HelloWorldContract]
)
GO

CREATE SERVICE TargetService
ON QUEUE TargetQueue
(
	[http://ssb.csharp.at/SSB_Book/c03/HelloWorldContract]
)
GO

--*************************************************************
--*  Getting some information about the newly created services
--*************************************************************
SELECT
	sv.name AS 'Service',
	sc.name AS 'Contract'
FROM sys.services sv
	INNER JOIN sys.service_contract_usages scu ON scu.service_id = sv.service_id
	INNER JOIN sys.service_contracts sc ON sc.service_contract_id = scu.service_contract_id
GO

--********************************************************************
--*  Sending a message from the InitiatorService to the TargetService
--********************************************************************
BEGIN TRY
	BEGIN TRANSACTION;
		DECLARE @ch UNIQUEIDENTIFIER
		DECLARE @msg NVARCHAR(MAX);

		BEGIN DIALOG CONVERSATION @ch
			FROM SERVICE [InitiatorService]
			TO SERVICE 'TargetService'
			ON CONTRACT [http://ssb.csharp.at/SSB_Book/c03/HelloWorldContract]
			WITH ENCRYPTION = OFF;

		SET @msg = 
			'<HelloWorldRequest>
					Klaus Aschenbrenner
			</HelloWorldRequest>';

		SEND ON CONVERSATION @ch MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/RequestMessage] (@msg);
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO

--********************************************************************
--*  View the sent message on the queue "TargetQueue"
--********************************************************************
SELECT * FROM TargetQueue
GO

--********************************************************************
--*  View the created conversation endpoints
--********************************************************************
SELECT * FROM sys.conversation_endpoints
GO

--********************************************************************
--*  Retrieve the sent message from the queue "TargetQueue"
--********************************************************************
DECLARE @cg UNIQUEIDENTIFIER
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML;

BEGIN TRY
	BEGIN TRANSACTION;

		RECEIVE TOP(1)
			@cg = conversation_group_id,
			@ch = conversation_handle,
			@messagetypename = message_type_name,
			@messagebody = CAST(message_body AS XML)
		FROM TargetQueue

		PRINT 'Conversation group: ' + CAST(@cg AS NVARCHAR(MAX))
		PRINT 'Conversation handle: ' + CAST(@ch AS NVARCHAR(MAX))
		PRINT 'Message type: ' + @messagetypename
		PRINT 'Message body: ' + CAST(@messagebody AS NVARCHAR(MAX))

	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO

--***********************************************************************************
--*  Retrieve the sent message from the queue "TargetQueue" with a WAITFOR statement
--***********************************************************************************
DECLARE @cg UNIQUEIDENTIFIER
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML;

BEGIN TRY
	BEGIN TRANSACTION;

		WAITFOR (
			RECEIVE TOP (1)
				@cg = conversation_group_id,
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM TargetQueue
		), TIMEOUT 60000

		IF (@@ROWCOUNT > 0)
		BEGIN
			PRINT 'Conversation group: ' + CAST(@cg AS NVARCHAR(MAX))
			PRINT 'Conversation handle: ' + CAST(@ch AS NVARCHAR(MAX))
			PRINT 'Message type: ' + @messagetypename
			PRINT 'Message body: ' + CAST(@messagebody AS NVARCHAR(MAX))
		END

	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO

--**************************************************
--*  Create a table to store the processed messages
--**************************************************
CREATE TABLE ProcessedMessages
(
	ID UNIQUEIDENTIFIER NOT NULL,
	MessageBody XML NOT NULL,
	ServiceName NVARCHAR(MAX) NOT NULL
)
GO

--*******************************************************************
--*  Send a response message back to the service "InitiatorService"
--*******************************************************************
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML
DECLARE @responsemessage XML;

BEGIN TRY
	BEGIN TRANSACTION
		WAITFOR (
			RECEIVE TOP (1)
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM TargetQueue
		), TIMEOUT 60000

		IF (@@ROWCOUNT > 0)
		BEGIN
			IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/RequestMessage')
			BEGIN
				-- Store the received request message in a table
				INSERT INTO ProcessedMessages (ID, MessageBody, ServiceName) VALUES (NEWID(), @messagebody, 'TargetService')

				-- Construct the response message
				SET @responsemessage = '<HelloWorldResponse>' + @messagebody.value('/HelloWorldRequest[1]', 'NVARCHAR(MAX)') + '</HelloWorldResponse>';

				-- Send the response message back to the initiating service
				SEND ON CONVERSATION @ch MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/ResponseMessage] (@responsemessage);

				-- End the conversation on the target's side
				END CONVERSATION @ch;
			END
		END
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO


--********************************************************************
--*  View the sent message on the queue "InitiatorQueue"
--********************************************************************
SELECT * FROM InitiatorQueue
GO

--********************************************************************
--*  View the processed message in the table "ProcessedMessages"
--********************************************************************
SELECT * FROM ProcessedMessages
GO

--*******************************************************************
--*  Service program for the service "InitiatorService"
--*******************************************************************
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML;

BEGIN TRY
	BEGIN TRANSACTION
		WAITFOR (
			RECEIVE TOP (1)
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM InitiatorQueue
		), TIMEOUT 60000

		IF (@@ROWCOUNT > 0)
		BEGIN
			IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/ResponseMessage')
			BEGIN
				-- Store the received response) message in a table
				INSERT INTO ProcessedMessages (ID, MessageBody, ServiceName) VALUES (NEWID(), @messagebody, 'InitiatorService')
			END

			IF (@messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
			BEGIN
				-- End the conversation on the initiator's side
				END CONVERSATION @ch;
			END
		END
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO

--***********************************************************************************
--*  Endless receive loop for processing incoming messages on the initiator's queue
--***********************************************************************************
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML;

WHILE (1=1)
BEGIN
	BEGIN TRY
		BEGIN TRANSACTION

		WAITFOR (
			RECEIVE TOP (1)
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM InitiatorQueue
		), TIMEOUT 60000

		IF (@@ROWCOUNT = 0)
		BEGIN
			ROLLBACK TRANSACTION
			BREAK
		END

		IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/ResponseMessage')
		BEGIN
			-- Store the received response) message in a table
			INSERT INTO ProcessedMessages (ID, MessageBody, ServiceName) VALUES (NEWID(), @messagebody, 'InitiatorService')
		END

		IF (@messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
		BEGIN
			-- End the conversation on the initiator's side
			END CONVERSATION @ch;
		END

		COMMIT TRANSACTION
	END TRY
	BEGIN CATCH
		ROLLBACK TRANSACTION
	END CATCH
END
GO

--********************************************************************************
--*  Endless receive loop for processing incoming messages on the target's queue
--********************************************************************************
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML
DECLARE @responsemessage XML;

WHILE (1=1)
BEGIN
	BEGIN TRY
		BEGIN TRANSACTION

		WAITFOR (
			RECEIVE TOP (1)
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM TargetQueue
		), TIMEOUT 60000

		IF (@@ROWCOUNT = 0)
		BEGIN
			ROLLBACK TRANSACTION
			BREAK
		END

		IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/RequestMessage')
		BEGIN
			-- Store the received request message in a table
			INSERT INTO ProcessedMessages (ID, MessageBody, ServiceName) VALUES (NEWID(), @messagebody, 'TargetService')

			-- Construct the response message
			SET @responsemessage = '<HelloWorldResponse>' + @messagebody.value('/HelloWorldRequest[1]', 'nvarchar(max)') + '</HelloWorldResponse>';

			-- Send the response message back to the initiating service
			SEND ON CONVERSATION @ch MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/ResponseMessage] (@responsemessage);

			-- End the conversation on the target's side
			END CONVERSATION @ch;
		END

		IF (@messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
		BEGIN
			-- End the conversation
			END CONVERSATION @ch;
		END

		COMMIT TRANSACTION
	END TRY
	BEGIN CATCH
		ROLLBACK TRANSACTION
	END CATCH
END
GO

--**********************************************************
--*  Error handling with a savepoint on the target's queue
--**********************************************************
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML
DECLARE @responsemessage XML;

WHILE (1=1)
BEGIN
	BEGIN TRANSACTION

	WAITFOR (
		RECEIVE TOP (1)
			@ch = conversation_handle,
			@messagetypename = message_type_name,
			@messagebody = CAST(message_body AS XML)
		FROM TargetQueue
	), TIMEOUT 60000

	IF (@@ROWCOUNT = 0)
	BEGIN
		ROLLBACK TRANSACTION
		BREAK
	END

	SAVE TRANSACTION MessageReceivedSavepoint

	IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/RequestMessage')
	BEGIN
		BEGIN TRY
			-- Store the received request message in a table
			INSERT INTO ProcessedMessages (ID, MessageBody, ServiceName) VALUES (NEWID(), @messagebody, 'TargetService')

			-- Construct the response message
			SET @responsemessage = '<HelloWorldResponse>' + @messagebody.value('/HelloWorldRequest[1]', 'nvarchar(max)') + '</HelloWorldResponse>';

			-- Send the response message back to the initiating service
			SEND ON CONVERSATION @ch MESSAGE TYPE [http://ssb.csharp.at/SSB_Book/c03/ResponseMessage] (@responsemessage);

			-- End the conversation on the target's side
			END CONVERSATION @ch;
		END TRY
		BEGIN CATCH
			IF (ERROR_NUMBER() = 1205) 
			BEGIN
				-- A deadlock occurred. 
				-- We can try it again...
				ROLLBACK TRANSACTION
				CONTINUE
			END
			ELSE
			BEGIN
				-- A other error occurred.
				-- The message can't be processed successfully, because it's a poison message
				ROLLBACK TRANSACTION MessageReceivedSavepoint
				PRINT 'Error occured: ' + CAST(@messagebody AS NVARCHAR(MAX))
			END
		END CATCH
	END

	IF (@messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
	BEGIN
		-- End the conversation
		END CONVERSATION @ch;
	END

	COMMIT TRANSACTION
END
GO

--**************************************
--*  Poison messages in Service Broker
--**************************************
-- Reactivating the queue
ALTER QUEUE TargetQueue WITH STATUS = ON
GO

-- Service program for handling the poison message
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML

WHILE (1=1)
BEGIN
	BEGIN TRANSACTION

	WAITFOR (
		RECEIVE TOP (1)
			@ch = conversation_handle,
			@messagetypename = message_type_name,
			@messagebody = CAST(message_body AS XML)
		FROM TargetQueue
	), TIMEOUT 60000

	IF (@@ROWCOUNT = 0)
	BEGIN
		ROLLBACK TRANSACTION
		BREAK
	END

	-- Rollling back the current transaction
	PRINT 'Rollback the current transaction - simulating a poison message...'
	ROLLBACK TRANSACTION
END
GO

--**********************************************************
--*  Setting up the event notification for poison messages
--**********************************************************
-- Create the queue which stores the event notification messages
CREATE QUEUE PoisonMessageNotifyQueue
GO

-- Create the service that accepts the event notification messages
CREATE SERVICE PoisonMessageNotifyService ON QUEUE PoisonMessageNotifyQueue
(
	[http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]
);
GO

-- Create the event notification itself
CREATE EVENT NOTIFICATION PoisonMessageNotification ON QUEUE TargetQueue
FOR Broker_Queue_Disabled
TO SERVICE 'PoisonMessageNotifyService', 'current database'
GO

-- Select the received event notification message
SELECT * FROM PoisonMessageNotifyQueue
GO

--**********************************************************
--*  End an conversation with an error
--**********************************************************
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML

BEGIN TRY
	BEGIN TRANSACTION
		WAITFOR (
			RECEIVE TOP (1)
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM TargetQueue
		), TIMEOUT 60000

		IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/RequestMessage')
		BEGIN
			-- End the conversation with an error
			END CONVERSATION @ch WITH ERROR = 4242 DESCRIPTION = 'My custom error message'
		END
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO

-- Table that stores error information
CREATE TABLE ErrorLog
(
	ID UNIQUEIDENTIFIER NOT NULL,
	ErrorCode INT NOT NULL,
	ErrorMessage NVARCHAR(MAX) NOT NULL
)
GO

-- Service program for the InitiatorService, that handles also error message types
DECLARE @ch UNIQUEIDENTIFIER 
DECLARE @messagetypename NVARCHAR(256)
DECLARE	@messagebody XML
DECLARE @errorcode INT
DECLARE @errormessage NVARCHAR(3000);

BEGIN TRY
	BEGIN TRANSACTION
		WAITFOR (
			RECEIVE TOP(1)
				@ch = conversation_handle,
				@messagetypename = message_type_name,
				@messagebody = CAST(message_body AS XML)
			FROM InitiatorQueue
		), TIMEOUT 60000

		IF (@@ROWCOUNT > 0)
		BEGIN
			IF (@messagetypename = 'http://ssb.csharp.at/SSB_Book/c03/ResponseMessage')
			BEGIN
				-- Store the received response) message in a table
				INSERT INTO ProcessedMessages (ID, MessageBody, ServiceName) VALUES (NEWID(), @messagebody, 'InitiatorService')
			END

			IF (@messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
			BEGIN
				-- End the conversation on the initiator's side
				END CONVERSATION @ch;
			END

			IF (@messagetypename = 'http://schemas.microsoft.com/SQL/ServiceBroker/Error')
			BEGIN
				-- Extract the error information from the sent message
				SET @errorcode = (SELECT @messagebody.value(
					N'declare namespace brokerns="http://schemas.microsoft.com/SQL/ServiceBroker/Error"; 
					(/brokerns:Error/brokerns:Code)[1]', 'int'));
				SET @errormessage = (SELECT @messagebody.value(
					'declare namespace brokerns="http://schemas.microsoft.com/SQL/ServiceBroker/Error";
					(/brokerns:Error/brokerns:Description)[1]', 'nvarchar(3000)'));

				-- Log the error
				INSERT INTO ErrorLog(ID, ErrorCode, ErrorMessage)
				VALUES (NEWID(), @errorcode, @errormessage)

				-- End the conversation on the initiator's side
				END CONVERSATION @ch;
			END
		END
	COMMIT
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
END CATCH
GO


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
--find SQL login with blank passwords
select name,type_desc,create_date from sys.sql_logins where pwdcompare('', password_hash) = 1

--find SQL login with password same as name
select name,type_desc,create_date from sys.sql_logins where pwdcompare(name, password_hash) = 1

--比对sa的密码是否为123abc
SELECT TOP 50 * 
FROM sys.sql_logins sl
WHERE name = 'sa' AND pwdcompare('123abc', password_hash) = 1


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
with(nolock)并意味着没有锁,实际上在查询一张表时,还是有锁,会对对象增加架构锁,
防止表会修改,会对数据库增加共享锁。若使用drop index,则要等到架构锁释放。

sql server2005提供了快照隔离和读取已提交快照这两种新的不加锁、无阻塞的事务隔离级别,可使用
快照:每次从数据进行修改时,会在teampdb上存储上一版本
好处:
select不要求锁,会大大降低整个库的锁负载量
nolock会读取到未提交事务时修改的数据,而读快照读取的是修改之前的数据,故nolock易读取到脏数据
读快照与nolock相同的地方在于都不加共享锁,但都会加对象架构锁与数据库的共享锁,区别在于,nolock需要
在每个sql语句后加,而读快照不用,并用读快照不会读到未提交事务的数据。
行版本控制:在任何一个修改之前,先对修改前的版本做一个复制 ,后续的一切读操作都会去读这个复制的版本,修改将创建一个新的版本。在这种处理方式下,读、写操作不会相互阻塞。使用这种行版本控制机制的好处,是程序的并发性比较高,但是缺点是用户读到的虽然不是一个脏数据,但是可能是个正在被修改马上就要过期的数据值
【注:加上行版本控制后,会最大限度降低死锁,但不是没有死锁】

相关存储过程:select * from sys.dm_tran_version_store


把SQL Server数据库事务隔离级别设置为已提交读快照隔离:
如果直接运行下面的语句:
ALTER Database [mydbname] SET READ_COMMITTED_SNAPSHOT ON
会可能被阻塞很长时间。
你可以选择运行下面的语句:
if(charindex('Microsoft SQL Server 2005',@@version) > 0)
begin
declare @sql varchar(8000)
select @sql = '
ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'
Exec(@sql)
end
通过查询 sys.databases的 is_read_committed_snapshot_on字段
select is_read_committed_snapshot_on from sys.databases where name = DB_Name()
is_read_committed_snapshot_on如果为1表示目前为已提交读快照隔离级别

引用:
7 Things Developers Should Know About SQL Server
Using Read-Committed Snapshot Isolation - Mini-Lab
SQL Server已提交读快照隔离级别的设置
SQL Server 2005使用基于行版本控制的隔离级别初探


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58

在sqlserver服务器有一个名为SQL Server Browser的服务,一直没用到,最近一台服务器安装了多个实例,其中一个实例在外部怎么都访问不了,这时查资料才明白需要开启SQL Server Browser服务。
如果一个物理服务器上面有多个SQL Server实例,那么为了确保客户端能访问到正确的实例,所以SQL Server 2005以后提供了一个新的Browser服务。
参考:SQL Server : Browser服务是干什么的


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
--只有mdf文件,没有ldf文件,可通过选项来恢复。FOR ATTACH_REBUILD_LOG;
--有日志文件则附加上,若无,则新建
CREATE DATABASE AdventureWorks2012
ON (FILENAME = 'M:\Program Files\Microsoft SQL Server201201\MSSQL11.MSSQLSERVER\MSSQL\DATA\AdventureWorks2012_Data.mdf')
FOR ATTACH_REBUILD_LOG;


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Repl_DropArticlePeer]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[Repl_DropArticlePeer]
GO

/*对等复制删除Article
 EXEC LS_DropArticlePeer 'testrepl'
*/
CREATE PROCEDURE Repl_DropArticlePeer
@article AS sysname
AS 
BEGIN 
	IF ISNULL(@article,'') = ''
	BEGIN
		RETURN
	END  

       DECLARE @publication AS sysname;  
	SET @publication =DB_NAME(); 
	--SET @article = N'testRepl'

	--删除对应订阅
	IF @@SERVERNAME = 'DataBaseC' --在哪台机器上运行,就不删除自己
	BEGIN
		--exec sp_dropsubscription @publication = @publication, @article = @article, @subscriber = 'databasec'
		exec sp_dropsubscription @publication =@publication, @article =@article, @subscriber = 'DataBaseD'
		exec sp_dropsubscription @publication = @publication, @article = @article, @subscriber = 'sqlcluster'
	END
	ELSE IF @@SERVERNAME = 'DataBaseD'
	BEGIN
		exec sp_dropsubscription @publication = @publication, @article = @article, @subscriber = 'databasec'
		--exec sp_dropsubscription @publication =@publication, @article =@article, @subscriber = 'DataBaseD'
		exec sp_dropsubscription @publication = @publication, @article = @article, @subscriber = 'sqlcluster'
	END
	ELSE IF @@SERVERNAME = 'SQLCLUSTER'
	BEGIN
		exec sp_dropsubscription @publication = @publication, @article = @article, @subscriber = 'databasec'
		exec sp_dropsubscription @publication =@publication, @article =@article, @subscriber = 'DataBaseD'
		--exec sp_dropsubscription @publication = @publication, @article = @article, @subscriber = 'sqlcluster'
	END


	EXEC sp_droparticle 
	  @publication = @publication, 
	  @article = @article,
	  @force_invalidate_snapshot = 1;
END 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Repl_AddArticlePeer]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[Repl_AddArticlePeer]
GO

/*对等复制增加Article
 EXEC Repl_AddArticlePeer 'testrepl'
*/

CREATE PROCEDURE Repl_AddArticlePeer
@article AS sysname
AS 
BEGIN 
	IF ISNULL(@article,'') = ''
	BEGIN
		RETURN
	END  

	DECLARE @publication AS sysname;  
	SET @publication =DB_NAME(); 

	DECLARE
        @ins_cmd	nvarchar (255),
        @del_cmd	nvarchar (255),
        @upd_cmd	nvarchar (255) 

	SET @ins_cmd = 'CALL sp_MS' + 'ins' + '_dbo' + @article
	SET @del_cmd = 'CALL sp_MS' + 'del' + '_dbo' + @article
	SET @upd_cmd = 'CALL sp_MS' + 'upd' + '_dbo' + @article

	EXEC sp_addarticle @publication = @publication, @article = @article, @source_owner = N'dbo', 
	@source_object =@article, @type = N'logbased', @description = null,@creation_script = null,
	@pre_creation_cmd = N'drop', @schema_option = 0x0000000008035DDB, @force_invalidate_snapshot = 1, @identityrangemanagementoption = N'manual', 
	@destination_table = @article, @status = 16,@vertical_partition = N'false', @ins_cmd = @ins_cmd, @del_cmd = @del_cmd, @upd_cmd = @upd_cmd
END 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
系统信息级别:http://blog.sqlauthority.com/2007/04/25/sql-server-error-messages-sysmessages-error-severity-level/

测试:
BEGIN TRY
    -- Generate a divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
    SELECT ERROR_SEVERITY() AS ErrorSeverity;
END CATCH;

当sqlserver有用户级错误时记录
CREATE event session xEvents_Session on server
add event sqlserver.error_reported
(
action
(
sqlserver.session_id, -- SPID which raises the error
sqlserver.plan_handle, -- Plan handle which can be used to retrieve the graphical plan
sqlserver.tsql_stack, -- T-SQL stack for extended debugging purposes
package0.callstack, -- Callstack for extended debugging purposes
sqlserver.sql_text, -- T-SQL query which encountered the error
sqlserver.username, -- Name of the user that reported the error
sqlserver.client_app_name, -- Client application name
sqlserver.client_hostname, -- Host which initiated the query
sqlserver.database_name -- Database against which the query was being executed
) 
 WHERE severity >= 11 AND Severity <=16
)
add target package0.ring_buffer
with (max_dispatch_latency=1seconds)
GO
-- start the tracing
alter event session xEvents_Session on server state = start

--alter event session xEvents_Session on server state = stop
--drop event session xEvents_Session on SERVER



--查看

SELECT 
    n.value('(event/@name)[1]', 'varchar(50)') AS event_name,
    n.value('(event/@package)[1]', 'varchar(50)') AS package_name,
    DATEADD(hh, 
            DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP), 
            n.value('(event/@timestamp)[1]', 'datetime2')) AS [timestamp],  
n.value('(event/action[@name="database_name"]/value)[1]', 'nvarchar(128)') AS [database_name],
    n.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS [sql_text],
n.value('(event/data[@name="message"]/value)[1]', 'nvarchar(max)') AS [message],
n.value('(event/action[@name="username"]/value)[1]', 'nvarchar(max)') AS [username],
n.value('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(max)') AS [client_hostname],
n.value('(event/action[@name="client_app_name"]/value)[1]', 'nvarchar(max)') AS [client_app_name],
n.value('(event/action[@name="session_id"]/value)[1]', 'nvarchar(max)') AS [session_id],
n.value('(event/action[@name="plan_handle"]/value)[1]', 'nvarchar(max)') AS [plan_handle],
n.value('(event/action[@name="tsql_stack"]/value/frames/frame/@handle)[1]', 'varchar(max)') AS [tsql_stack],
n.value('(event/action[@name="tsql_stack"]/value/frames/frame/@offsetStart)[1]', 'int') AS [statement_start_offset],
n.value('(event/action[@name="tsql_stack"]/value/frames/frame/@offsetEnd)[1]', 'int') AS [statement_end_offset],
n.value('(event/action[@name="callstack"]/value)[1]', 'nvarchar(max)') AS [callstack],
n.value('(event/data[@name="object_id"]/value)[1]', 'int') AS [object_id],
    n.value('(event/data[@name="object_type"]/value)[1]', 'nvarchar(128)') AS [object_type],
    n.value('(event/data[@name="duration"]/value)[1]', 'int') AS [duration],
    n.value('(event/data[@name="cpu"]/value)[1]', 'int') AS [cpu],
    n.value('(event/data[@name="reads"]/value)[1]', 'int') AS [reads],
    n.value('(event/data[@name="writes"]/value)[1]', 'int') AS [writes] into #1120
FROM
(    SELECT td.query('.') as n
    FROM 
    (
        SELECT CAST(target_data AS XML) as target_data
        FROM sys.dm_xe_sessions AS s 
        JOIN sys.dm_xe_session_targets AS t 
            ON t.event_session_address = s.address
        WHERE s.name = 'xEvents_Session'
          --AND t.target_name = 'ring_buffer'
    ) AS sub
    CROSS APPLY target_data.nodes('RingBufferTarget/event') AS q(td)
) as TAB

--查看有sql的
SELECT TIMESTAMP,database_name,[message],sql_text,username,client_hostname,client_app_name
FROM #1120 a
WHERE a.sql_text != ''


--查看应用执行的
SELECT TIMESTAMP,database_name,[message],
SUBSTRING(qt.text,a.statement_start_offset/2+1,
(case when a.statement_end_offset = -1
then DATALENGTH(qt.text) 
else a.statement_end_offset end -a.statement_start_offset)/2 + 1) sql_text,qt.text alltext,
username,client_hostname,client_app_name
FROM #1120 a
CROSS APPLY sys.dm_exec_sql_text(CONVERT(VARBINARY(max),a.tsql_stack,1) )  qt
WHERE a.sql_text IS NULL AND tsql_stack != '' AND client_app_name = '.Net SqlClient Data Provider'
ORDER BY TIMESTAMP DESC


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
--以下xevent记录了通过sqlserver查询工具直接更新,删除表数据时的记录。
IF NOT EXISTS( SELECT 1 FROM sys.dm_xe_sessions dxs(NOLOCK) WHERE name = 'EventErrorMonitor' )
BEGIN 
	CREATE EVENT session EventErrorMonitor on server
	ADD EVENT sqlserver.error_reported
	(
	ACTION
	(
	sqlserver.session_id, -- SPID which raises the error
	sqlserver.plan_handle, -- Plan handle which can be used to retrieve the graphical plan
	sqlserver.tsql_stack, -- T-SQL stack for extended debugging purposes
	package0.callstack, -- Callstack for extended debugging purposes
	sqlserver.sql_text, -- T-SQL query which encountered the error
	sqlserver.username, -- Name of the user that reported the error
	sqlserver.client_app_name, -- Client application name
	sqlserver.client_hostname, -- Host which initiated the query
	sqlserver.database_name -- Database against which the query was being executed
	) 
	 WHERE severity >= 11 AND Severity <=16
	)
	ADD TARGET package0.ring_buffer
	WITH (max_dispatch_latency=1seconds)

	ALTER EVENT SESSION EventErrorMonitor on server state = START
  
END 
ELSE
BEGIN

	SELECT 
		 DATEADD(hh, 
				DATEDIFF(hh, GETUTCDATE(), CURRENT_TIMESTAMP), 
				n.value('(event/@timestamp)[1]', 'datetime2')) AS [timestamp],  
		n.value('(event/action[@name="database_name"]/value)[1]', 'nvarchar(128)') AS [database_name],
		n.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS [sql_text],
		n.value('(event/data[@name="message"]/value)[1]', 'nvarchar(max)') AS [message],
		n.value('(event/action[@name="username"]/value)[1]', 'nvarchar(max)') AS [username],
		n.value('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(max)') AS [client_hostname],
		n.value('(event/action[@name="client_app_name"]/value)[1]', 'nvarchar(max)') AS [client_app_name],
		n.value('(event/action[@name="tsql_stack"]/value/frames/frame/@handle)[1]', 'varchar(max)') AS [tsql_stack],
		n.value('(event/action[@name="tsql_stack"]/value/frames/frame/@offsetStart)[1]', 'int') AS [statement_start_offset],
		n.value('(event/action[@name="tsql_stack"]/value/frames/frame/@offsetEnd)[1]', 'int') AS [statement_end_offset]
	into #ErrorMonitor
	FROM
	(    SELECT td.query('.') as n
		FROM 
		(
			SELECT CAST(target_data AS XML) as target_data
			FROM sys.dm_xe_sessions AS s 
			JOIN sys.dm_xe_session_targets AS t 
				ON t.event_session_address = s.address
			WHERE s.name = 'EventErrorMonitor'
			  --AND t.target_name = 'ring_buffer'
		) AS sub
		CROSS APPLY target_data.nodes('RingBufferTarget/event') AS q(td)
	) as TAB
  
	INSERT INTO PerfLogicMessage(StartTime,database_name,message,sql_text,alltext,username,client_hostname,client_app_name)
	SELECT TIMESTAMP,database_name,[message],sql_text,'',username,client_hostname,client_app_name
	FROM #ErrorMonitor a
	WHERE a.sql_text != '' AND client_app_name !='Microsoft SQL Server Management Studio - 查询'

	INSERT INTO PerfLogicMessage(StartTime,database_name,message,sql_text,alltext,username,client_hostname,client_app_name)
	--查看应用执行的
	SELECT  TIMESTAMP,database_name,[message],
	SUBSTRING(qt.text,a.statement_start_offset/2+1,
				(case when a.statement_end_offset = -1
				then DATALENGTH(qt.text) 
				else a.statement_end_offset end -a.statement_start_offset)/2 + 1) sql_text,qt.text alltext,
	username,client_hostname,client_app_name
	FROM #ErrorMonitor a
	CROSS APPLY sys.dm_exec_sql_text(CONVERT(VARBINARY(max),a.tsql_stack,1) )  qt
	WHERE a.sql_text IS NULL AND tsql_stack != '' AND client_app_name = '.Net SqlClient Data Provider'

	DROP TABLE #ErrorMonitor

	--重启以清空
	ALTER EVENT SESSION EventErrorMonitor ON SERVER STATE = STOP
	ALTER EVENT SESSION EventErrorMonitor on server state = START
END 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
XEVENT:在指定事件发生时记录,可将日志放在内存或文件中,效率比sqlprofile高。
参考:
Introduction to Extended Events
Troubleshooting Error 511 using XEvents

相关DMV1
相关DMV2

相关DMV:

Events
-- Event objects
SELECT p.name AS package_name,
       o.name AS event_name,
       o.description
FROM sys.dm_xe_packages AS p
JOIN sys.dm_xe_objects AS o 
     ON p.guid = o.package_guid
WHERE (p.capabilities IS NULL OR p.capabilities & 1 = 0)
  AND (o.capabilities IS NULL OR o.capabilities & 1 = 0)
  AND o.object_type = 'event'
Actions

-- Actions
SELECT p.name AS package_name,
       o.name AS action_name,
       o.description
FROM sys.dm_xe_packages AS p
JOIN sys.dm_xe_objects AS o 
     ON p.guid = o.package_guid
WHERE (p.capabilities IS NULL OR p.capabilities & 1 = 0)
  AND (o.capabilities IS NULL OR o.capabilities & 1 = 0)
  AND o.object_type = 'action' 
Targets

--Event获取的数据

select * from sys.dm_xe_object_columns
where object_name = 'lock_acquired' and column_type = 'data'


-- Targets
SELECT p.name AS package_name,
       o.name AS target_name,
       o.description
FROM sys.dm_xe_packages AS p
JOIN sys.dm_xe_objects AS o ON p.guid = o.package_guid
WHERE (p.capabilities IS NULL OR p.capabilities & 1 = 0)
  AND (o.capabilities IS NULL OR o.capabilities & 1 = 0)
  AND o.object_type = 'target'
 


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
--varchar -> varbinary
declare @hexstring varchar(64),@binstring varbinary(64)
set @hexstring = '0x01000200A09EFC30B04A69DE02000000000000000000000000000000000000';
SET @binstring = CONVERT(varbinary(64), @hexstring, 1);
SELECT @binstring
go

--varbinary -> varchar
declare @hexstring varchar(64),@binstring varbinary(64)
set @binstring = 0x01000200A09EFC30B04A69DE02000000000000000000000000000000000000
SET @hexstring = master.dbo.fn_varbintohexstr(@binstring)
SELECT @hexstring