我有一个视图,返回用户项目,也是他们的Windows登录。数据的一个例子如下: -如何在sql server 2008中创建一个全局变量
project | Login
------------------
project 1 | richab
project 2 | stevej
我需要将域追加到登录。我可以把它放在代码中,但我不想在我创建的每个视图中都这么做,这会导致用户登录。
我可以创造我可以在视图代码中引用一个全局变量。我该如何实现这个目标?这是什么最佳实践?
我有一个视图,返回用户项目,也是他们的Windows登录。数据的一个例子如下: -如何在sql server 2008中创建一个全局变量
project | Login
------------------
project 1 | richab
project 2 | stevej
我需要将域追加到登录。我可以把它放在代码中,但我不想在我创建的每个视图中都这么做,这会导致用户登录。
我可以创造我可以在视图代码中引用一个全局变量。我该如何实现这个目标?这是什么最佳实践?
我不知道,如果SQL Server有全局变量,但你可以按如下方式使用用户定义的函数:
CREATE FUNCTION dbo.fn_GetDomainName()
RETURNS STRING
AS
BEGIN
RETURN 'domain_name\\'
END
,并在您欣赏到相应的位置做一个SELECT dbo.fn_GetDomainName() + Login FROM table WHERE ...
。
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', 0x0;
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'
您可以使用临时表。 我的情景是,当数据通过一个已知的进程进行更新时,它会向审计表添加一条注释,指出“这是故意完成的”。
当该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。
或使用表中的全局变量,而不是... – Matten
性能如何呢?我会在每行调用一个函数时看到一大滴吗? –
它只是返回一个静态字符串,所以开销应该相当有限。 – Asken