IT Log

[SQL Server] CREATE PROCEDURE 본문

SQL/SQL Server

[SQL Server] CREATE PROCEDURE

newly0513 2022. 2. 14. 09:52
728x90
반응형

※ 구문 규칙 참고

규칙 설명
기울임꼴 사용자가 제공하는 매개 변수
굵게 각종 이름및 텍스트를 그대로 정확히 입력
| (세로줄) 구문 항목을 구분하며, 항목 중 하나만 사용 가능 (선택사항)
{} (중괄호) 필수 구문이며, 중괄호는 입력하지 않음
[] 생략이 가능한 구문
[ , ...n] 앞의 항목이 n번 반복 가능하며, 각 항목은 쉼표로 구분
[ ... n] 앞의 항목이 n번 반복 가능하며, 각 항목은 공백으로 구분
; SQL문 종결자로, 대부분 생략하지만 이후 버전에서는 필요
<label> ::== 구문 블록의 이름

 

※ 간단 구문 설명

구문 설명
기본 구문 CREATE PROCEDURE
매개변수 전달 @parameter
 = 기본값 / OUTPUT / 테이블 반환 매개변수 형식 / CURSOR VARYING
데이터 수정 UPDATE
오류 처리 TRY...CATCH
프로시저 정의 난독 처리 WITH ENCRYPTION
프로시저의 리컴파일 강제 수행 WITH RECOMPILE
보안 컨텍스트 설정 EXECUTE AS

CREATE PROCEDURE

CREATE [ OR ALTER ] { PROC | PROCEDURE }
    [schema_name.] procedure_name [ ; number ]
    [ { @parameter_name [ type_schema_name. ] data_type }
        [ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY]
    ] [ ,...n ]
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ]
AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }
[;]

<procedure_option> ::=
    [ ENCRYPTION ]
    [ RECOMPILE ]
    [ EXECUTE AS Clause ]

 

예시

  • 단순 예시
CREATE PROCEDURE HumanResources.uspGetAllEmployees
AS
    SET NOCOUNT ON;
    SELECT LastName, FirstName, JobTitle, Department
    FROM HumanResources.vEmployeeDepartment;
GO

SELECT * FROM HumanResources.vEmployeeDepartment;

-- 프로시저 실행방식 3가지
-- 1. 기본(EXECUTE)
EXECUTE HumanResources.uspGetAllEmployees;
GO
-- 2. 기본 줄임(EXEC)
EXEC HumanResources.uspGetAllEmployees;
GO
-- 3. 생략
HumanResources.uspGetAllEmployees;

-- 프로시저 실행결과는 SELECT...FROM절 결과를 출력

 

  • 둘 이상 결과 집합
CREATE PROCEDURE dbo.uspMultipleResults
AS
SELECT TOP(10) BusinessEntityID, Lastname, FirstName FROM Person.Person;
SELECT TOP(10) CustomerID, AccountNumber FROM Sales.Customer;
GO

 

  • 매개변수가 있는 프로시저
CREATE PROCEDURE HumanResources.uspGetEmployees
    @LastName NVARCHAR(50),
    @FirstName NVARCHAR(50)
AS

    SET NOCOUNT ON;
    SELECT FirstName, LastName, JobTitle, Department
    FROM HumanResources.vEmployeeDepartment
    WHERE FirstName = @FirstName AND LastName = @LastName;
GO

-- 파라미터 지정X
EXECUTE HumanResources.uspGetEmployees N'Ackerman', N'Pilar';
-- 파라미터 지정(1)
EXEC HumanResources.uspGetEmployees @LastName = N'Ackerman', @FirstName = N'Pilar';
GO
-- 파라미터 지정(2)
EXECUTE HumanResources.uspGetEmployees @FirstName = N'Pilar', @LastName = N'Ackerman';
GO

 

  • 와일드카드 매개변수
CREATE PROCEDURE HumanResources.uspGetEmployees2
    @LastName NVARCHAR(50) = N'D%',
    @FirstName NVARCHAR(50) = N'%'
AS
    SET NOCOUNT ON;
    SELECT FirstName, LastName, JobTitle, Department
    FROM HumanResources.vEmployeeDepartment
    WHERE FirstName LIKE @FirstName AND LastName LIKE @LastName;

-- 매개변수 X
EXECUTE HumanResources.uspGetEmployees2;
-- 매개변수 1개
EXECUTE HumanResources.uspGetEmployees2 N'Wi%';
-- 매개변수 지정
EXECUTE HumanResources.uspGetEmployees2 @FirstName = N'%';
-- []사용 매개변수
EXECUTE HumanResources.uspGetEmployees2 N'[CK]ars[OE]n';
-- 매개변수 2개(1)
EXECUTE HumanResources.uspGetEmployees2 N'Hesse', N'Stefen';
-- 매개변수 2개(2)
EXECUTE HumanResources.uspGetEmployees2 N'H%', N'S%';

 

  • OUTPUT 사용
CREATE PROCEDURE Production.uspGetList @Product VARCHAR(40)
    , @MaxPrice MONEY
    , @ComparePrice MONEY OUTPUT
    , @ListPrice MONEY OUT
AS  
    SET NOCOUNT ON;
    SELECT p.[Name] AS Product, p.ListPrice AS 'List Price'
    FROM Production.Product AS p
    JOIN Production.ProductSubcategory AS s
      ON p.ProductSubcategoryID = s.ProductSubcategoryID
    WHERE s.[Name] LIKE @Product AND p.ListPrice < @MaxPrice;
-- Populate the output variable @ListPprice.
SET @ListPrice = (SELECT MAX(p.ListPrice)
    FROM Production.Product AS p
    JOIN Production.ProductSubcategory AS s
      ON p.ProductSubcategoryID = s.ProductSubcategoryID
    WHERE s.[Name] LIKE @Product AND p.ListPrice < @MaxPrice);
-- Populate the output variable @compareprice.
SET @ComparePrice = @MaxPrice;
GO

DECLARE @ComparePrice MONEY, @Cost MONEY;
EXECUTE Production.uspGetList '%Bikes%', 700,
    @ComparePrice OUT,
    @Cost OUTPUT
IF @Cost <= @ComparePrice
BEGIN
    PRINT 'These products can be purchased for less than
    $'+RTRIM(CAST(@ComparePrice AS VARCHAR(20)))+'.'
END
ELSE
    PRINT 'The prices for all products in this category exceed
    $'+ RTRIM(CAST(@ComparePrice AS VARCHAR(20)))+'.';
    
-- 결과
Product                     List Price
--------------------------  ----------
Road-750 Black, 58          539.99
Mountain-500 Silver, 40     564.99
Mountain-500 Silver, 42     564.99
...
Road-750 Black, 48          539.99
Road-750 Black, 52          539.99

(14 row(s) affected)

These items can be purchased for less than $700.00.

 

  • OUTPUT 커서 매개변수
CREATE PROCEDURE dbo.uspCurrencyCursor
    @CurrencyCursor CURSOR VARYING OUTPUT
AS
    SET NOCOUNT ON;
    SET @CurrencyCursor = CURSOR
    FORWARD_ONLY STATIC FOR
      SELECT CurrencyCode, Name
      FROM Sales.Currency;
    OPEN @CurrencyCursor;
GO

DECLARE @MyCursor CURSOR;
EXEC dbo.uspCurrencyCursor @CurrencyCursor = @MyCursor OUTPUT;
WHILE (@@FETCH_STATUS = 0)
BEGIN;
    FETCH NEXT FROM @MyCursor;
END;
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
GO

 

  • UPDATE 사용
CREATE PROCEDURE HumanResources.Update_VacationHours
@NewHours SMALLINT, @Rowcount INT OUTPUT
AS
SET NOCOUNT ON;
UPDATE HumanResources.Employee
SET VacationHours =
    ( CASE
        WHEN SalariedFlag = 0 THEN VacationHours + @NewHours
        ELSE @NewHours
        END
    )
WHERE CurrentFlag = 1;
SET @Rowcount = @@rowcount;

GO
DECLARE @Rowcount INT
EXEC HumanResources.Update_VacationHours 40, @Rowcount OUTPUT
PRINT @Rowcount;

 

  • 오류 처리
CREATE PROCEDURE Production.uspDeleteWorkOrder ( @WorkOrderID INT )
AS
SET NOCOUNT ON;
BEGIN TRY
  BEGIN TRANSACTION
  -- Delete rows from the child table, WorkOrderRouting, for the specified work order.
    DELETE FROM Production.WorkOrderRouting
    WHERE WorkOrderID = @WorkOrderID;
  -- Delete the rows from the parent table, WorkOrder, for the specified work order.
    DELETE FROM Production.WorkOrder
    WHERE WorkOrderID = @WorkOrderID;
  COMMIT
END TRY

BEGIN CATCH
  -- Determine if an error occurred.
  IF @@TRANCOUNT > 0
    ROLLBACK

  -- Return the error information.
  DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT;
  SELECT @ErrorMessage = ERROR_MESSAGE(),@ErrorSeverity = ERROR_SEVERITY();
  RAISERROR(@ErrorMessage, @ErrorSeverity, 1);
END CATCH;

GO
EXEC Production.uspDeleteWorkOrder 13;
GO
/* Intentionally generate an error by reversing the order in which rows
   are deleted from the parent and child tables. This change does not
   cause an error when the procedure definition is altered, but produces
   an error when the procedure is executed.
*/
ALTER PROCEDURE Production.uspDeleteWorkOrder ( @WorkOrderID INT )
AS

BEGIN TRY
  BEGIN TRANSACTION
  -- Delete the rows from the parent table, WorkOrder, for the specified work order.
    DELETE FROM Production.WorkOrder
    WHERE WorkOrderID = @WorkOrderID;

  -- Delete rows from the child table, WorkOrderRouting, for the specified work order.
    DELETE FROM Production.WorkOrderRouting
    WHERE WorkOrderID = @WorkOrderID;
  COMMIT TRANSACTION
END TRY

BEGIN CATCH
  -- Determine if an error occurred.
  IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION

  -- Return the error information.
  DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT;
  SELECT @ErrorMessage = ERROR_MESSAGE(),@ErrorSeverity = ERROR_SEVERITY();
  RAISERROR(@ErrorMessage, @ErrorSeverity, 1);
END CATCH;
GO
-- Execute the altered procedure.
EXEC Production.uspDeleteWorkOrder 15;
GO
DROP PROCEDURE Production.uspDeleteWorkOrder;

 

  • 사용자 지정 권한
CREATE PROCEDURE dbo.TruncateMyTable
WITH EXECUTE AS SELF
AS TRUNCATE TABLE MyDB..MyTable;

참조 URL : https://docs.microsoft.com/ko-kr/sql/t-sql/statements/create-procedure-transact-sql?view=sql-server-ver15

 

728x90
반응형

'SQL > SQL Server' 카테고리의 다른 글

[SQL Server] PROCEDURE 성능 개선  (0) 2022.02.14
[SQL Server] 흐름제어(Control-of-Flow)  (0) 2022.02.08
[SQL Server] Functions - 논리 함수  (0) 2022.02.08
[SQL Server] Functions - Cursor 함수  (0) 2022.01.25
[SQL Server] CURSOR  (0) 2022.01.25
Comments