magslabs / laravel-storedproc
A fluent Laravel package for calling stored procedures with support for OUTPUT parameters, pagination, and transactions.
Installs: 144
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/magslabs/laravel-storedproc
Requires
- php: ^8.4|^8.3|^8.2|^8.1|^8.0
- laravel/framework: ^12.0|^11.9|^10.0|^9.0
This package is auto-updated.
Last update: 2025-12-11 02:05:24 UTC
README
Laravel-Storedproc is a fluent wrapper for calling stored procedures in Laravel β because not every query belongs in Eloquent.
In many real-world applications, especially enterprise systems, stored procedures are a key part of the backend. Laravel doesnβt natively support them in an elegant way, so most developers are stuck writing raw DB::select() queries over and over.
This package simplifies that.
Features
- Fluent, chainable syntax for stored procedure calls
- Parameter binding from arrays or Laravel requests
- Optional Laravel-managed transaction support
- Works with MySQL and SQL Server
- Exception-safe with automatic rollback on failure
- NEW: OUTPUT parameter support for SQL Server and MySQL stored procedures
- NEW: Built-in pagination macro for Laravel Collections
- Enhanced logging with dedicated log channel
- Smart result handling (datasets + OUTPUT parameters)
Installation
You can install the package via Composer:
composer require magslabs/laravel-storedproc
The package will automatically register the PaginationServiceProvider to enable the paginate() macro on Laravel Collections.
Basic Usage
use MagsLabs\LaravelStoredProc\StoredProcedure; // Basic stored procedure call with parameters $result = StoredProcedure::stored_procedure('get_user_by_id') ->stored_procedure_params([':id']) ->stored_procedure_values([1]) ->execute() ->stored_procedure_result();
Or if your stored procedure does not require parameters:
$result = StoredProcedure::stored_procedure('get_all_users') ->execute() ->stored_procedure_result();
With Pagination
// Get paginated results $users = StoredProcedure::stored_procedure('get_all_users') ->execute() ->stored_procedure_result() ->paginate(15); // 15 items per page
With OUTPUT Parameters (SQL Server & MySQL)
SQL Server Example:
// SQL Server stored procedure with OUTPUT parameters $result = StoredProcedure::stored_procedure('sp_get_user_stats') ->stored_procedure_params([ ':user_id', '@total_count OUTPUT' ]) ->stored_procedure_values([123]) // Only input values ->stored_procedure_output_params(['@total_count' => 'INT']) ->execute() ->stored_procedure_result(); // Access both dataset and OUTPUT parameters $users = $result->result; // Laravel Collection $totalCount = $result->output; // Scalar value
MySQL Example:
// MySQL stored procedure with OUT parameters $result = StoredProcedure::stored_procedure('get_user_stats') ->stored_procedure_params([ ':user_id', '@total_count' ]) ->stored_procedure_values([123]) // Only input values ->stored_procedure_output_params(['@total_count' => 'INT']) ->execute() ->stored_procedure_result(); // Access both dataset and OUT parameters $users = $result->result; // Laravel Collection $totalCount = $result->output; // Scalar value
The result is returned as a Laravel Collection for easy chaining and manipulation, or as an object with result and output properties when OUTPUT parameters are used.
Parameters & Values
You can pass parameters in multiple formats:
// As an array ->stored_procedure_params([':id']) ->stored_procedure_values([1]); // From a Laravel FormRequest or Request ->stored_procedure_params($request); // will automatically extract keys and format them ->stored_procedure_values([$request->id]);
Transaction Support
Enable Laravel-managed transactions like so:
->with_transaction()
Laravel will automatically commit on success or roll back if the procedure throws an error.
Warning: Use this only if your stored procedure does not manage its own transactions (
BEGIN,COMMIT, etc.).
OUTPUT Parameters (SQL Server & MySQL)
For stored procedures that return OUTPUT/OUT parameters, you can capture them using the stored_procedure_output_params() method:
SQL Server OUTPUT Parameters
// Define OUTPUT parameters in stored_procedure_params with OUTPUT keyword $result = StoredProcedure::stored_procedure('sp_get_user_stats') ->stored_procedure_params([ ':user_id', '@total_users OUTPUT', '@active_users OUTPUT', '@message OUTPUT' ]) ->stored_procedure_values([123]) // Only input values, OUTPUT params are handled automatically ->stored_procedure_output_params([ '@total_users' => 'INT', '@active_users' => 'INT', '@message' => 'VARCHAR(255)' ]) ->execute() ->stored_procedure_result(); // Access the results echo $result->output->total_users; // OUTPUT parameter value echo $result->output->active_users; // OUTPUT parameter value echo $result->output->message; // OUTPUT parameter value echo $result->result; // Regular dataset (if any)
MySQL OUT Parameters
// Define OUT parameters in stored_procedure_params (clean syntax) $result = StoredProcedure::stored_procedure('get_user_stats') ->stored_procedure_params([ ':user_id', '@total_users', '@active_users', '@message' ]) ->stored_procedure_values([123]) // Only input values, OUT params are handled automatically ->stored_procedure_output_params([ '@total_users' => 'INT', '@active_users' => 'INT', '@message' => 'VARCHAR(255)' ]) ->execute() ->stored_procedure_result(); // Access the results echo $result->output->total_users; // OUT parameter value echo $result->output->active_users; // OUT parameter value echo $result->output->message; // OUT parameter value echo $result->result; // Regular dataset (if any)
OUTPUT/OUT Parameter Usage
Step 1: Include OUTPUT/OUT parameters in stored_procedure_params() with the appropriate keyword:
For SQL Server:
->stored_procedure_params([ ':api_service_id', ':statuscode', '@result OUTPUT', '@message OUTPUT' ])
For MySQL:
->stored_procedure_params([ ':api_service_id', ':statuscode', '@result', '@message' ])
π‘ Example from your use case:
->stored_procedure_params([ ':api_service_id', ':statuscode', '@result OUTPUT', ])
Step 2: Define SQL types in stored_procedure_output_params():
// Simple array (defaults to BIT type for SQL Server, INT for MySQL) ->stored_procedure_output_params(['@result', '@status']) // Associative array with specific types ->stored_procedure_output_params([ '@result' => 'INT', '@message' => 'VARCHAR(255)', '@success' => 'BIT', // SQL Server '@success' => 'TINYINT', // MySQL equivalent '@created_date' => 'DATETIME' ])
Step 3: Only provide input values in stored_procedure_values():
->stored_procedure_values([$apiServiceId, $statusCode]) // OUTPUT/OUT params handled automatically
Smart Result Handling
The package automatically detects if OUTPUT/OUT parameters are used and returns an object with both result (dataset) and output (parameters):
$response = StoredProcedure::stored_procedure('sp_complex_operation') ->stored_procedure_output_params(['@status' => 'BIT']) ->execute() ->stored_procedure_result(); // Single OUTPUT parameter β scalar value $status = $response->output; // Direct scalar value // Multiple OUTPUT parameters β object $status = $response->output->status; $message = $response->output->message; // Regular dataset $data = $response->result; // Laravel Collection
Pagination Support
The package includes a built-in pagination macro for Laravel Collections, making it easy to paginate stored procedure results:
// Get paginated results from a stored procedure $users = StoredProcedure::stored_procedure('get_users_paginated') ->stored_procedure_params([':page', ':per_page']) ->stored_procedure_values([1, 15]) ->execute() ->stored_procedure_result() ->paginate(15); // 15 items per page // Use in your controller return view('users.index', compact('users'));
Pagination Features
- Automatic URL handling: Uses current request URL and query parameters
- Laravel pagination: Full compatibility with Laravel's pagination system
- Customizable: Set custom page name and per-page count
- Blade integration: Works seamlessly with Laravel's pagination views
// Custom pagination options $results = $storedProcResult->paginate( $perPage = 20, // Items per page $page = 2, // Current page (optional) $pageName = 'page' // Page parameter name (optional) ); // In your Blade template {{ $results->links() }}
Example: Full Workflow
use MagsLabs\LaravelStoredProc\StoredProcedure; // Basic usage with parameters and transaction $users = StoredProcedure::stored_procedure('get_users_by_role') ->stored_procedure_connection('mysql') // Optional ->stored_procedure_params([':role']) ->stored_procedure_values(['admin']) ->with_transaction() // Optional ->execute() ->stored_procedure_result(); // With pagination $paginatedUsers = StoredProcedure::stored_procedure('get_users_by_role') ->stored_procedure_params([':role']) ->stored_procedure_values(['admin']) ->execute() ->stored_procedure_result() ->paginate(20); // 20 items per page // SQL Server with OUTPUT parameters $stats = StoredProcedure::stored_procedure('sp_get_user_statistics') ->stored_procedure_connection('sqlsrv') // SQL Server connection ->stored_procedure_params([':user_id']) ->stored_procedure_values([123]) ->stored_procedure_output_params([ '@total_posts' => 'INT', '@is_active' => 'BIT', '@last_login' => 'DATETIME' ]) ->execute() ->stored_procedure_result(); // MySQL with OUT parameters $stats = StoredProcedure::stored_procedure('get_user_statistics') ->stored_procedure_connection('mysql') // MySQL connection ->stored_procedure_params([':user_id']) ->stored_procedure_values([123]) ->stored_procedure_output_params([ '@total_posts' => 'INT', '@is_active' => 'TINYINT', '@last_login' => 'DATETIME' ]) ->execute() ->stored_procedure_result(); // Access results $userData = $stats->result; // Dataset as Collection $totalPosts = $stats->output->total_posts; // OUTPUT/OUT parameter $isActive = $stats->output->is_active; // OUTPUT/OUT parameter $lastLogin = $stats->output->last_login; // OUTPUT/OUT parameter // Example via dependency injection in a controller class UserController extends Controller { protected StoredProcedure $storedProc; public function __construct(StoredProcedure $storedProc) { $this->storedProc = $storedProc; } public function index(Request $request) { $users = $this->storedProc->stored_procedure('get_users_by_role') ->stored_procedure_connection('mysql') ->stored_procedure_params([':role']) ->stored_procedure_values([$request->role]) ->with_transaction() ->execute() ->stored_procedure_result() ->paginate(15); return view('users.index', compact('users')); } public function stats($userId) { $stats = $this->storedProc->stored_procedure('sp_get_user_statistics') ->stored_procedure_connection('sqlsrv') ->stored_procedure_params([ ':user_id', '@total_posts OUTPUT' ]) ->stored_procedure_values([$userId]) ->stored_procedure_output_params(['@total_posts' => 'INT']) ->execute() ->stored_procedure_result(); return response()->json([ 'user_data' => $stats->result, 'total_posts' => $stats->output ]); } }
This is useful when you want to inject the instance or reuse it across multiple calls.
Switching Database Connections
Need to call a stored procedure on a different connection/database?
->stored_procedure_connection('your_own_connection_database_name')
This uses Laravelβs connection from config/database.php.
Common Gotchas
-
You must call methods in this order:
stored_procedure()(required)stored_procedure_connection()(optional)stored_procedure_params()(optional, if your proc has parameters)stored_procedure_values()(required if you set params)stored_procedure_output_params()(optional, SQL Server only)with_transaction()(optional)execute()(required)stored_procedure_result()(required)
-
All input parameters must be bound by position in the
stored_procedure_values()array. -
OUTPUT/OUT parameters must be included in
stored_procedure_params()with clean syntax:- SQL Server:
'@result OUTPUT'(OUTPUT keyword required) - MySQL:
'@result'(clean syntax, no OUT keyword needed)
- SQL Server:
-
OUTPUT/OUT parameters are supported on both SQL Server and MySQL databases.
-
When using OUTPUT/OUT parameters, the result will be an object with
resultandoutputproperties. -
Pagination works on the returned Collection, so call
paginate()afterstored_procedure_result(). -
The PaginationServiceProvider is automatically registered, so the
paginate()macro is available immediately.
Compatibility
- PHP: 8.0, 8.1, 8.2, 8.3, 8.4
- Laravel: 9.x, 10.x, 11.x, 12.x
- Databases:
- MySQL (5.7+, 8.0+)
- SQL Server (2016+, 2019+, 2022+)
- Other databases are not officially supported and may not work as expected
Feature Support by Database
| Feature | MySQL | SQL Server |
|---|---|---|
| Basic stored procedures | β | β |
| Parameters & Values | β | β |
| Transactions | β | β |
| OUTPUT/OUT Parameters | β | β |
| Pagination | β | β |
| Logging | β | β |
Advanced Usage
Complex Stored Procedure with Multiple OUTPUT/OUT Parameters
SQL Server Example:
// SQL Server stored procedure with multiple OUTPUT parameters $result = StoredProcedure::stored_procedure('sp_complex_user_operation') ->stored_procedure_connection('sqlsrv') ->stored_procedure_params([ ':user_id', ':action', '@rows_affected OUTPUT', '@success OUTPUT', '@message OUTPUT', '@execution_time OUTPUT' ]) ->stored_procedure_values([123, 'update_profile']) // Only input values ->stored_procedure_output_params([ '@rows_affected' => 'INT', '@success' => 'BIT', '@message' => 'VARCHAR(500)', '@execution_time' => 'FLOAT' ]) ->with_transaction() ->execute() ->stored_procedure_result(); // Access all results $userData = $result->result; // Dataset $rowsAffected = $result->output->rows_affected; // OUTPUT parameter $success = $result->output->success; // OUTPUT parameter $message = $result->output->message; // OUTPUT parameter $executionTime = $result->output->execution_time; // OUTPUT parameter
MySQL Example:
// MySQL stored procedure with multiple OUT parameters $result = StoredProcedure::stored_procedure('complex_user_operation') ->stored_procedure_connection('mysql') ->stored_procedure_params([ ':user_id', ':action', '@rows_affected', '@success', '@message', '@execution_time' ]) ->stored_procedure_values([123, 'update_profile']) // Only input values ->stored_procedure_output_params([ '@rows_affected' => 'INT', '@success' => 'TINYINT', '@message' => 'VARCHAR(500)', '@execution_time' => 'DECIMAL(10,3)' ]) ->with_transaction() ->execute() ->stored_procedure_result(); // Access all results $userData = $result->result; // Dataset $rowsAffected = $result->output->rows_affected; // OUT parameter $success = $result->output->success; // OUT parameter $message = $result->output->message; // OUT parameter $executionTime = $result->output->execution_time; // OUT parameter
Pagination with Custom Options
// Advanced pagination with custom options $users = StoredProcedure::stored_procedure('get_users_with_filters') ->stored_procedure_params([':role', ':status', ':search']) ->stored_procedure_values(['admin', 'active', $searchTerm]) ->execute() ->stored_procedure_result() ->paginate( $perPage = 25, // Items per page $page = $request->page, // Current page $pageName = 'users_page' // Custom page parameter name ); // In Blade template {{ $users->appends(request()->query())->links('custom.pagination') }}
Error Handling and Logging
try { $result = StoredProcedure::stored_procedure('risky_operation') ->stored_procedure_params([':data']) ->stored_procedure_values([$complexData]) ->with_transaction() ->execute() ->stored_procedure_result(); // Success handling return response()->json([ 'success' => true, 'data' => $result ]); } catch (Exception $e) { // Error is automatically logged to the dedicated log channel return response()->json([ 'success' => false, 'message' => 'Operation failed', 'error' => $e->getMessage() ], 500); }
Reusing StoredProcedure Instances
class UserService { protected StoredProcedure $storedProc; public function __construct(StoredProcedure $storedProc) { $this->storedProc = $storedProc; } public function getUserStats($userId) { return $this->storedProc ->stored_procedure('sp_get_user_stats') ->stored_procedure_params([ ':user_id', '@total_posts OUTPUT' ]) ->stored_procedure_values([$userId]) ->stored_procedure_output_params(['@total_posts' => 'INT']) ->execute() ->stored_procedure_result(); } public function updateUserProfile($userId, $data) { return $this->storedProc ->stored_procedure('sp_update_user_profile') ->stored_procedure_params([':user_id', ':name', ':email']) ->stored_procedure_values([$userId, $data['name'], $data['email']]) ->with_transaction() ->execute() ->stored_procedure_result(); } }
Logging Stored Procedure Executions
This package includes built-in logging to help trace and debug stored procedure execution.
Enable a Custom Log File
To log all stored procedure operations into a dedicated log file, add the following channel to your Laravel appβs config/logging.php:
'channels' => [ // other log channels... 'magslabs_laravel_stored_proc' => [ 'driver' => 'single', 'path' => storage_path('logs/magslabs_laravel_stored_proc.log'), 'level' => 'debug', ], ],