데이터베이스에 대한 일련의 작업을 정리한 절차를 RDBMS에 저장한 것(지속성)
CREATE PROCEDURE {프로시저명} AS {저장할 SQL문장들}
CREATE PROCEDURE SimpleSP //프로시저명
AS SELECT Id,Score FROM [Scores] //저장할 SQL문장들
-- 입력 파라미터 @class, @minScore
-- 출력 파라미터 @avergage
--
CREATE PROCEDURE sp_ClassAvg
@class int,
@minScore int,
@average int output
AS
DECLARE @sum int
DECLARE @cnt int
SELECT @sum=SUM(Score),@cnt=COUNT(Score)
FROM [Scores]
WHERE Score >= @minScore
SET @average = @sum/@cnt
INSERT INTO RunData
VALUES (@class,@minScore,@avergage)
GO
@
로 시작되는 파라미터명과 타입을 적어 콤마(,)로 구분하여 넣음OUTPUT
키워드를 뒤에 붙임EXECUTE
(또는 EXEC
)문이나 sp_executesql
사용-- SimpleSP 호출
EXECUTE SimpleSP
-- sp_ClassAvg 호출
-- Ordered Parameters
DECLARE @avg int
EXEC sp_ClassAvg 10, 50, @avg output
SELECT @avg
GO
-- sp_ClassAvg 호출
-- Named Parameters
DECLARE @avg int
EXEC sp_ClassAvg @minScore=50, @class=10, @average=@avg output
SELECT @avg
GO
sp_executesql
은 EXECUTE보다 보안이나 성능면에서 더 향상된 기능 제공네트워크 부하 감소
하나의 요청으로 여러 SQL문 실행 가능
처리시간 감소
사전에 구문 분석 및 내부 중간 코드로 변환을 마쳐야 함
데이터베이스의 데이터 참조 무결성 유지
데이터베이스 트리거와 결합하여 복잡한 규칙에 의한 데이터의 앞뒤가 맞게 될 수 있음
JAVA 등의 호스트 언어와 SQL 문장이 확실하게 분리된 소스 코드의 전망이 좋아짐
뛰어난 보수성
웹사이트 등 운용 중에도 저장 프로시저의 교체에 의한 수정 가능
코드 자산으로서의 재사용성이 나쁨
데이터베이스 제품에 대해 설명하는 구문 규칙이 SQL / PSM 표준과의 호환성이 낮음
불필요한 수고와 변경 실수에 의한 장애 발생 가능성 존재
비즈니스 로직의 일부로 사용하는 경우, 업무의 사양 변경 시 외부 응용 프로그램과 함께 저장 프로시저의 정의를 변경할 필요 존재
JPA 2.1부터 JPA 기준 쿼리 API를 사용하여 저장 프로시저 호출 지원
IN
: 입력 매개변수OUT
: 출력 매개변수INOUT
: 입력 및 출력에 사용되는 매개변수REF_CURSOR
: 결과 집합의 커서<!-- 2개의 IN 매개변수 를 취하여 합산하고 결과를 OUT 매개변수 로 반환 -->
CREATE OR REPLACE FUNCTION calculate(
IN x double precision,
IN y double precision,
OUT sum double precision)
RETURNS double precision AS
$BODY$
BEGIN
sum = x + y;
END;
$BODY$
LANGUAGE plpgsql
@NamedStoredProcedureQuery
@NamedStoredProcedureQuery(
name = "calculate", //쿼리 이름
procedureName = "calculate", //데이터베이스의 저장 프로시저명
parameters = { //저장 프로시저의 매개변수와 일치하는 매개변수 목록
@StoredProcedureParameter(mode = ParameterMode.IN, type = Double.class, name = "x"),
@StoredProcedureParameter(mode = ParameterMode.IN, type = Double.class, name = "y"),
@StoredProcedureParameter(mode = ParameterMode.OUT, type = Double.class, name = "sum")
}
)
//정의된 @NamedStoredProcedureQuery에 대한 StoredProcedureQuery 얻음
StoredProcedureQuery query = this.em.createNamedStoredProcedureQuery("calculate");
query.setParameter("x", 1.23d);
query.setParameter("y", 4.56d);
query.execute();
Double sum = (Double) query.getOutputParameterValue("sum");
StoredProcedureQuery
IN
매개변수의 값을 설정하고, 저장 프로시저를 실행하여OUT
매개변수를 가져오는 데 필요한 메소드 제공
REF_CURSOR
가 있는 SPCREATE OR REPLACE FUNCTION get_reviews(bookid bigint)
RETURNS refcursor AS
$BODY$
DECLARE
reviews refcursor; – Declare cursor variables
BEGIN
OPEN reviews FOR SELECT id, comment, rating, version, book_id FROM review WHERE book_id = bookId;
RETURN reviews;
END;
$BODY$
LANGUAGE plpgsql
@NamedStoredProcedureQuery
@NamedStoredProcedureQuery(
name = "getReviews",
procedureName = "get_reviews",
resultClasses = Review.class, //저장 프로시저 호출에 의해 반환된 결과 클래스 정의
parameters = { //위치 매개변수 매핑 사용
@StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, type = void.class),
@StoredProcedureParameter(mode = ParameterMode.IN, type = Long.class)
}
)
List<Book> books = (List<Book>) this.em.createNamedStoredProcedureQuery("getBooks").getResultList();
for (Book b : books) {
StoredProcedureQuery q = this.em.createNamedStoredProcedureQuery("getReviews");
q.setParameter(2, b.getId());
List<Review> reviews = q.getResultList();
for (Review r : reviews) {
// do something
}
}
getResultList()
호출execute()
메서드를 암시적으로 호출📖 참고