SQL보기-변수가 없습니까?


83

뷰 내에서 변수를 선언 할 수 있습니까? 예를 들면 :

Declare @SomeVar varchar(8) = 'something'

나에게 구문 오류를 제공합니다.

키워드 'Declare'근처에 잘못된 구문이 있습니다.

답변:


66

당신이 올바른지. 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

그 효율성은 뷰의 효율성과 비슷합니까?
RaRdEvA

아니요, TVF는 종종 더 느립니다. "SQL Server의 TVF (테이블 반환 함수)는 좋은 생각처럼 보이지만 잠재적 인 성능 문제를 숨 깁니다. TVF는 실행 계획의 일부를 직렬로 유지하고 (병렬 처리를 피할 수 있음) 잘못된 행 추정을 생성합니다. 다중 문 TVF는 사용 가능한 최상의 최적화를 얻지 못할 수도 있습니다. 간단히 말해서 TVF는 악취가납니다. " brentozar.com/blitzcache/tvf-join
wp78de

49

WITH를 사용하여 표현식을 정의 할 수 있습니다. 그런 다음 간단한 하위 선택을 수행하여 해당 정의에 액세스하십시오.

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)

3
이것은 변수가 아니라 상수입니다!
Vladislav

2
@Vladislav 테이블의 데이터를 (필터링 된?) 쉽게 사용할 수 있습니다.
Dodecaphone

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

수정 해 주셔서 감사합니다. 대신 CROSS APPLY를 사용하도록 업데이트되었습니다.
Daniel Neel 2014

이것은 작동하지만 교차 적용의 열이 모든 행에 대해 다시 초기화되지 않습니까? 특히 큰 성능 손실을 의미하는 계산 된 값의 경우. View에서 Local Variable과 CTE를 사용할 수 없다는 것은 슬픈 일입니다.
T_D 2015

1
@T_D는 '보기'에서 'CTE'를 만들고 사용할 수 있습니다.
Semuserable 2019-04-03

6

@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

4

언급 된 spencer7593으로 함수를 사용하는 것은 동적 데이터에 대한 올바른 접근 방식입니다. 정적 데이터의 경우 SQL 데이터 디자인과 일치하는보다 성능이 뛰어난 접근 방식 (sprocs에서 방대한 절차 코드를 작성하는 안티 패턴과 비교)은 정적 값을 사용하여 별도의 테이블을 만들고 여기에 조인하는 것입니다. 이는 SQL 엔진이 JOIN을 중심으로 효과적인 실행 계획을 구축 할 수 있고 필요한 경우 인덱스를 추가 할 수도 있기 때문에 성능 측면에서 매우 유용합니다.

함수 (또는 인라인 계산 된 값) 사용의 단점은 모든 잠재력에 대해 콜 아웃이 발생한다는 것입니다. 반환되는 행에 비용이 많이 든다는 것입니다. 왜? SQL은 먼저 계산 된 값으로 전체 데이터 세트를 만든 다음 해당 데이터 세트에 WHERE 절을 적용해야하기 때문입니다.

10 개 중 9 번은 쿼리에서 동적으로 계산 된 셀 값이 필요하지 않습니다. 필요한 것이 무엇인지 파악한 다음이를 지원하는 데이터 모델을 설계하고 해당 데이터 모델을 반동적 데이터 (예 : 일괄 작업을 통해)로 채우고 SQL 엔진을 사용하여 표준 SQL을 통해 무거운 작업을 수행하는 것이 훨씬 좋습니다. .


3

예, 맞습니다. 뷰에 변수를 사용할 수 없습니다 (다른 제한 사항도 있음).

결과를 select 문으로 바꿀 수있는 경우 뷰를 사용할 수 있습니다.


테이블 함수는 select 문에서 대체 될 수 있으며 지역 변수가 있습니다.
JeffO

select 문은 지역 변수를 가질 수 없기 때문에 뷰도 할 수 없다는 말입니까?
JeffO

1
@JeffO "뷰에서 변수를 가질 수 없습니다"라고 제가 말한 것입니다. 이것이 명확하지 않습니까?
Hogan

마지막 문장입니다. 보기는 select 문을 대체 할 수 있지만 변수와 관련이있는 것은 무엇입니까? 테이블 함수가 select 문을 대체 할 수 없지만 변수를 포함 할 수 있습니까?
JeffO

1
테이블 함수는 select 문으로도 바꿀 수 있지만 조인과 같이 뷰가 가능한 모든 곳에서 테이블 함수를 사용할 수는 없습니다. 그가 말하려는 것은 뷰가 단일 select 문을 바꿀 수 있지만 여러 문을 바꿀 수는 없다는 것입니다. BEGIN 키워드는 CREATE VIEW 문과 인라인 함수에서 유효하지 않습니다. 다중 문 스크립트를 작성해야합니다. 프로 시저 또는 다중 명령문 함수가이를 수행하는 가장 좋은 방법 일 것입니다.
Arlen Beiler

1

내가하는 일은 테이블 변수와 동일한 선택을 수행하는 뷰를 만들고 해당 뷰를 두 번째 뷰에 연결하는 것입니다. 따라서보기는 다른보기에서 선택할 수 있습니다. 이것은 동일한 결과를 얻습니다.


2
벤, 아주 작은 테이블을 다루지 않는 한 성능 문제가 발생할 수 있습니다.
Logixologist jul

아주 작은 테이블 (레코드 3 개)이 있더라도 백만 개의 레코드가있는 뷰는 큰 성능 문제를 일으 킵니다.
st_stefanov 19

0

보기를 얼마나 자주 새로 고쳐야합니까? 새 데이터가 한 달에 한 번 나오는 비슷한 경우가 있습니다. 그런 다음로드해야하고로드 프로세스 중에 새 테이블을 만들어야합니다. 그 순간 나는 변화를 고려하기 위해 나의 견해를 바꾼다. 이 다른 질문의 정보를 기반으로 사용했습니다.

동적으로보기 및 동의어 만들기

거기에서 두 가지 방법으로 제안됩니다.

  1. 동의어 사용.
  2. 동적 SQL을 사용하여보기 생성 (이것이 결과를 얻는 데 도움이되었습니다).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.