SQL Server 得到SPID,唯一的sessionID

本文介绍如何在SQL Server中获取和利用会话ID(session ID)来追踪特定用户的活动和执行的SQL语句。文章提供了获取当前会话ID的方法,并演示了如何使用动态管理视图和函数来查看最近执行的SQL语句。

     像.net中的session一样,如果能知道了数据库中的sessionID,那所有的操作都能知道了,因为有了这个唯一的身份识别的标识。

     可以做的事情有很多,如:当前哪个用户在做什么操作,在执行什么sql, 又如一个比较大的逻辑中要分别执行很多存储过程,

    在执行这些存储过程的过程当中,你想知道当前执行的进度,SQLServer正在执行哪个段sql语句,那么通过sessionID是很容易

   就得到这些信息的。

  SQL Server 得到SPID,唯一的sessionID:

    SELECT @@SPID

    以前我一直不知道,最近又装了SQLServer2014,发现每开一个Query 界面就有一个ID出来。我就特别想知道怎么取sessionID.

下面的存储过程是用来查看哪些sessionID正在执行什么操作。

create PROC [dbo].[dba_WhatSQLIsExecuting]
AS

BEGIN
-- Do not lock anything, and do not get held up by any locks.
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


-- What SQL Statements Are Currently Running?
SELECT [Spid] = session_Id
, ecid
, [Database] = DB_NAME(sp.dbid)
, [User] = nt_username
, [Status] = er.status
, [Wait] = wait_type
, [Individual Query] = SUBSTRING (qt.text,
er.statement_start_offset/2,
(CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE er.statement_end_offset END -
er.statement_start_offset)/2)
,[Parent Query] = qt.text
, Program = program_name
, Hostname
, nt_domain
, start_time
FROM sys.dm_exec_requests er
INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle)as qt
WHERE session_Id > 50 -- Ignore system spids.
AND session_Id NOT IN (@@SPID) -- Ignore this current statement.
--and DB_NAME(sp.dbid)='RangeCheckTool'
ORDER BY 1, 2
END

    还可以参考下面的文章:

   http://www.mssqltips.com/sqlservertip/1799/identify-last-statement-run-for-a-specific-sql-server-session/

   

Identify last statement run for a specific SQL Server session

Problem
I was reading a recent blog post from Pinal Dave, SQL Server MVP, regarding returning information on the latest query executed for a given session.  He offered up a couple options to return the last query statement executed, settling upon querying the sys.sysprocesses system compatibility view, but another way that this can be done is through the Dynamic Management Views and Functions.  The process for doing so is quite straight-forward and works in all versions of Microsoft SQL Server since DMOs (dynamic management objects) were integrated into SQL Server. 

Solution
Before proceeding we should take a second to explain what a session is.  In Microsoft SQL Server, a session is synonymous with a user process.  Previous to SQL 2005 sessions were referred to - and identified solely - as SPIDs (short for session id).  A SPID uniquely identifies a session and a SPID is unique across the SQL Server instance.  In an attempt to conform SQL Server object identifiers to be more user-friendly and to standardize a naming convention across all system objects, sessions are now identified across the DMO and system catalog views as session_id.  You'll see similar changes between previous versions of SQL Server and current versions where all object identifiers are concerned.

You can use the @@spid() system function to return the session_id of the current session as follows:

SELECT @@SPID

For my test I get session_id = 52.

So, now that we've identified what session_id uniquely identifies the session I'm using during this demonstration, I'll do a simple query against the Northwind database.

SELECT C.[CompanyName]  
FROM [Northwind].dbo.[Customers] C  
WHERE C.[City] 'Berlin'  
ORDER BY [C].[CompanyName]

At this point I'll now open up a separate query window in SQL Server Management Studio.  If I now execute the first query above you'll see that this registers as a new session on the SQL Server instance:

SELECT @@SPID

For my test I get session_id = 53

Now I can utilize the sys.dm_exec_connections Dynamic Management View, in conjunction with thesys.dm_exec_sql_text Dynamic Management Function to return the last query statement executed against the SQL Server instance on a selected session.  In all truth, you can return the last query executed on all sessions, but for the sake of this discussion we're limiting the results based upon the session_id (52) we've identified above.  I'll present the query, then we can examine in detail what it provides for us.

SELECT DEST.TEXT  
FROM 
sys.[dm_exec_connections] SDEC 
 CROSS APPLY sys.[dm_exec_sql_text](SDEC.[most_recent_sql_handle]AS DEST 
WHERE SDEC.[most_recent_session_id] 52 

The output for this query shows the statement that was run for session_id 52.

So what just happened?  Simply-put, we returned the results from the sys.dm_exec_connections DMV, limiting the results by the session_id (52) we identified above.  We, submitted the value contained in the most_recent_sql_handle column of this DMV to the sys.dm_exec_sql_text Dynamic Management Function.  That function then returned as text, the value of the sql_handle we passed to it. 

So what is a sql_handle?  Think of a sql_handle as a unique identifier for a query that is unique across the entire SQL Server instance.  Just as a session_id uniquely identifies a session, so does a sql_handle identify a query.  The actual value of the sql_handle column is very cryptic.  The value for the most_recent_sql_handle in this example is shown below:

SELECT SDEC.[most_recent_sql_handle]DEST.[text]  
FROM sys.[dm_exec_connections] SDEC 
 CROSS APPLY sys.[dm_exec_sql_text](SDEC.[most_recent_sql_handle]AS DEST 
WHERE SDEC.[most_recent_session_id] 52 

Here we can see the value of the sql_handle and the text translation.

The handle itself does not really do much for us without the function call that rationalizes it into the original query text.  As you can see though, this very simple query does provide us with yet another option for returning information on what users are (or have been) doing on the SQL Server instances we support.

Next Steps

  • The Dynamic Management Objects have so much to offer the DBA.  Check out other tips on DMOs from MSSQLTips.com.
  • Read more tips by the author here.
  • Still interested in information on sysprocesses, whether as a system table (pre-SQL 2005) or system view?  Here are some tips that meet your needs.

 

<think>我们正在讨论SQL Server中的session_id。根据之前的对话,用户询问了关于session_id的含义。在之前的问题中,用户提到了查询当前数据库正在执行的语句和作业,其中使用了session_id。现在,用户直接询问session_id的含义。 根据引用[4]:session是在服务器端程序运行的过程中创建的,不同的语言实现的应用程序创建session的方法不同。但在SQL Server上下文中,session_id指的是什么? 在SQL Server中,session_id(有时也称为SPID)是服务器分配给每个连接的唯一标识符。当客户端应用程序连接到SQL Server时,服务器会为该连接创建一个会话(session),并分配一个唯一的session_id。这个session_id在整个服务器实例中是唯一的。 我们可以从以下几个方面来详细解释: 1. **连接与会话**:每当一个用户或应用程序连接到SQL Server时,就会创建一个会话。每个会话都有一个唯一的session_id(即SPID)。这个ID在SQL Server实例中唯一标识该连接。 2. **系统视图与函数**:在动态管理视图(DMV)中,如`sys.dm_exec_requests`、`sys.dm_exec_sessions`等,都可以看到session_id。在之前的查询中,我们使用`session_id`来关联不同的系统视图。 3. **与进程的关系**:在SQL Server中,每个会话可能对应一个或多个任务(tasks),这些任务由工作线程(workers)执行。但通常,一个会话至少有一个任务(即主查询)。 4. **系统进程与用户进程**:session_id小于等于50的通常是系统进程(内部进程),而大于50的是用户进程。因此,在查询用户会话时,我们通常过滤掉session_id<=50的进程。 5. **会话上下文**:引用[1]提到了SESSION_CONTEXT()函数,它允许在会话中存储键值对。这说明每个会话都有自己的上下文信息,这些信息与session_id相关联。 6. **锁和阻塞**:引用[2]和[5]提到了表锁和阻塞问题。在诊断锁和阻塞时,我们通常需要查看是哪个session_id持有锁,哪个session_id在等待锁。 7. **活动监控**:如引用[5]中提到的sp_whoisactive工具,它使用session_id来报告每个连接的活动情况。 因此,我们可以这样总结: **session_id** 是SQL Server中用于唯一标识客户端连接的整数值。通过该标识符,我们可以: - 查看连接执行的查询 - 诊断性能问题(如阻塞、死锁) - 管理连接(例如,使用KILL命令终止会话) - 查看连接的相关信息(如登录名、数据库、应用程序名称等) 在系统视图`sys.dm_exec_sessions`中,我们可以查询到每个会话的详细信息。 下面是一个查询会话信息的示例: ```sql SELECT session_id, login_time, host_name, program_name, login_name, status FROM sys.dm_exec_sessions WHERE session_id > 50; -- 过滤系统会话 ``` 注意:在SQL Server的早期版本中,session_id也被称为SPIDServer Process ID),在视图`sys.sysprocesses`中仍使用spid列名。 因此,在回答用户问题时,我们应清晰地解释session_id的概念、作用以及它在SQL Server管理中的重要性。 最后,按照要求,我们需要生成相关问题。 </think> ### SQL Server 中 `session_id` 的含义详解 `session_id`(会话 ID)是 SQL Server 为每个客户端连接分配的唯一标识符,用于在服务器实例中跟踪和管理连接状态。其核心作用类似于进程 ID,在 SQL Server 中通常被称为 **SPID** (Server Process ID)[^5]。 #### 一、`session_id` 的核心特性 1. **唯一标识连接** 每当客户端(应用程序、用户工具等)连接到 SQL Server 实例时,系统自动分配一个整数值作为 `session_id`。例如: - 系统进程:`session_id ≤ 50`(如后台任务) - 用户连接:`session_id > 50`(如用户查询、作业) 2. **会话上下文载体** 通过 `SESSION_CONTEXT()` 函数存储会话级键值对数据(如用户自定义参数),这些数据仅在当前 `session_id` 对应的连接中有效[^1]。示例: ```sql -- 设置会话上下文 EXEC sp_set_session_context @key = 'UserID', @value = 1001; -- 获取数据(仅当前session_id可见) SELECT SESSION_CONTEXT(N'UserID') AS CurrentUser; ``` 3. **资源关联纽带** `session_id` 关联连接的各类资源: - 执行中的查询(通过 `sys.dm_exec_requests`) - 锁持有情况(通过 `sys.dm_tran_locks`) - 临时对象(如 `tempdb` 中的临时表) #### 二、`session_id` 的应用场景 1. **监控活动连接** 查看所有活动会话并识别资源消耗: ```sql SELECT session_id, login_time, host_name, program_name, status FROM sys.dm_exec_sessions WHERE is_user_process = 1; ``` 2. **诊断锁与阻塞** 识别引发阻塞的会话[^2]: ```sql -- 查找阻塞链源头 SELECT blocking_session_id, session_id AS waiting_session, wait_type FROM sys.dm_os_waiting_tasks WHERE blocking_session_id > 0; ``` 3. **终止问题会话** 强制结束异常连接(如死锁、长时间阻塞): ```sql KILL 62; -- 终止session_id=62的连接 ``` #### 三、`session_id` 与系统视图的关系 | 动态管理视图 (DMV) | 作用描述 | 关键字段 | [^4] |----------------------------|-----------------------------------|------------------------| | `sys.dm_exec_sessions` | 查看所有会话基础信息 | `session_id`, `status` | | `sys.dm_exec_requests` | 分析活动请求(如运行中的查询) | `session_id`, `sql_handle` | | `sys.dm_tran_locks` | 检查会话持有的锁 | `request_session_id` | > 💡 示例:查询会话 62 正在执行的 SQL 语句 > ```sql > SELECT TEXT > FROM sys.dm_exec_sql_text( > (SELECT sql_handle FROM sys.dm_exec_requests WHERE session_id = 62) > ); > ``` #### 四、`session_id` 的生命周期 1. **创建**:客户端通过身份验证建立连接时生成 2. **维持**:连接保持期间持续存在(即使空闲) 3. **销毁**:连接断开或执行 `KILL` 命令后释放资源 > ⚠️ 注意:重启 SQL Server 服务会重置所有 `session_id`,但不影响永久性配置。 --- ### 总结 `session_id` 是 SQL Server 连接管理的核心标识符,用于: - 区分不同客户端连接 - 关联会话级资源(锁、查询、上下文数据) - 实现性能监控与故障诊断 通过动态管理视图和系统函数,可高效利用 `session_id` 优化数据库运维[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值