Am creating an application for a transportation company that will store information about their drivers, the cars they drive and to what branches and districts they belong to.
I have a branch table in my database with the following data
branch_id branch_name active district_id
1 Naboa Road 1 76
2 Main Street 1 35
3 Bukoto 1 43
4 Najeera 1 110
and i have created this view to query it
CREATE OR REPLACE VIEW branch_view AS
SELECT b.branch_id,b.branch_name, b.active, d.district_id,
CONCAT(d.district_name, ' ( ', d.district_region,' )') AS location
FROM branch AS b JOIN district AS d
ON b.district_id = d.district_id
Now i have also created a stored procedure that returns either all data from that view or some of the data depending on the arguments given. Here is the stored procedure
DELIMITER $$
CREATE PROCEDURE get_branches(
branch_name_param VARCHAR(30), start_row INT, num_rows INT, OUT sql_param TINYTEXT
)
BEGIN
DECLARE select_clause VARCHAR(300);
DECLARE where_clause VARCHAR(300);
SET select_clause = "SELECT branch_id, branch_name, location FROM branch_view";
IF branch_name_param IS NULL THEN
SET where_clause = " WHERE active ";
ELSE
SET branch_name_param = TRIM( BOTH ' ' FROM branch_name_param );
SET where_clause = CONCAT( " WHERE branch_name LIKE '%", branch_name_param ,"%' " );
END IF;
SET select_clause = CONCAT( select_clause, where_clause );
-- a small tweak to get total number of rows before limit clause is used
SET sql_param = CONCAT( "SELECT COUNT(*) AS total_rows FROM branch_view", where_clause );
SET select_clause = CONCAT( select_clause, " ORDER BY branch_name " );
IF start_row IS NOT NULL THEN
SET select_clause = CONCAT( select_clause, " LIMIT ", start_row, ", ", num_rows );
END IF;
SET @dynamic_sql = select_clause;
PREPARE get_branches_stmt FROM @dynamic_sql;
EXECUTE get_branches_stmt;
DEALLOCATE PREPARE get_branches_stmt;
END$$
DELIMITER ;
The thing about this stored procedure though is that i get an sql statement through the fourth argument that i pass it, which i can use to execute later in my php application to find out how many rows would have been returned would there have not been a limit clause applied. Before you can kill and say why didn't i use SQL_CALC_FOUND_ROWS and FOUND_ROWS() information function to help me return information needed, i actually did that and found_rows function kept returning an incorrect total number of rows hence the above solution. Here is a my php code in case you need some closure, it takes a pdo connection object as it's first parameter, and the next parameters are to used in pagination on the application side that is the start_row parameter indicating which row to start with and num_rows parameter indicates how many rows to return and finally the where array parameter which contain key value pairs of my search in this case the branch name
/* Function to get all branches */
function get_branches( PDO $conn, $start_row, $num_rows, array $where = null ) {
$sql = "CALL get_branches( :branch_name, :start_row, :num_rows, @sql_p )";
try {
$st = $conn->prepare($sql);
$st->bindParam( ':branch_name', $where['name'], PDO::PARAM_STR | PDO::PARAM_NULL );
$st->bindParam( ':start_row', $start_row, PDO::PARAM_INT | PDO::PARAM_NULL );
$st->bindParam( ':num_rows', $num_rows, PDO::PARAM_INT | PDO::PARAM_NULL );
$st->execute();
$branches = array();
foreach ( $st->fetchAll(PDO::FETCH_ASSOC) as $row ) {
$branches[] = $row;
}
$st = null;
// Get sql query returned by stored procedure
$st = $conn->query("SELECT @sql_p AS `sql`");
$row = $st->fetch(PDO::FETCH_ASSOC);
// Execute sql query returned by stored procedure
$st = $conn->query($row['sql']);
$total = $st->fetch(PDO::FETCH_ASSOC);
$st = null;
return array( $branches, $total['total_rows'] );
} catch (PDOException $e) {
die( "<p>Query failed: " . $e->getMessage() . "</p>" );
}
}
What i wanted to find out is, will this affect the performance of the database and my application and how can i improve it, if need be? Thank you