2011-05-24 156 views
43

是否可以在View中聲明一個變量?例如:SQL視圖 - 沒有變量?

Declare @SomeVar varchar(8) = 'something' 

給我的語法錯誤:

Incorrect syntax near the keyword 'Declare'.

回答

43

你是對的。 VIEW中不允許局部變量。

可以設置在一個表值函數的局部變量,它返回一個結果集(像的圖一樣。)

http://msdn.microsoft.com/en-us/library/ms191165.aspx

例如

CREATE FUNCTION dbo.udf_foo() 
RETURNS @ret TABLE (col INT) 
AS 
BEGIN 
    DECLARE @myvar INT; 
    SELECT @myvar = 1; 
    INSERT INTO @ret SELECT @myvar; 
    RETURN; 
END; 
GO 
SELECT * FROM dbo.udf_foo(); 
GO 
+4

他們怎麼能使這件事變得可怕?有時候我認爲他們只僱用微軟認證專家。 – 2015-08-26 12:48:40

+1

我想有一個課程可以跳出用戶的概念,並用一袋錢的概念代替它,這個袋子可以幫助您獲得認證 – user1566694 2016-02-08 18:48:05

3

是的,這是正確的,你不能有意見 變量(還有其他的限制也是如此)。

視圖可以用於可以用select語句替換結果的情況。

+0

表函數可以在SELECT語句來代替,它有局部變量。 – JeffO 2017-03-29 12:28:45

+0

@JeffO - 不知道你指的是什麼。 – Hogan 2017-03-29 15:52:45

+0

你是說因爲select語句不能有局部變量,視圖也不能? – JeffO 2017-03-29 22:50:11

13

編輯:我試圖用我以前的答案,是不正確的熱膨脹係數,由@bummi指出。這個選項,而不是工作:

下面是一個使用CROSS APPLY一個選項,以一種工作解決此問題:

SELECT st.Value, Constants.CONSTANT_ONE, Constants.CONSTANT_TWO 
FROM SomeTable st 
CROSS APPLY (
    SELECT 'Value1' AS CONSTANT_ONE, 
      'Value2' AS CONSTANT_TWO 
) Constants 
+0

感謝您的更正 - 更新爲使用CROSS APPLY代替。 – 2014-11-19 19:57:06

+0

這是有效的,但不要交叉應用的列重新初始化爲每一行?特別是對於計算值來說,這意味着很大的性能損失。局部變量和CTE在視圖中不可用,這真讓人傷心,任何人都知道爲什麼? – 2015-11-30 15:05:36

1

我要做的就是創建一個執行同樣的選擇作爲表變量和視圖將該視圖鏈接到第二個視圖。所以一個視圖可以從另一個視圖中選擇。這實現了相同的結果

+1

Ben,除非你正在處理非常小的表格,否則這可能會導致性能問題。 – logixologist 2016-07-11 20:42:36

0

使用函數作爲spencer7593提到的動態數據是一種正確的方法。對於靜態數據,與SQL數據設計(與sprocs中寫入大量過程代碼的反模式)相一致的更高性能的方法是使用靜態值創建單獨的表並加入到它中。從性能角度來看,這是非常有益的,因爲SQL引擎可以圍繞JOIN構建有效的執行計劃,並且如果需要,您還可以添加索引。

使用函數(或任何內嵌計算值)的缺點是每隔潛在的行發生標註,這是昂貴的。爲什麼?由於SQL必須首先使用計算值創建完整數據集,然後將WHERE子句應用於該數據集。

九次你不應該需要在你的查詢動態計算的單元格值。它更好地弄清楚你需要什麼,然後設計一個支持它的數據模型,並用半動態數據(例如通過批處理作業)填充該數據模型,並使用SQL引擎來完成繁重的工作標準SQL。

15

您可以使用WITH來定義您的表達式。然後做一個簡單的Sub-SELECT來訪問這些定義。

CREATE VIEW MyView 
AS 
    WITH MyVars (SomeVar, Var2) 
    AS (
    SELECT 
     'something' AS 'SomeVar', 
     123 AS 'Var2' 
) 

    SELECT * 
    FROM MyTable 
    WHERE x = (SELECT SomeVar FROM MyVars) 
0

@datenstation有正確的概念。下面是一個使用CTE緩存變量名的工作例如:

CREATE VIEW vwImportant_Users AS 
WITH params AS (
    SELECT 
    varType='%Admin%', 
    varMinStatus=1) 
SELECT status, name 
    FROM sys.sysusers, params 
    WHERE status > varMinStatus OR name LIKE varType 

SELECT * FROM vwImportant_Users 

還通過JOIN

WITH params AS (SELECT varType='%Admin%', varMinStatus=1) 
SELECT status, name 
    FROM sys.sysusers INNER JOIN params ON 1=1 
    WHERE status > varMinStatus OR name LIKE varType 

還通過CROSS APPLY

WITH params AS (SELECT varType='%Admin%', varMinStatus=1) 
SELECT status, name 
    FROM sys.sysusers CROSS APPLY params 
    WHERE status > varMinStatus OR name LIKE varType