SQL视图 - 没有变量?

Pos*_*Guy 75 t-sql

是否可以在视图中声明变量?例如:

Declare @SomeVar varchar(8) = 'something'
Run Code Online (Sandbox Code Playgroud)

给我语法错误:

关键字'Declare'附近的语法不正确.

spe*_*593 59

你是对的.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
Run Code Online (Sandbox Code Playgroud)

  • 不,TVF 通常较慢。“SQL Server 的表值函数 (TVF) 看起来是个好主意,但它们掩盖了许多潜在的性能问题。TVF 导致执行计划的某些部分保持串行(它们将避免并行性),它们会产生错误的行估计,多语句 TVF 甚至可能无法获得最佳优化。简而言之 – TVF 很糟糕。” https://www.brentozar.com/blitzcache/tvf-join/ (2认同)

小智 42

您可以使用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)
Run Code Online (Sandbox Code Playgroud)

  • 这是一个常数,而不是变量! (2认同)
  • @Vladislav它可以轻松地使用(过滤?)表中的数据。 (2认同)

Dan*_*eel 18

编辑:正如@bummi指出的那样,我尝试在我之前的回答中使用CTE是不正确的.此选项应该起作用:

这是使用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
Run Code Online (Sandbox Code Playgroud)


Ole*_*kov 7

@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
Run Code Online (Sandbox Code Playgroud)

也通过 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
Run Code Online (Sandbox Code Playgroud)

也通过 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
Run Code Online (Sandbox Code Playgroud)