SQL Views - no variables?

TsqlSql View

Tsql Problem Overview


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'.

Tsql Solutions


Solution 1 - Tsql

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

Solution 2 - Tsql

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)

Solution 3 - Tsql

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

Solution 4 - Tsql

@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

Solution 5 - Tsql

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.

Solution 6 - Tsql

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.

Solution 7 - Tsql

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

Solution 8 - Tsql

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).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPositiveGuyView Question on Stackoverflow
Solution 1 - Tsqlspencer7593View Answer on Stackoverflow
Solution 2 - TsqldatenstationView Answer on Stackoverflow
Solution 3 - TsqlDaniel NeelView Answer on Stackoverflow
Solution 4 - TsqlOleg MelnikovView Answer on Stackoverflow
Solution 5 - TsqlHoganView Answer on Stackoverflow
Solution 6 - TsqlShane KView Answer on Stackoverflow
Solution 7 - TsqlBen MessengerView Answer on Stackoverflow
Solution 8 - TsqlRaRdEvAView Answer on Stackoverflow