如何设置多个批次中可用的会话变量?

Mic*_*elD 5 sql t-sql sql-server

我有一个大型数据库脚本将同一结构的多个数据库迁移到一个目标数据库.此目标数据库更通用,因此可以存储来自不同源数据库的数据.我使用变量来跟踪当前正在迁移的实体,因此我知道要在目标表中插入什么ID.

此时迁移性能非常糟糕.为了能够更好地分析脚本,我想通过在每次表迁移后放置'go'来拆分脚本,但这会破坏变量.有没有办法声明一个可供整个连接/会话访问的变量?就像temp #table一样?

Dev*_*art 9

查询:

DECLARE
      @UserID TINYINT = 1
    , @LocaleID INT = 123456789
    , @ApplicationID BIGINT = 123456789123456789
    , @UserName VARCHAR(10) = 'User1'
    , @context VARBINARY(128)

SELECT @context = 
    CAST(@UserID AS BINARY(1)) + 
    CAST(@LocaleID AS BINARY(4)) + 
    CAST(@ApplicationID AS BINARY(8)) +
    CAST(@UserName AS BINARY(10))

SET CONTEXT_INFO @context

GO

SELECT 
      UserID = CAST(SUBSTRING(ci, 1, 1) AS TINYINT)
    , LocaleID = CAST(SUBSTRING(ci, 2, 4) AS INT)
    , ApplicationID = CAST(SUBSTRING(ci, 6, 8) AS BIGINT)
    , UserName = CAST(SUBSTRING(ci, 14, 10) AS VARCHAR)
FROM (SELECT ci = CONTEXT_INFO()) t
Run Code Online (Sandbox Code Playgroud)

结果:

UserID      LocaleID    ApplicationID      UserName
----------- ----------- ------------------ ------------------------------
1           123456789   123456789123456789 User1     
Run Code Online (Sandbox Code Playgroud)

附加信息:

MSDN - CONTEXT_INFO


got*_*tqn 6

您SQL Server 2016可以使用sp_set_session_context:

EXEC [sys].[sp_set_session_context] @key = 'SecurityObjectUserID'
                                   ,@value = @SecurityObjectUserID
                                   ,@read_only = 1;  
Run Code Online (Sandbox Code Playgroud)

设置一个变量,并使用以下命令读取它:

SELECT @SecurityObjectUserID = CONVERT(BIGINT,SESSION_CONTEXT(N'SecurityObjectUserID'));
Run Code Online (Sandbox Code Playgroud)

注意,我们可以将变量标记为read_only。这样其他例程就无法改变它了。

  • 有趣的事实(仅在 SQL Server 2016 上测试):`SESSION_CONTEXT()` 不区分大小写_除了键的最后一个字符_。例如,如果您有一个由“toto”键控的值,则可以通过该键的所有变体(但以大写“O”结尾的变体)检索它。 (4认同)