-- 查看性能记数器

 
 
 
SELECT * FROM sys.dm_os_performance_counters
 
 
 
 -- 执行过的线程所遇到的所有等待(不是当前正在运行的线程, 为自上次重置统计信息或启动服务器以来累积的数据),可分析靠前的几个等待较高的事件。
 
select * from sys.dm_os_wait_stats order by wait_time_ms desc
该动态视图的细节,请查看帮助文档. 
 
 
 
-- 重置该动态视图
DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR);
GO
 
 
 
 
 
 -- 正在等待某些资源的任务的等待队列
 
 select * from sys.dm_os_waiting_tasks order by wait_duration_ms desc
 
 
 
 
 
 
 
 
 
 
 
内存使用:  
查看当前由 SQL Server 分配的内存对象(KB): select sum((page_size_in_bytes/1024)*max_pages_allocated_count) from sys.dm_os_memory_objects;
查看系统内存当前信息: select * from sys.dm_os_sys_memory (这个动态视图只在sql 2008中才有)
select 
cpu_count,
hyperthread_ratio,
scheduler_count,
physical_memory_in_bytes / 1024 / 1024 as physical_memory_mb,
virtual_memory_in_bytes / 1024 / 1024 as virtual_memory_mb,
bpool_committed * 8 / 1024 as bpool_committed_mb,
bpool_commit_target * 8 / 1024 as bpool_target_mb,
bpool_visible * 8 / 1024 as bpool_visible_mb
from sys.dm_os_sys_info
 
 
 
限制SQL Server使用的最小,最大内存(MB):
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'min server memory', 300;
GO
sp_configure 'max server memory', 850;
GO
RECONFIGURE;
GO
 
 
CPU使用情况:
 
 
SELECT TOP 50
total_worker_time/execution_count AS '每次执行占用CPU(微秒)',
execution_count       as '执行次数',
total_worker_time     as '总共占用CPU(微秒)',
creation_time         as '创建时间',
last_execution_time   as '最后执行时间',
min_worker_time       as '最低每次占用CPU',
max_worker_time       as '最高每次占用cpu',
total_physical_reads  as '总共io物理读取次数',
total_logical_reads   as '总共逻辑读取次数',
total_logical_writes  as '总共逻辑写次数',
total_elapsed_time    as '完成此计划的执行所占用的总时间(微秒)',
(SELECT SUBSTRING(text,statement_start_offset/2,(CASE WHEN statement_end_offset = -1 then LEN(CONVERT(nvarchar(max), text)) * 2 ELSE statement_end_offset end -statement_start_offset)/2) FROM sys.dm_exec_sql_text(sql_handle)) AS 'SQL内容'
FROM sys.dm_exec_query_stats
ORDER BY 1 DESC
 
 
 
--下面的查询显示SQL 等待分析和前10 个等待的资源
 
select top 10 *
from sys.dm_os_wait_stats
where wait_type not in ('CLR_SEMAPHORE','LAZYWRITER_SLEEP','RESOURCE_QUEUE','SLEEP_TASK','SLEEP_SYSTEMTASK','WAITFOR')
order by wait_time_ms desc;
 
 
SQL Server中的活动会话数:
exec   sp_who   'active'
print @@rowcount
 
 
 
SQL Server等待情况
select * from sys.dm_os_waiting_tasks ; --当前等待事件
select * from sys.dm_os_wait_stats  --历史等待次数,是sqlserver启动后的累计值,需使用下一条语句清空
DBCC SQLPERF ('sys.dm_os_wait_stats', CLEAR);
 
 
找出进程阻塞:
运行下面的查询可确定阻塞的会话
select blocking_session_id, wait_duration_ms, session_id from 
sys.dm_os_waiting_tasks
where blocking_session_id is not null
 
 
 
spid 正在阻塞另一个 spid,可在数据库中创建以下存储过程,然后执行该存储过程。此存储过程会报告此阻塞情况。键入 sp_who 可找出 @spid;@spid 是可选参数。
 
 
create proc dbo.sp_block (@spid bigint=NULL)
as
select 
    t1.resource_type,
    'database'=db_name(resource_database_id),
    'blk object' = t1.resource_associated_entity_id,
    t1.request_mode,
    t1.request_session_id,
    t2.blocking_session_id    
from 
    sys.dm_tran_locks as t1, 
    sys.dm_os_waiting_tasks as t2
where 
    t1.lock_owner_address = t2.resource_address and
    t1.request_session_id = isnull(@spid,t1.request_session_id)
 
以下是使用此存储过程的示例。
exec sp_block
exec sp_block @spid = 7
 
select sum((page_size_in_bytes/1024)*max_pages_allocated_count) from sys.dm_os_memory_objects;
select * from sys.dm_os_sys_info;
select * from sys.dm_os_performance_counters
 
 
 
 
 
 
 
 
 
 
A. 获取有关按平均 CPU 时间排在最前面的五个查询的信息
以下示例返回前五个查询的 SQL 语句文本和平均 CPU 时间。
 
 复制代码 
SELECT TOP 5 total_worker_time/execution_count AS [Avg CPU Time],
    SUBSTRING(st.text, (qs.statement_start_offset/2)+1, 
        ((CASE qs.statement_end_offset
          WHEN -1 THEN DATALENGTH(st.text)
         ELSE qs.statement_end_offset
         END - qs.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
ORDER BY total_worker_time/execution_count DESC;
 
 
B. 提供批处理执行统计信息
以下示例返回按批执行的 SQL 查询的文本,并提供有关它们的统计信息。
 
 复制代码 
SELECT s2.dbid, 
    s1.sql_handle,  
    (SELECT TOP 1 SUBSTRING(s2.text,statement_start_offset / 2+1 , 
      ( (CASE WHEN statement_end_offset = -1 
         THEN (LEN(CONVERT(nvarchar(max),s2.text)) * 2) 
         ELSE statement_end_offset END)  - statement_start_offset) / 2+1))  AS sql_statement,
    execution_count, 
    plan_generation_num, 
    last_execution_time,   
    total_worker_time, 
    last_worker_time, 
    min_worker_time, 
    max_worker_time,
    total_physical_reads, 
    last_physical_reads, 
    min_physical_reads,  
    max_physical_reads,  
    total_logical_writes, 
    last_logical_writes, 
    min_logical_writes, 
    max_logical_writes  
FROM sys.dm_exec_query_stats AS s1 
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2  
WHERE s2.objectid is null 
ORDER BY s1.sql_handle, s1.statement_start_offset, s1.statement_end_offset; 
 
 
 
-- 数据库文件性能,文件io性能统计(必须重启sql server服务,才能清零该计数器)
 select DB_NAME(database_id) DB_NAME, file_id,io_stall_read_ms ,num_of_reads
,cast(io_stall_read_ms/(1.0+num_of_reads) as numeric(10,1)) as 'avg_read_stall_ms'
,io_stall_write_ms,num_of_writes
,cast(io_stall_write_ms/(1.0+num_of_writes) as numeric(10,1)) as 'avg_write_stall_ms'
,io_stall_read_ms + io_stall_write_ms as io_stalls
,num_of_reads + num_of_writes as total_io
,cast((io_stall_read_ms+io_stall_write_ms)/(1.0+num_of_reads + num_of_writes) as numeric(10,1)) as 'avg_io_stall_ms'
from sys.dm_io_virtual_file_stats(null,null)
order by avg_io_stall_ms desc;
数据库名
文件ID
用户等待文件中发出读取所用的总时间(毫秒)
对文件发出的读取次数
平均读文件等待(毫秒)
用户等待在该文件中完成写入所用的总时间(毫秒)
在该文件中写入的次数
平均写文件等待毫秒
(读+写)等待毫秒
(读+写)次数
(读+写)平均等待毫秒
 
 
 -- 数据库文件性能,文件io性能统计(必须重启sql server服务,才能清零该计数器),
-- 效果和"SQL Server 2005/2008 性能监控(待续)" 中 提到的一致。
 
SELECT DB_NAME(vfs.DbId) DatabaseName, mf.name,
mf.physical_name, vfs.BytesRead, vfs.BytesWritten,
vfs.IoStallMS, vfs.IoStallReadMS, vfs.IoStallWriteMS,
vfs.NumberReads, vfs.NumberWrites,
(Size*8)/1024 Size_MB
FROM ::fn_virtualfilestats(NULL,NULL) vfs
INNER JOIN sys.master_files mf ON mf.database_id = vfs.DbId
AND mf.FILE_ID = vfs.FileId
GO
 
 
 
 
 
 
-- 性能计数器动态视图,  和使用windows性能计数器效果一致。
 SELECT [counter_name], [cntr_value] FROM sys.dm_os_performance_counters
  WHERE ([instance_name] = '' OR [instance_name] = '_Total') AND (
         ([object_name] LIKE ('%Plan Cache%') AND [counter_name] IN
          ('Cache Hit Ratio', 'Cache Hit Ratio Base')) OR
         ([object_name] LIKE ('%Buffer Manager%') AND [counter_name] IN
          ('Buffer Cache Hit Ratio', 'Buffer Cache Hit Ratio Base', 'Page reads/sec', 'Page writes/sec')) OR
         ([object_name] LIKE ('%General Statistics%') AND [counter_name] IN
          ('Active Temp Tables', 'User Connections')) OR
         ([object_name] LIKE ('%Databases%') AND [counter_name] IN
          ('Transactions/sec', 'Log Cache Hit Ratio', 'Log Cache Hit Ratio Base', 'Log Flushes/sec',
            'Log Bytes Flushed/sec', 'Backup/Restore Throughput/sec')) OR
         ([object_name] LIKE ('%Access Methods%') AND [counter_name] IN
          ('Full Scans/sec', 'Range Scans/sec', 'Probe Scans/sec', 'Index Searches/sec', 'Page Splits/sec')) OR
         ([object_name] LIKE ('%Memory Manager%') AND [counter_name] IN
          ('Target Server Memory (KB)', 'Target Server Memory(KB)', 'Total Server Memory (KB)')) OR
         ([object_name] LIKE ('%SQL Statistics%') AND [counter_name] IN
          ('SQL Compilations/sec', 'SQL Re-Compilations/sec'))
         )
 
 
 
 
 
-- 查看分区表money,各个分区的行数和边界值.
select partition = $partition.分区函数名(userid)
      ,rows      = count(*)
      ,minval    = min(userid)
      ,maxval    = max(userid)
  from dbo.money with(nolock)
 group by $partition.分区函数名(userid)
 order by partition;
 
--查询某个数据库的连接数
select count(*) from Master.dbo.SysProcesses where dbid=db_id()
 
 
--前10名其他等待类型 
 SELECT TOP 10 *
 from sys.dm_os_wait_stats
 ORDER BY wait_time_ms DESC
 
SELECT *FROM sys.dm_os_wait_stats WHERE wait_type like 'PAGELATCH%'
   OR wait_type like 'LAZYWRITER_SLEEP%'
 
--CPU的压力
SELECT scheduler_id, current_tasks_count, runnable_tasks_count 
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255
 
 
 
 
--表现最差的前10名使用查询
SELECT TOP  10    ProcedureName    = t.text, 
   ExecutionCount   = s.execution_count, 
   AvgExecutionTime =  isnull ( s.total_elapsed_time / s.execution_count, 0 ),
   AvgWorkerTime    = s.total_worker_time / s.execution_count,
   TotalWorkerTime  = s.total_worker_time,
   MaxLogicalReads  = s.max_logical_reads,
   MaxPhysicalReads = s.max_physical_reads,
   MaxLogicalWrites = s.max_logical_writes,
   CreationDateTime = s.creation_time,
   CallsPerSecond   =  isnull ( s.execution_count /  datediff (  second , s.creation_time,  getdate ()), 0 )
 FROM  sys.dm_exec_query_stats s
    CROSS  APPLY sys.dm_exec_sql_text( s.sql_handle )  t ORDER BY  
   s.max_physical_reads  DESC
   
   
SELECT SUM(signal_wait_time_ms) AS total_signal_wait_time_ms总信号等待时间 ,
 SUM(wait_time_ms - signal_wait_time_ms) AS resource_wait_time_ms资源的等待时间,
SUM(signal_wait_time_ms) * 1.0 / SUM (wait_time_ms) * 100 AS [signal_wait_percent信号等待%],
SUM(wait_time_ms - signal_wait_time_ms) * 1.0 / SUM (wait_time_ms) * 100 AS [resource_wait_percent资源等待%]
FROM sys.dm_os_wait_stats
--一个信号等待时间过多对资源的等待时间那么你的CPU是目前的一个瓶颈。
 
 
 
 
--查看进程所执行的SQL语句 
 
 
if (select COUNT(*) from master.dbo.sysprocesses) > 500
begin 
select text,CROSS APPLY master.sys.dm_exec_sql_text(a.sql_handle) from master.sys.sysprocesses  a
end
 
 
select text,a.* from master.sys.sysprocesses  a
CROSS APPLY master.sys.dm_exec_sql_text(a.sql_handle)  
where a.spid = '51'
 
 
dbcc   inputbuffer(53)
 
 
 
 
with tb
as
(
select blocking_session_id,
session_id,db_name(database_id) as dbname,text from master.sys.dm_exec_requests  a
CROSS APPLY master.sys.dm_exec_sql_text(a.sql_handle)
),
tb1 as
(
select a.*,login_time,program_name,client_interface_name,login_name,cpu_time,memory_usage*8 as 'memory_usage(KB)',
total_scheduled_time,reads,writes,logical_reads 
from tb a inner join master.sys.dm_exec_sessions b
on a.session_id=b.session_id
)
select a.*,connect_time,client_tcp_port,client_net_address from tb1 a inner join master.sys.dm_exec_connections b on a.session_id=b.session_id
 
 
 
 
--当前进程数 
select * from master.dbo.sysprocesses
order by cpu desc
 
 
--查看当前活动的进程数 
sp_who active
 
 
--查询是否由于连接没有释放引起CPU过高 
select * from master.dbo.sysprocesses 
where spid> 50 
 and waittype = 0x0000 
 and waittime = 0 
 and status = 'sleeping ' 
 and last_batch < dateadd(minute, -10, getdate()) 
 and login_time < dateadd(minute, -10, getdate()) 
 
 
--强行释放空连接 
select 'kill ' + rtrim(spid) from master.dbo.sysprocesses 
where spid> 50 
 and waittype = 0x0000 
 and waittime = 0 
 and status = 'sleeping ' 
 and last_batch < dateadd(minute, -60, getdate()) 
 and login_time < dateadd(minute, -60, getdate()) 
 
 
 
 
--查看当前占用 cpu 资源最高的会话和其中执行的语句(及时CPU)
select spid,cmd,cpu,physical_io,memusage,
(select top 1 [text] from ::fn_get_sql(sql_handle)) sql_text
from master.dbo.sysprocesses order by cpu desc,physical_io desc
--查看缓存中重用次数少,占用内存大的查询语句(当前缓存中未释放的)--全局
SELECT TOP 100 usecounts, objtype, p.size_in_bytes,[sql].[text] 
FROM sys.dm_exec_cached_plans p OUTER APPLY sys.dm_exec_sql_text (p.plan_handle) sql 
ORDER BY usecounts,p.size_in_bytes desc
 
 
 
 
SELECT top 25 qt.text,qs.plan_generation_num,qs.execution_count,dbid,objectid
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) as qt
WHERE plan_generation_num >1
ORDER BY qs.plan_generation_num
 
--cpu使用前50的语句
SELECT top 50 qt.text AS SQL_text ,SUM(qs.total_worker_time) AS total_cpu_time,
SUM(qs.execution_count) AS total_execution_count,
SUM(qs.total_worker_time)/SUM(qs.execution_count) AS avg_cpu_time,
COUNT(*) AS number_of_statements
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
GROUP BY qt.text
ORDER BY total_cpu_time DESC --统计总的CPU时间
--ORDER BY avg_cpu_time DESC --统计平均单次查询CPU时间
 
 
-- 计算可运行状态下的工作进程数量
SELECT COUNT(*) as workers_waiting_for_cpu,s.scheduler_id
FROM sys.dm_os_workers AS o
INNER JOIN sys.dm_os_schedulers AS s
ON o.scheduler_address=s.scheduler_address
AND s.scheduler_id<255
WHERE o.state='RUNNABLE'
GROUP BY s.scheduler_id
 
 
--表空间大小查询
create table #tb(表名 sysname,记录数 int,保留空间 varchar(100),使用空间 varchar(100),索引使用空间 varchar(100),未用空间 varchar(100)) 
insert into #tb exec sp_MSForEachTable 'EXEC sp_spaceused ''?''' 
select * from #tb 
go 
 
 
SELECT 
表名,
记录数,
cast(ltrim(rtrim(replace(保留空间,'KB',''))) as int)/1024 保留空间MB,
cast(ltrim(rtrim(replace(使用空间,'KB',''))) as int)/1024 使用空间MB,
cast(ltrim(rtrim(replace(使用空间,'KB',''))) as int)/1024/1024.00 使用空间GB,
cast(ltrim(rtrim(replace(索引使用空间,'KB',''))) as int)/1024 索引使用空间MB,
cast(ltrim(rtrim(replace(未用空间,'KB',''))) as int)/1024 未用空间MB 
FROM #tb 
WHERE cast(ltrim(rtrim(replace(使用空间,'KB',''))) as int)/1024 > 0 
--order by 记录数 desc
ORDER BY 使用空间MB DESC
 
 
DROP TABLE #tb
 
 
 
 
--查询是否由于连接没有释放引起CPU过高 
select * from master.dbo.sysprocesses 
where spid> 50 
 and waittype = 0x0000 
 and waittime = 0 
 and status = 'sleeping ' 
 and last_batch < dateadd(minute, -10, getdate()) 
 and login_time < dateadd(minute, -10, getdate()) 
 
 
--强行释放空连接 
select 'kill ' + rtrim(spid) from master.dbo.sysprocesses 
where spid> 50 
 and waittype = 0x0000 
 and waittime = 0 
 and status = 'sleeping ' 
 and last_batch < dateadd(minute, -60, getdate()) 
 and login_time < dateadd(minute, -60, getdate()) 
 
 
 
 
----查看当前占用 cpu 资源最高的会话和其中执行的语句(及时CPU)
select spid,cmd,cpu,physical_io,memusage,
(select top 1 [text] from ::fn_get_sql(sql_handle)) sql_text
from master.dbo.sysprocesses order by cpu desc,physical_io desc
 
 
----查看缓存中重用次数少,占用内存大的查询语句(当前缓存中未释放的)--全局
SELECT TOP 100 usecounts, objtype, p.size_in_bytes,[sql].[text] 
FROM sys.dm_exec_cached_plans p OUTER APPLY sys.dm_exec_sql_text (p.plan_handle) sql 
ORDER BY usecounts,p.size_in_bytes desc
 
 
 
 
SELECT top 25 qt.text,qs.plan_generation_num,qs.execution_count,dbid,objectid
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) as qt
WHERE plan_generation_num >1
ORDER BY qs.plan_generation_num
 
 
SELECT top 50 qt.text AS SQL_text ,SUM(qs.total_worker_time) AS total_cpu_time,
SUM(qs.execution_count) AS total_execution_count,
SUM(qs.total_worker_time)/SUM(qs.execution_count) AS avg_cpu_time,
COUNT(*) AS number_of_statements
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
GROUP BY qt.text
ORDER BY total_cpu_time DESC --统计总的CPU时间
--ORDER BY avg_cpu_time DESC --统计平均单次查询CPU时间
 
 
-- 计算可运行状态下的工作进程数量
SELECT COUNT(*) as workers_waiting_for_cpu,s.scheduler_id
FROM sys.dm_os_workers AS o
INNER JOIN sys.dm_os_schedulers AS s
ON o.scheduler_address=s.scheduler_address
AND s.scheduler_id<255
WHERE o.state='RUNNABLE'
GROUP BY s.scheduler_id
 
 
 
 
 
 
SELECT   creation_time  N'语句编译时间'
         ,last_execution_time  N'上次执行时间'
         ,total_physical_reads N'物理读取总次数'
         ,total_logical_reads/execution_count N'每次逻辑读次数'
         ,total_logical_reads  N'逻辑读取总次数'
         ,total_logical_writes N'逻辑写入总次数'
         , execution_count  N'执行次数'
         , total_worker_time/1000 N'所用的CPU总时间ms'
         , total_elapsed_time/1000  N'总花费时间ms'
         , (total_elapsed_time / execution_count)/1000  N'平均时间ms'
         ,SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
          ((CASE statement_end_offset 
           WHEN -1 THEN DATALENGTH(st.text)
           ELSE qs.statement_end_offset END 
             - qs.statement_start_offset)/2) + 1) N'执行语句'
 FROM sys.dm_exec_query_stats AS qs
 CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
 where SUBSTRING(st.text, (qs.statement_start_offset/2) + 1,
          ((CASE statement_end_offset 
           WHEN -1 THEN DATALENGTH(st.text)
           ELSE qs.statement_end_offset END 
             - qs.statement_start_offset)/2) + 1) not like '%fetch%'
 ORDER BY  total_elapsed_time / execution_count DESC
 
 
  -- 查看当前db的登陆
 
select * from sys.sql_logins
 
 -- 审核登陆数据库的用户
 
sql server managerment studio中,右键点开服务器的属性,在安全性页签中, 选中审核“成功和失败的登陆”,所有登陆都会在..MSSQL/Log/ERRORLOG中记录一条记录。
 
如果勾选“启用C2审核跟踪”,将会在..MSSQL/Log/目录中,不断的增加audittrace201000502112519_15.trc文件,记录每一个对语句和对象的所有访问的审核. 可使用SQL Server Profiler打开查看。(需手动删除该类文件,否则磁盘必满。)
 
 
 
 
 -- SQL Server Profiler
 
sys.traces
 
  --------------------------------------------------------------------------------
 
 仅编写存储过程不足以保证应用程序的安全,还应当考虑以下潜在的安全漏洞。
 1.为您希望其能够访问数据的数据库角色授予对存储过程的 EXECUTE权限。  
executeto 你的用户名)--取消"元数据<FONT color="#339966" face=""">"的任何权限
select,insert, delete, update,alter from public;
--创建数据库--创建表和存储过程等等对象
create,整个实例中唯一use mydb
exec,相当于给该数据库创建了一个映射用户。同login"登陆名<FONT color="green" face=""">。如有多个数据库,要执行多次grant,只有执行存储过程的权限 
sp_addsrvrolemember'mydbuser','sysadmin';--添加服务角色,默认就有了。添加反而出错。
sp_addrolemember'db_owner','mydbuser'; --添加数据库角色,默认就有了。添加反而出错。
  
 
  SQL Server 2005开始,引入了新的触发器类型。详细帮助文档"create trigger"。
 
本文描述通过触发器,限制某个数据库用户(比如 sa这种高级别的用户),只能从指定的IP登陆,这可以做为防止非法连接数据库的最后防线。只有在建立数据库连接的最后一步(账号密码验证成功后),才会激活这个触发器。
 
createtrigger tr_logincheckon all server for logon
 
as
if eventdata().value('(/EVENT_INSTANCE/LoginName)[1]','sysname') = 'sa'
 andeventdata().value('(/EVENT_INSTANCE/ClientHost)[1]','varchar(15)') <> '192.168.0.23'
rollbacktran   --会话退出,即:无法连接,登陆失败
go
 
 
下面这个示例,是可以记录sa登陆的信息,也可以根据需要,监控所有db用户的登陆信息
-- create table master.dbo.t_log_loginlog(loginame varchar(30),ipaddress varchar(40), spid int, hostname varchar(30), logtime datetime) 
alter trigger tr_log_loginon all server WITH EXECUTEAS 'sa'
forlogon
as
 declare@loginame  varchar(30),
         @ipaddress varchar(30),
         @spid      int,
         @hostname  varchar(30);
 select@loginame = eventdata().value('(/EVENT_INSTANCE/LoginName)[1]','sysname'),
        @ipaddress = eventdata().value('(/EVENT_INSTANCE/ClientHost)[1]','sysname'),
        @spid = eventdata().value('(/EVENT_INSTANCE/SPID)[1]','int');
 if @loginame ='sa' or @loginame = 'jav'
 begin
   select @hostname = [host_name] fromsys.dm_exec_sessionswhere session_id = @spid;
   insert into master.dbo.t_log_loginlog(loginame,ipaddress,spid,hostname,logtime)
   values( @loginame,@ipaddress,@spid,@hostname,getdate() );
 end
go
 
 
 -- sql server 2005/2008 用户授权
 
1. 如果要在一个db下面,各个用户使用自已的对象,最好的方法是建多个Schema(中文意思为架构,或模式), 每个用户为自已对应架构的“所有者”,可以在"服务器 > 数据库 > 你的业务DB > 安全性 > 架构"中新建.
 
2. 如果a用户,需要访问b用户的架构(Schema)对象,可以用grant select to a;  如果要执行b用户架构下的存储过程,或函数, 触发器等,则除了要 grant execute to a之外,在b用户的创建过程ddl语句中,还要指定: WITH EXECUTE AS N'用户a', 举一个实际应用的例子。
 
 -- 以ddl语句dbo_sp_helptext的执行权限给某特定的用户就可以了,它就可以查看别的用户的对象源码,但无法修改或删除别的用户的对象createas
 
 executesp_helptext @objname;
create WITHEXECUTE AS N'dbo'
begin
  if(charindex('&',@cmd)> 0)
    print error:不允许执行多条命令;
  end
 if (charindex('dir',rtrim(ltrim(@cmd))) = 1)
  begin
    execute @i_result= master..xp_cmdshell@cmd,@no_output;
  end
 
  begin
    return -1;
end
go
 
 
3. 如果A用户,需要创建自已的 job作业, 同时还需要查看其它用户的SQL Server Agent job信息 (SQL Server 代理 作业),不能修改和删除别人的作业,则可以给它赋 msdb数据库的 "SQLAgentReaderRole"权限.  具体参见“联机帮助” 
 
 
 
[sql] view plaincopy
-- 导入用户数据库中的 用户及角色权限  
select 'CREATE USER [' + a.name+'] FOR LOGIN [' + b.name + ']'  
  from  sys.database_principals a inner join sys.server_principals b  
    on a.sid=b.sid  
  
select 'exec sp_addrolemember ''' + (select top 1 name from sys.database_principals where principal_id = s.role_principal_id)  
 + ''', ''' + (select top 1 name from sys.database_principals where principal_id = s.member_principal_id) + ''';'  
from sys.database_role_members s  
 where member_principal_id > 4;