如何在sql server 2008中创建一个全局变量

时间:2011-12-02 12:41:55

标签: sql-server-2008 tsql

我有一个视图,它返回用户项目以及他们的Windows登录。数据的一个例子如下: -

project   | Login
------------------
project 1 | richab
project 2 | stevej

我需要将域附加到登录名。我可以把它放在代码中,但我不想在我创建的每个视图中执行此操作拉动用户登录。

我可以创建一个可以在视图代码中引用的全局变量。我怎么能做到这一点?什么是最好的做法?

3 个答案:

答案 0 :(得分:3)

我不知道SQL Server是否具有全局变量,但您可以使用用户定义的函数,如下所示:

CREATE FUNCTION dbo.fn_GetDomainName()
RETURNS STRING
AS
BEGIN
    RETURN 'domain_name\\'
END

并在视图中的相应位置执行SELECT dbo.fn_GetDomainName() + Login FROM table WHERE ...

答案 1 :(得分:2)

SQL Server中没有全局变量。

你不能只做:

DECLARE @@GlobalVar int

您可以使用CONTEXT_INFO伪造它,但要使用会超出会话或重新启动的内容,您需要执行以下操作:

USE master
IF OBJECT_ID('dbo.sp_GlobalVariables') IS NOT NULL
    DROP TABLE dbo.sp_GlobalVariables
GO
CREATE TABLE dbo.sp_GlobalVariables
(
    varName NVARCHAR(100) COLLATE Latin1_General_CS_AI,
    varValue SQL_VARIANT
)
GO

IF OBJECT_ID('dbo.sp_GetGlobalVariableValue') IS NOT NULL
    DROP PROC dbo.sp_GetGlobalVariableValue
GO
CREATE PROC dbo.sp_GetGlobalVariableValue
(
    @varName NVARCHAR(100),
    @varValue SQL_VARIANT = NULL OUTPUT 
)
AS
    SET NOCOUNT ON    
    -- set the output parameter
    SELECT    @varValue = varValue 
    FROM    sp_globalVariables 
    WHERE    varName = @varName

    -- also return it as a resultset
    SELECT    varName, varValue 
    FROM    sp_globalVariables 
    WHERE    varName = @varName
    SET NOCOUNT OFF
GO

IF OBJECT_ID('dbo.sp_SetGlobalVariableValue') IS NOT NULL
    DROP PROC dbo.sp_SetGlobalVariableValue
GO
CREATE PROC dbo.sp_SetGlobalVariableValue
(
    @varName NVARCHAR(100),
    @varValue SQL_VARIANT,
    @result CHAR(1) = NULL OUTPUT 
)
AS
    SET NOCOUNT ON
    UPDATE    dbo.sp_GlobalVariables 
    SET        varValue = @varValue
    WHERE    varName = @varName;    
    -- if it doesn't exist yet add it
    IF @@rowcount = 0
    BEGIN 
        INSERT INTO dbo.sp_GlobalVariables(varName, varValue)
        SELECT @varName, @varValue
        -- return it as inserted        
        SELECT @result = 'I'
    END 
    -- return it as updated
    SELECT @result = 'U'
    SET NOCOUNT OFF
GO

DECLARE @dt DATETIME
SELECT @dt = GETDATE()
EXEC sp_SetGlobalVariableValue 'GlobalDate', @dt;
EXEC sp_SetGlobalVariableValue 'GlobalInt', 5;
EXEC sp_SetGlobalVariableValue 'GlobalVarchar', 'This is a very good global variable'
EXEC sp_SetGlobalVariableValue 'GlobalBinary', 0x0012314;

GO

EXEC sp_GetGlobalVariableValue 'GlobalDate' 
EXEC sp_GetGlobalVariableValue 'GlobalInt'
EXEC sp_GetGlobalVariableValue 'GlobalVarchar'
EXEC sp_GetGlobalVariableValue 'GlobalBinary'

GO
-- update value in master
EXEC sp_SetGlobalVariableValue 'GlobalVarchar', 'New varchar value'

USE AdventureWorks

EXEC sp_GetGlobalVariableValue 'GlobalDate' 
EXEC sp_GetGlobalVariableValue 'GlobalInt'
EXEC sp_GetGlobalVariableValue 'GlobalVarchar'
EXEC sp_GetGlobalVariableValue 'GlobalBinary'

-- update value in AdventureWorks
EXEC sp_SetGlobalVariableValue 'GlobalInt', 6

EXEC sp_GetGlobalVariableValue 'GlobalDate' 
EXEC sp_GetGlobalVariableValue 'GlobalInt'
EXEC sp_GetGlobalVariableValue 'GlobalVarchar'
EXEC sp_GetGlobalVariableValue 'GlobalBinary'

答案 2 :(得分:0)

您可以使用临时表。 我的方案是,当通过已知流程更新数据时,它会在审计表中添加一条注释,说明“这是故意的”。

当proc触发时,它会在#auditnote中插入一个值(这是我动态创建的临时表)。

触发器检查该表。如果它存在,它会拉出注释并将其放在审计表上。

如果没有,那就是它的业务。

我查看了使用@@变量,但其中的技巧是确定变量是否存在。我没有办法。

实施例: 存储过程:

SELECT 'Alrighty Then' AS NOTE INTO #AuditNote

触发:

    DECLARE @noteExists BIT
    DECLARE @note NVARCHAR(500)
    IF OBJECT_ID('tempdb..#auditnote') IS NOT NULL
    BEGIN
        SELECT 
            TOP (1)
            @noteExists = 1,
            @note = Note
        FROM 
            #auditNote
    END ELSE BEGIN
        SELECT @noteExists = 0
    END

-- do something with the note

    IF @noteExists = 1
    BEGIN
        DROP TABLE #AuditNotes
    END

我正在使用@noteExists而不是null检查,因为有人可以插入一个null作为注释,所以我们不知道null是否表示TABLE不存在或注意是NULL。