Sql server 如何向SQL连接字符串添加自定义属性?

Sql server 如何向SQL连接字符串添加自定义属性?,sql-server,function,tsql,extended-properties,Sql Server,Function,Tsql,Extended Properties,我想在SqlServer连接字符串中添加一些自定义属性,如下所示: Integrated Security=SSPI;Extended Properties="SomeAttr=SomeValue";Persist Security Info=False;Initial Catalog=DB;Data Source=SERVER 然后在sql中获取该属性。例如选择一些函数('SomeAttr')您可以在连接字符串中使用WSID和APP关键字。您可以使用HOST_NAME()和APP_NAME(

我想在SqlServer连接字符串中添加一些自定义属性,如下所示:

Integrated Security=SSPI;Extended Properties="SomeAttr=SomeValue";Persist Security Info=False;Initial Catalog=DB;Data Source=SERVER

然后在sql中获取该属性。例如
选择一些函数('SomeAttr')

您可以在连接字符串中使用WSID和APP关键字。您可以使用HOST_NAME()和APP_NAME()函数读取这些值。有关详细信息,请参阅。

没有通用方法通过客户端API传递自定义连接字符串属性并使用T-SQL进行检索。不过,你有很多选择。下面是一些例子

方法1:使用连接字符串中的应用程序名称关键字传递最多128个字符,并使用APP_Name()T-SQL函数进行检索:

Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DB;Data Source=SERVER;Application Name="SomeAttr=SomeValue"

SELECT APP_NAME();
DECLARE @context_info varbinary(128) = CAST('SomeAttr=SomeValue' AS varbinary(128));
SET CONTEXT_INFO @context_info;

SELECT CAST(CONTEXT_INFO() AS varchar(128));
请注意,这被限制为128个字符,您将需要解析有效负载。此外,由于ADO.NET为每个不同的连接字符串创建了一个单独的连接池,所以考虑到将很少或根本没有数据库连接池。 方法2:连接后执行设置的上下文信息,并分配最多128个字节,可使用上下文信息)T-SQL函数检索:

Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DB;Data Source=SERVER;Application Name="SomeAttr=SomeValue"

SELECT APP_NAME();
DECLARE @context_info varbinary(128) = CAST('SomeAttr=SomeValue' AS varbinary(128));
SET CONTEXT_INFO @context_info;

SELECT CAST(CONTEXT_INFO() AS varchar(128));
请注意,这被限制为128字节,您将需要解析有效负载

方法3:在连接后创建会话级临时表,并插入可通过SELECT查询检索的名称/值对:

CREATE TABLE #CustomSessionAttributes(
      AttributeName varchar(128) PRIMARY KEY
    , AttributeValue varchar(1000));
INSERT INTO #CustomSessionAttributes VALUES('SomeAttr', 'SomeValue');

SELECT AttributeValue 
FROM #CustomSessionAttributes 
WHERE AttributeName = 'SomeAttr';
CREATE TABLE dbo.CustomSessionAttributes(
      SessionID smallint
    , AttributeName varchar(128)
    , AttributeValue varchar(1000)
    , CONSTRAINT PK_CustomSessionAttributes PRIMARY KEY (SessionID, AttributeName)
    );
--clean up previous session
DELETE FROM dbo.CustomSessionAttributes WHERE SessionID = @@SPID; 
--insert values for this session
INSERT INTO dbo.CustomSessionAttributes VALUES(@@SPID, 'SomeAttr', 'SomeValue');

--retreive attribute value
SELECT AttributeValue 
FROM dbo.CustomSessionAttributes 
WHERE
    SessionID = @@SPID 
    AND AttributeName = 'SomeAttr';
请注意,您可以根据需要增加属性值的大小和类型,而无需解析

方法4:创建一个由会话id和属性名称键入的永久表,在连接后插入可通过SELECT查询检索的名称/值对:

CREATE TABLE #CustomSessionAttributes(
      AttributeName varchar(128) PRIMARY KEY
    , AttributeValue varchar(1000));
INSERT INTO #CustomSessionAttributes VALUES('SomeAttr', 'SomeValue');

SELECT AttributeValue 
FROM #CustomSessionAttributes 
WHERE AttributeName = 'SomeAttr';
CREATE TABLE dbo.CustomSessionAttributes(
      SessionID smallint
    , AttributeName varchar(128)
    , AttributeValue varchar(1000)
    , CONSTRAINT PK_CustomSessionAttributes PRIMARY KEY (SessionID, AttributeName)
    );
--clean up previous session
DELETE FROM dbo.CustomSessionAttributes WHERE SessionID = @@SPID; 
--insert values for this session
INSERT INTO dbo.CustomSessionAttributes VALUES(@@SPID, 'SomeAttr', 'SomeValue');

--retreive attribute value
SELECT AttributeValue 
FROM dbo.CustomSessionAttributes 
WHERE
    SessionID = @@SPID 
    AND AttributeName = 'SomeAttr';
请注意,您可以根据需要增加属性值的大小和类型,而无需解析

编辑:

方法5:使用存储过程存储会话范围的名称/值对,并使用函数检索值。SQL Server 2016和Azure SQL数据库中引入了此功能

EXEC sp_set_session_context 'SomeAttr', 'SomeValue';
SELECT SESSION_CONTEXT(N'SomeAttr');

我需要它来启用每个应用程序实例的会话,我认为只有方法1对我有效,因为我在每个连接上发送数据,我想其他方法在新连接上不会有以前的数据。@Hove,你是说你需要来自同一应用程序实例的不同连接的相同信息吗?也许方法4的一个变体(使用应用程序实例标识符而不是SessionID)适合您。事实上,是的,我打算将一些数据写入表中,并将其绑定到连接字符串中的应用程序名称(例如GUID),因此,方法1和4的组合以及我将在应用程序启动时写入该表,并在该实例运行时在每次数据更改时更新该表。我这样做是为了不必向需要的每个进程或查询发送相同的数据。@ Hove,考虑连接池差异对连接池差异的影响。不过,对于小型应用程序来说,这可能不是问题,因为每个应用程序实例(Windows中exe文件的开头)都有一个GUID(应用程序名称),每个应用程序实例的“应用程序名称”都是固定的。e、 g.在web应用程序中,您只有一个“实例”,您只能使用一个登录登录,而不能使用另一个选项卡中的另一个登录,使用桌面应用程序,我可以允许每个登录都有多个实例和设置。这对多任务处理很有好处,尤其是当你在一个任务中有长时间运行的任务,而你有空闲时间在另一个任务中用不同的设置做其他事情时。