SQL 视图 - 没有变量?

发布于 2024-11-09 04:06:00 字数 175 浏览 7 评论 0原文

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

Declare @SomeVar varchar(8) = 'something'

给我语法错误:

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

Is it possible to declare a variable within a View? For example:

Declare @SomeVar varchar(8) = 'something'

gives me the syntax error:

Incorrect syntax near the keyword 'Declare'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

∞觅青森が 2024-11-16 04:06:01

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

What I do is create a view that performs the same select as the table variable and link that view into the second view. So a view can select from another view. This achieves the same result

┼── 2024-11-16 04:06:01

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

动态创建视图&同义词

在那里,建议采用两种方式:

  1. 使用同义词。
  2. 使用动态 SQL 创建视图(这帮助我实现了结果)。

How often do you need to refresh the view? I have a similar case where the new data comes once a month; then I have to load it, and during the loading processes I have to create new tables. At that moment I alter my view to consider the changes.
I used as base the information in this other question:

Create View Dynamically & synonyms

In there, it is proposed to do it 2 ways:

  1. using synonyms.
  2. Using dynamic SQL to create view (this is what helped me achieve my result).
心意如水 2024-11-16 04:06:00

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

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

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

You are correct. Local variables are not allowed in a VIEW.

You can set a local variable in a table valued function, which returns a result set (like a view does.)

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

e.g.

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
¢蛋碎的人ぎ生 2024-11-16 04:06:00

您可以使用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)

You could use WITH to define your expressions. Then do a simple Sub-SELECT to access those definitions.

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)
岁月静好 2024-11-16 04:06:00

编辑:我尝试在之前的答案中使用 CTE,这是不正确的,正如 @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

EDIT: I tried using a CTE on my previous answer which was incorrect, as pointed out by @bummi. This option should work instead:

Here's one option using a CROSS APPLY, to kind of work around this problem:

SELECT st.Value, Constants.CONSTANT_ONE, Constants.CONSTANT_TWO
FROM SomeTable st
CROSS APPLY (
    SELECT 'Value1' AS CONSTANT_ONE,
           'Value2' AS CONSTANT_TWO
) Constants
屌丝范 2024-11-16 04:06:00

@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

@datenstation had the correct concept. Here is a working example that uses CTE to cache variable's names:

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

also via 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

also via 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
温暖的光 2024-11-16 04:06:00

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

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

Yes this is correct, you can't have variables in views
(there are other restrictions too).

Views can be used for cases where the result can be replaced with a select statement.

度的依靠╰つ 2024-11-16 04:06:00

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

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

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

Using functions as spencer7593 mentioned is a correct approach for dynamic data. For static data, a more performant approach which is consistent with SQL data design (versus the anti-pattern of writting massive procedural code in sprocs) is to create a separate table with the static values and join to it. This is extremely beneficial from a performace perspective since the SQL Engine can build effective execution plans around a JOIN, and you have the potential to add indexes as well if needed.

The disadvantage of using functions (or any inline calculated values) is the callout happens for every potential row returned, which is costly. Why? Because SQL has to first create a full dataset with the calculated values and then apply the WHERE clause to that dataset.

Nine times out of ten you should not need dynamically calculated cell values in your queries. Its much better to figure out what you will need, then design a data model that supports it, and populate that data model with semi-dynamic data (via batch jobs for instance) and use the SQL Engine to do the heavy lifting via standard SQL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文