85

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

Declare @SomeVar varchar(8) = 'something'

给我语法错误:

关键字“声明”附近的语法不正确。

4

8 回答 8

67

你是对的。视图中不允许使用局部变量。

您可以在表值函数中设置局部变量,该函数返回结果集(就像视图一样。)

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
于 2011-05-24T18:08:06.670 回答
50

您可以使用 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)
于 2016-12-09T13:49:49.590 回答
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
于 2014-11-17T23:37:17.033 回答
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

也通过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
于 2017-12-12T18:19:01.763 回答
4

是的,这是正确的,视图中不能有变量(也有其他限制)。

视图可用于结果可以用 select 语句替换的情况。

于 2011-05-24T18:05:32.363 回答
4

使用提到的 spencer7593 函数是动态数据的正确方法。对于静态数据,与 SQL 数据设计(相对于在 sprocs 中编写大量过程代码的反模式)一致的更高性能的方法是使用静态值创建一个单独的表并连接到它。从性能的角度来看,这是非常有益的,因为 SQL 引擎可以围绕 JOIN 构建有效的执行计划,并且如果需要,您还可以添加索引。

使用函数(或任何内联计算值)的缺点是调用会针对返回的每个潜在行进行,这是昂贵的。为什么?因为 SQL 必须首先使用计算值创建一个完整的数据集,然后将 WHERE 子句应用于该数据集。

十分之九的查询中不需要动态计算的单元格值。最好弄清楚你需要什么,然后设计一个支持它的数据模型,并用半动态数据(例如通过批处理作业)填充该数据模型,并使用 SQL 引擎通过标准 SQL 完成繁重的工作.

于 2016-09-01T14:07:48.583 回答
1

我所做的是创建一个执行与表变量相同的选择的视图,并将该视图链接到第二个视图。所以一个视图可以从另一个视图中选择。这达到了相同的结果

于 2016-06-08T01:55:52.670 回答
0

您需要多久刷新一次视图?我有一个类似的情况,新数据每月出现一次;然后我必须加载它,并且在加载过程中我必须创建新表。在那一刻,我改变了我的观点来考虑这些变化。我将其他问题中的信息用作基础:

动态创建视图和同义词

在那里,建议以两种方式进行:

  1. 使用同义词。
  2. 使用动态 SQL 创建视图(这是帮助我实现结果的原因)。
于 2019-09-23T14:48:47.330 回答