SQLServerでストアドプロシージャを作成するには、CREATE PROCEDURE文を使用します。基本的な構文は以下のとおりです:
CREATE PROCEDURE プロシージャ名
@パラメータ1 データ型,
@パラメータ2 データ型
AS
BEGIN
-- SQLステートメント
END
具体的な例を見てみましょう。顧客情報を取得するシンプルなストアドプロシージャを作成します:
CREATE PROCEDURE GetCustomerInfo
@CustomerID INT
AS
BEGIN
SELECT CustomerName, Email, Phone
FROM Customers
WHERE CustomerID = @CustomerID
END
このプロシージャは、指定された顧客IDに基づいて顧客情報を取得します。
作成したストアドプロシージャを実行するには、EXEC(またはEXECUTE)コマンドを使用します。先ほど作成したGetCustomerInfoプロシージャを実行する例を見てみましょう:
EXEC GetCustomerInfo @CustomerID = 1001
パラメータを複数持つストアドプロシージャの場合は、以下のように記述します:
CREATE PROCEDURE UpdateCustomerInfo
@CustomerID INT,
@NewEmail VARCHAR(100),
@NewPhone VARCHAR(20)
AS
BEGIN
UPDATE Customers
SET Email = @NewEmail, Phone = @NewPhone
WHERE CustomerID = @CustomerID
END
-- 実行例
EXEC UpdateCustomerInfo @CustomerID = 1001, @NewEmail = 'new@example.com', @NewPhone = '090-1234-5678'
パラメータにはデフォルト値を設定することもできます:
CREATE PROCEDURE GetCustomersByCity
@City VARCHAR(50) = 'Tokyo'
AS
BEGIN
SELECT CustomerName, Email
FROM Customers
WHERE City = @City
END
-- デフォルト値を使用
EXEC GetCustomersByCity
-- 特定の都市を指定
EXEC GetCustomersByCity @City = 'Osaka'
ストアドプロシージャを効率的に使用するためには、パフォーマンスの最適化が重要です。以下にいくつかのテクニックを紹介します:
CREATE INDEX IX_Customers_City ON Customers(City)
EXEC GetCustomersByCity @City = 'Osaka' WITH RECOMPILE
CREATE PROCEDURE InsertCustomer
@Name VARCHAR(100),
@Email VARCHAR(100)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Customers (Name, Email) VALUES (@Name, @Email)
END
ストアドプロシージャを使用することで、データベースのセキュリティを強化できます。以下に主要なポイントを挙げます:
CREATE PROCEDURE UpdateSensitiveData
WITH EXECUTE AS 'DataAdminUser'
AS
BEGIN
-- 機密データの更新処理
END
CREATE PROCEDURE SecureProc
WITH ENCRYPTION
AS
BEGIN
-- 機密性の高い処理
END
ストアドプロシージャは単純なデータ取得や更新だけでなく、複雑なビジネスロジックの実装にも活用できます。以下に、注文処理を行うストアドプロシージャの例を示します:
CREATE PROCEDURE ProcessOrder
@CustomerID INT,
@ProductID INT,
@Quantity INT,
@OrderID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
DECLARE @StockQuantity INT, @UnitPrice DECIMAL(10,2)
-- 在庫チェック
SELECT @StockQuantity = StockQuantity, @UnitPrice = UnitPrice
FROM Products
WHERE ProductID = @ProductID
IF @StockQuantity < @Quantity
BEGIN
RAISERROR('在庫が不足しています', 16, 1)
RETURN
END
BEGIN TRANSACTION
-- 注文の作成
INSERT INTO Orders (CustomerID, OrderDate, TotalAmount)
VALUES (@CustomerID, GETDATE(), @UnitPrice * @Quantity)
SET @OrderID = SCOPE_IDENTITY()
-- 注文詳細の作成
INSERT INTO OrderDetails (OrderID, ProductID, Quantity, UnitPrice)
VALUES (@OrderID, @ProductID, @Quantity, @UnitPrice)
-- 在庫の更新
UPDATE Products
SET StockQuantity = StockQuantity - @Quantity
WHERE ProductID = @ProductID
COMMIT TRANSACTION
END
このストアドプロシージャは以下の処理を行います:
また、トランザクション処理を使用して、すべての操作が成功した場合にのみコミットされるようにしています。
このプロシージャの使用例:
DECLARE @NewOrderID INT
EXEC ProcessOrder @CustomerID = 1001, @ProductID = 5001, @Quantity = 2, @OrderID = @NewOrderID OUTPUT
PRINT '新しい注文ID: ' + CAST(@NewOrderID AS VARCHAR)
このように、ストアドプロシージャを使用することで、複雑なビジネスロジックをデータベース層で一元管理できます。これにより、アプリケーション層のコードを簡素化し、データの整合性を保ちやすくなります。
ストアドプロシージャの開発や運用中に問題が発生した場合、効果的なデバッグとトラブルシューティングが重要です。以下にいくつかの手法を紹介します:
CREATE PROCEDURE DebugExample
@Param1 INT
AS
BEGIN
PRINT 'パラメータ値: ' + CAST(@Param1 AS VARCHAR)
-- 処理
PRINT '処理完了'
END
CREATE PROCEDURE ErrorHandlingExample
AS
BEGIN
BEGIN TRY
-- エラーが発生する可能性のある処理
SELECT 1/0
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_MESSAGE() AS ErrorMessage,
ERROR_LINE() AS ErrorLine
END CATCH
END
CREATE PROCEDURE StepByStepDebug
AS
BEGIN
CREATE TABLE #TempResults (ID INT, Value VARCHAR(50))
INSERT INTO #TempResults
SELECT ID, Name FROM SomeTable WHERE Condition = 1
-- 中間結果の確認
SELECT * FROM #TempResults
-- さらに処理を続ける
UPDATE #TempResults SET Value = 'Updated' WHERE ID > 100
-- 最終結果の確認
SELECT * FROM #TempResults
DROP TABLE #TempResults
END
sys.dm_exec_procedure_stats
などのシステムビューを使用して、プロシージャの実行統計を確認できます。
SELECT TOP 10
d.object_id, d.database_id, OBJECT_NAME(object_id, database_id) AS [プロシージャ名],
d.cached_time, d.last_execution_time, d.total_elapsed_time,
d.total_elapsed_time/d.execution_count AS [平均実行時間],
d.execution_count
FROM sys.dm_exec_procedure_stats d
ORDER BY [平均実行時間] DESC
これらのテクニックを組み合わせることで、ストアドプロシージャの問題を効果的に特定し、解決することができます。
SQLServerの最新バージョンに対応したストアドプロシージャのベストプラクティスと、使用時の注意点をいくつか紹介します:
CREATE PROCEDURE ProcessJSONData
@JSONData NVARCHAR(MAX)
AS
BEGIN
SELECT *
FROM OPENJSON(@JSONData)
WITH (
Name NVARCHAR(100) '$.name',
Age INT '$.age'
)
END