T-SQL 반복

5628 단어
요약: 프로그램에서 컴포지팅을 호출하는 것은 매우 간단하다. 방법에서 자신을 호출하면 되지만 데이터베이스 작업에서 이런 방법은 불가능하다. 그러면 SQL Server에서 컴포지팅 호출을 어떻게 쓰는지 살펴보자.
주요 내용:
SQL Server 2005 이전까지 SQL Server는 런타임 레벨에서 반복 처리를 위해 설계되지 않았다고 할 수 있습니다.즉, 귀속을 실현하려면 귀속 논리를 스스로 제어할 수 밖에 없으며, 귀속을 순환 조작으로 전환할 수 있다는 것이다.그러나 SQL Server 2005에 도착한 후에 돌아가는 쓰기 방식은 훨씬 간단해졌다. 왜냐하면 SQL Server 2005는 CTE(Common Table Expression 공용 표 표현식)를 도입했기 때문이다.다음은 msdn에서 CTE에 대한 간단한 설명입니다.
공용 테이블 표현식(CTE)을 임시 결과 세트로 보고 SELECT, INSERT, UPDATE, DELETE 또는 CREATE VIEW 문의 실행 범위 내에서 정의할 수 있습니다.CTE는 파생 테이블과 유사하며 개체로 저장되지 않고 조회 기간에만 유효합니다.파생표와 다른 점은 CTE는 스스로 인용할 수 있고 같은 조회에서 여러 번 인용할 수 있다는 점이다.CET에서 사용 가능: 재귀적 질의를 작성합니다.자세한 내용은 공통 테이블 표현식을 사용한 반복 질의를 참조하시기 바랍니다.일반적인 보기를 사용할 필요가 없을 때 보기를 바꿉니다. 즉, 정의를 메타데이터에 저장할 필요가 없습니다.표량에 따라 select 문장에서 파생된 열을 그룹화하거나 불확실성 함수나 외부 접근이 있는 함수를 그룹화합니다.같은 문장에서 여러 번 인용하여 생성된 표.CTE를 사용하면 읽기 쉽고 복잡한 질의를 쉽게 유지할 수 있습니다.조회는 단독 블록, 단순 블록, 논리적 생성 블록으로 나눌 수 있다.그런 다음 최종 결과 세트가 생성될 때까지 더 복잡한 임시 CTE를 생성하는 데 이러한 단순 블록을 사용할 수 있습니다.반복 CTE는 다음 세 가지 요소로 구성됩니다. 루틴 호출입니다.반복 CTE의 첫 번째 호출에는 UNION ALL, UNION, EXCEPT 또는 INTERSECT 연산자로 연결된 CTE 하나 이상의 CTE가 포함됩니다.query_definitions.이러한 질의 정의는 CTE 구조의 데이텀 결과 세트를 형성하기 때문에 위치 점 멤버라고 합니다.CTE_query_definitions는 CTE 자체를 인용하지 않는 한 포지셔닝 포인트 구성원으로 간주됩니다.모든 고정점 구성원 조회 정의는 첫 번째 귀속 구성원 정의 앞에 놓여야 하며, UNION ALL 연산자를 사용하여 마지막 고정점 구성원과 첫 번째 귀속 구성원을 연결해야 한다.규칙의 귀속 호출.CTE 자체를 참조하는 UNION ALL 연산자로 연결된 하나 이상의 CTE 반복 호출query_definitions.이러한 질의 정의는 반복 멤버라고 합니다.검사를 중지하다.검사를 중지하는 것은 은식이다.이전 호출에서 줄을 되돌려 주지 않았을 때, 귀속은 정지됩니다.
CTE가 생기면 SQL Server에서 귀속을 사용하는 것이 훨씬 간단해진다. 귀속 호출의 종료 조건을 전혀 고려하지 않아도 되기 때문이다. 정말 귀속 호출 절차는 데이터베이스 자체에 맡겨져 처리된다.다음은 귀속의 사용을 직접 살펴보고 먼저 아래의 문장을 사용하여 귀속의 사용 환경을 구축한다.
--Create Table
IF EXISTS (SELECT [name] FROM dbo.sysobjects WHERE [name]='Tree' AND type='u' )
	BEGIN 
		IF EXISTS(SELECT [name] FROM dbo.sysobjects WHERE [name]='Info' AND type='u')
			DROP TABLE Info
		DROP TABLE Tree
	END
ELSE
	BEGIN
		CREATE TABLE Tree 
		(
			id BIGINT PRIMARY KEY,
			[name] NVARCHAR(50) NOT NULL,
			parentID BIGINT FOREIGN KEY REFERENCES Tree(id) ON DELETE NO ACTION NOT NULL
		)
	END
IF EXISTS(SELECT [name] FROM dbo.sysobjects WHERE [name]='Info' AND type='u')
	DROP TABLE Info
ELSE
	BEGIN
		CREATE TABLE Info
		(
			id BIGINT PRIMARY KEY FOREIGN KEY REFERENCES Tree(id) ON DELETE CASCADE,
			info NVARCHAR(500)
		)
	END	
-- Insert Data
DELETE FROM dbo.Tree
DELETE FROM dbo.Info
INSERT INTO dbo.Tree VALUES(1,'A',0)
INSERT INTO dbo.Tree VALUES(2,'B',1)
INSERT INTO dbo.Tree VALUES(3,'C',1)
INSERT INTO dbo.Tree VALUES(4,'D',2)
INSERT INTO dbo.Tree VALUES(5,'E',2)
INSERT INTO dbo.Tree VALUES(6,'F',3)
INSERT INTO dbo.Tree VALUES(7,'G',3)
INSERT INTO dbo.Tree VALUES(8,'H',4)
INSERT INTO dbo.Tree VALUES(9,'I',4)
INSERT INTO dbo.Tree VALUES(10,'J',4)
INSERT INTO info VALUES(1,'AA')
INSERT INTO info VALUES(2,'BB')
INSERT INTO info VALUES(3,'CC')
INSERT INTO info VALUES(4,'DD')
INSERT INTO info VALUES(5,'EE')
INSERT INTO info VALUES(6,'FF')
INSERT INTO info VALUES(7,'GG')
INSERT INTO info VALUES(8,'HH')
INSERT INTO info VALUES(9,'II')
INSERT INTO info VALUES(10,'JJ')	

이 표에는 하위 노드와 상위 노드의 관계가 저장되어 있고 깊이가 얼마나 되는지 모른다. 현재의 수요는 임의의 하위 노드를 찾아야 하는 모든 하위 노드를 찾는 것이다. CTE를 사용하여 실현하기 전에 CTE가 없기 전의 문법을 되돌아보자.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		KenshinCui
-- Create date: 2011.12.26
-- Description:	 
-- =============================================
CREATE FUNCTION GetChildren
(	
	@ID INT 
)
RETURNS @tbChildren TABLE(ID INT,Level INT)
AS
	BEGIN
		DECLARE @Level INT
		SET @Level=1 
		INSERT INTO @tbChildren(ID,Level) SELECT id,@Level FROM dbo.Tree WHERE parentID=@ID
		WHILE @@ROWCOUNT<>0
			BEGIN	
				SET @Level=@Level+1
				INSERT INTO @tbChildren(ID,Level) SELECT id,@Level FROM dbo.Tree WHERE parentID IN (SELECT ID FROM @tbChildren WHERE Level=(@Level-1) )
			END
		RETURN
	END
GO

이전의 글인'SQL의 트리 구조 무한급 연결 삭제'에서도 사실상 귀환으로 해결되었는데, 실현 원리는 위와 같다(귀환을 순환으로 전환한 다음에 순환 종료 조건을 제어함으로써 호출을 끝낸다)는 것은 위쪽이 간결할 수 있을 뿐이다.CTE를 사용하여 이 문제를 해결하는 방법에 대해 살펴보겠습니다.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		KenshinCui
-- Create date: 2011.12.30
-- Description:	 
-- =============================================
CREATE FUNCTION GetChildren
(
	@ID INT
)
RETURNS 
@tbChildren TABLE 
(
	ID INT 
)
AS
BEGIN
	
	WITH ChildrenCTE(ID)
	AS
	(
		SELECT ID FROM dbo.Tree WHERE parentID=@ID
		UNION ALL
		SELECT Tree.ID FROM Tree INNER JOIN ChildrenCTE ON ChildrenCTE.ID = Tree.parentID
	)
	INSERT INTO @tbChildren  SELECT Id FROM ChildrenCTE
	
	RETURN
END
GO

귀속 절차는 수동으로 관여하지 않아도 되고 종료 조건도 수동으로 판단할 필요가 없으며 처음으로 SELECTIDFROMdbo를 호출한 것을 볼 수 있다.TreeWHEREparentID=@ID는ChildrencTE에 ID를 넣고 두 번째는SELECTree를 호출합니다.IDFROMTree INNERJOIN ChildrenCTEONChildrenCTE.ID = Tree.parentID (물론 이 때 처음 호출된 ID가 있음) 는 이 문장을 반복적으로 실행합니다. (또한 ChildrencTE에서 값을 얻을 때마다 지난번에 얻은 값을 배제합니다. 그렇지 않으면 이 문장이 다시 줄로 돌아가지 않을 때까지 반복됩니다.)이때 모든 데이터도 이미 Childrencte에 넣었으니 어떻게 조작하든지 당연히 네 마음대로 해라.
주의해야 할 것은 CTE의 기본 귀속 단계는 100이다. 만약에 당신의 요구를 충족시키지 못하면 OPTION(MAXRECURSION Level)을 통해 설정할 수 있다. 예를 들어 위에서 2층 이내의 데이터만 조회하고자 한다면 ChildrencTE를 조회할 때 OPTION(MAXRECURSION 2)을 추가하면 된다.
본 작품은 지식 공유 서명 2.5 중국 대륙 허가 협의를 이용하여 허가를 진행하고 전재, 연역 또는 상업 목적에 사용되는 것을 환영합니다.그러나 전재는 최강도(KenshinCui)에서 왔고 관련 링크가 포함되어 있음을 명시해 주십시오.

좋은 웹페이지 즐겨찾기