Представления SQL - без переменных? - PullRequest
68 голосов
/ 24 мая 2011

Можно ли объявить переменную в представлении? Например:

Declare @SomeVar varchar(8) = 'something'

дает мне синтаксическую ошибку:

Неверный синтаксис рядом с ключевым словом «Объявить».

Ответы [ 7 ]

55 голосов
/ 24 мая 2011

Вы правы. Локальные переменные не допускаются в 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
39 голосов
/ 09 декабря 2016

Вы можете использовать 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)
18 голосов
/ 18 ноября 2014

РЕДАКТИРОВАТЬ: Я пытался использовать 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
3 голосов
/ 01 сентября 2016

Использование функций в качестве упомянутого spencer7593 является правильным подходом для динамических данных. Для статических данных более производительный подход, который согласуется с дизайном данных SQL (по сравнению с анти-паттерном написания массивного процедурного кода в sprocs), заключается в создании отдельной таблицы со статическими значениями и присоединении к ней. Это чрезвычайно полезно с точки зрения производительности, поскольку SQL Engine может строить эффективные планы выполнения на основе JOIN, и у вас есть возможность добавлять индексы, если это необходимо.

Недостаток использования функций (или любых встроенных вычисляемых значений) заключается в том, что сноска происходит для каждой возвращаемой строки потенциала , что является дорогостоящим. Зачем? Поскольку SQL должен сначала создать полный набор данных с вычисленными значениями, а затем применить предложение WHERE к этому набору данных.

В девяти случаях из десяти вам не нужно динамически вычислять значения ячеек в ваших запросах. Намного лучше выяснить, что вам нужно, затем спроектировать модель данных, которая ее поддерживает, и заполнить эту модель данных полудинамическими данными (например, с помощью пакетных заданий) и использовать SQL Engine для выполнения тяжелый подъем с помощью стандартного SQL.

3 голосов
/ 24 мая 2011

Да, это правильно, вы не можете иметь переменные в представлениях (есть и другие ограничения).

Представления могут использоваться в тех случаях, когда результат может быть заменен оператором выбора.

2 голосов
/ 12 декабря 2017

@ 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
1 голос
/ 08 июня 2016

Что я делаю, это создаю представление, которое выполняет тот же выбор, что и переменная таблицы, и связываю это представление со вторым представлением.Таким образом, вид может выбрать другой вид.Это достигает того же результата

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...