2011-04-08 4 views
5

우리는 지금 10-12 년 된 오래된 프로젝트를 가지고 있습니다. 그것은 우리가 SQL2008로 옮긴 SQL2000을 사용하고있었습니다.저장 프로 시저의 동적으로 형성된 SQL은 저장 프로 시저의 목적을 부정합니다?

이 작업을 수행하는 동안 저장 프로 시저가 매개 변수를 수락했다가 쿼리를 문자열로 구성한 다음 EXEC를 사용하여 명령을 실행하는 것으로 나타났습니다.

CREATE PROCEDURE MyProc 
    (@TableName varchar(255), 
    @FirstName varchar(50), 
    @LastName varchar(50)) 
AS 

    -- Create a variable @SQLStatement 
    DECLARE @SQLStatement varchar(255) 

    -- Enter the dynamic SQL statement into the 
    -- variable @SQLStatement 
    SELECT @SQLStatement = "SELECT * FROM " + 
        @TableName + "WHERE FirstName = '" 
        + @FirstName + "' AND LastName = '" 
        + @LastName + "'" 

    -- Execute the SQL statement 
    EXEC(@SQLStatement) 

이 방법이 좋지 않습니다. 이로 인해 저장 프로 시저 (미리 컴파일 된 쿼리 이점)의 이점이 사라지나요?

+0

그런 목적으로 select를 수행하는 것이 유일한 목적이라면 나쁜 생각 인 것처럼 보이지만 성능상의 이유로 디자인이 좋지 않기 때문입니다. – JNK

+0

+1 질문, 나는 이것이 단지 예일 뿐이라는 것을 이해합니다. 일반적으로 질문입니다. 이것은 저장 프로 시저의 이점을 없애 줍니까? 더 복잡한 sproc에서 가정 해 봅시다. –

+0

예, SP는 단순한 예일뿐입니다.하지만 걱정되는 것은 정말 크고 못생긴 것입니다. 중간 선택 구문을 작성하고 중간에 임시 테이블을 채우는 것과 같은 패턴이 다음과 같이 있습니다. 페이지 매김 ... 그리고 물건 –

답변

7

아니요. 스토어드 프로 시저의 주요 이점은 더 이상 "미리 컴파일 된"것이 아니라고 말하고 싶습니다 (2005 년 또는 그 이전부터, 매우 높은 볼륨 호출을 제외하고는 절대로).

또한 임시 문에 사용할 계획 캐시가있다. 테이블 이름 파라미터되는 위해서

CREATE PROCEDURE MyProc 
    (@FirstName varchar(50), 
    @LastName varchar(50)) 
AS 
BEGIN 
    SELECT * FROM TABLENAME 
    WHERE FirstName = @FirstName 
     AND LastName = @LastName 
END 

전체 :

이 특정 예제와 자동 주입 될 취약점을 재 도입 하였다.

저장 프로 시저의

장점은 다음과 않습니다 :

  • 보안 관리를

  • 액세스 조정 (모든 작업을 보장하는 것은 특정에 완료 (독립적으로 SELECT/INSERT/UPDATE의 EXEC 권한을 제어 할 수있는) 방식)

  • 조직 (일관된 방식으로 데이터베이스에 대한 인터페이스를 구성 할 수 있음)

  • 주입 예방 (저장 프로 시저가 항상 매개 변수화되어있어 호출자가 주입에 취약한 데이터베이스 케이스를 만들 수 없음 - SP 자체는 올바르게 작성되어야하지만 클라이언트 프로그래머는 주입을 도입 할 수 없습니다. 만 SP를하지 테이블)

  • 시스템 인벤토리 (프로파일 및 저장 프로 시저로 구성된 포괄적이고 잘 문서화 인터페이스 층)

을 할 수있는 이름으로 특정 절차를 최적화 할 수있는 액세스 권한이 SP의에서

동적 SQL은 그 자리를 가지고, 그것은 몇 가지를 부정 할 수 - 보안 (같은 새로운 체인을 시작하므로 SELECT 권한을 부여해야합니다.) 및 삽입. 실행 계획 캐싱은 내가 목록에 올릴만한 것이 아닙니다.

0

는 실행 계획의 복잡성에 따라 달라집니다. 이 특별한 경우에는 실행 계획이 매우 간단하므로 저장 프로 시저에 아무런 문제가 없습니다.

1

EXEC (@SQL) 대신 sp_execute (@SQL)를 시도하십시오.

sp_execute 두 (@SQL)은 쿼리 계획 재사용을 촉진합니다. sp_executesql을 사용할 때 사용자 또는 응용 프로그램이 매개 변수를 명시 적으로 식별합니다. 이 기술 기사에서 계획 캐싱 문제 here에 대해 읽어보십시오. # 3을 참조하십시오.

+0

나는 또한 sp_executesql의 함정을 설명하는이 기사를 추천 할 것이다. http://www.sqlskills.com/BLOGS/KIMBERLY/post/EXEC-and-sp_executesql-how-are-they-different.aspx –

1

스토어드 프로 시저의 '목적'에 따라 결정되는 사항에 따라 다릅니다. 데이타베이스에 보안 API를 노출하고 SQL을 코드베이스에서 제외시킴으로써 데이터베이스 구현에서 응용 프로그램을 분리하는 저장 프로 시저가 있다고 주장합니다.

이렇게하면 데이터베이스를 참조하는 응용 프로그램 코드와 별도로 수정하고 버전을 지정할 수있는 별도의 구성 요소가됩니다 (API 서명이 변경되지 않는 한 변경되지 않습니다).

모든 데이터베이스 액세스가 저장 프로 시저를 통해 수행되는 경우 저장 프로 시저 인수 및 결과 집합이 변경되지 않는 한 DBA는 쿼리를 튜닝하고 데이터베이스를 마음의 내용으로 자유롭게 개조 할 수 있습니다. 코드가 데이터 모델에 대한 가정을 깨뜨리지 않습니다. 코드 변경을 요구하지 않고 [이론적으로] 기본 스키마를 완전히 변경할 수 있습니다.

저장 프로 시저의 장점입니다.