我有一個視圖,返回用戶項目,也是他們的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