Я пишу простую хранимую процедуру MySQL:
DELIMITER $
DROP PROCEDURE IF EXISTS GetUserByCaseId $
CREATE DEFINER = 'DEV_Organization'@'localhost'
PROCEDURE GetUserByCaseId (IN searchedForId VARCHAR(8))
LANGUAGE SQL NOT DETERMINISTIC READS SQL DATA SQL SECURITY DEFINER
BEGIN
SELECT
CaseIdAuthenticator.sid AS sid,
CaseIdAuthenticator.caseId AS caseId,
User.firstName AS firstName,
User.lastName AS lastName,
User.position AS position,
User.email AS email
FROM CaseIdAuthenticator
INNER JOIN User ON User.sid = CaseIdAuthenticator.sid
WHERE CaseIdAuthenticator.caseId = searchedForId
LIMIT 1;
END
$
Это работает:
mysql> CALL DEV_Organization.GetUserByCaseId("bro4");
+------+--------+-----------+----------+----------+----------------------+
| sid | caseId | firstName | lastName | position | email |
+------+--------+-----------+----------+----------+----------------------+
| 3773 | bro4 | Billy | O'Neal | | billy.oneal@case.edu |
+------+--------+-----------+----------+----------+----------------------+
1 row in set (0.00 sec)
, но, к сожалению, позволяет клиенту сойти с рук с передачей NULL:
mysql> CALL DEV_Organization.GetUserByCaseId(NULL);
Empty set (0.00 sec)
Я бы предпочел вместо этого выбросить ошибку.Как я могу это сделать?(Простая установка типа VARCHAR(8) NOT NULL
заставляет MySQL выдавать ошибку при создании процедуры ...)
РЕДАКТИРОВАТЬ: Комментаторы запросили мое обоснование.Я работаю с API базы данных в PHP-земле, которая выглядит следующим образом:
/**
* Inside function which is used to implement other procedure functions.
*
* @param string $suffix The database schema suffix.
* @param string $procedure The name of the procedure that should be executed.
* @param array $arguments A set of arguments which should be passed to the stored procedure.
* @return PDOStatement The PDOStatement generated by sending the query to the MySQL Server.
*/
private function ProcedureInner($suffix, $procedure, $arguments = array())
{
$suffix = (string)$suffix;
$procedure = (string)$procedure;
$questionMarks = '';
$args = count($arguments);
if ($args > 0)
{
$questionMarks = '?';
for ($idx = 1; $idx < $args; ++$idx)
{
$questionMarks .= ', ?';
}
}
$stmt = $this->pdo->prepare("CALL `{$this->mode}_{$suffix}`.`{$procedure}` ({$questionMarks})");
$stmt->execute($arguments);
return $stmt;
}
/**
* Executes a stored procedure which returns a single value in a single row.
*
* @param string $schema The suffix of the schema where the procedure is located.
* @param string $procedure The name of the procedure to call.
* @param array $arguments Arguments to supply to the procedure, if any.
* @return mixed The content of the value.
*/
public function ProcedureScalar($schema, $procedure, $arguments = array())
{
$result = $this->ProcedureInner($schema, $procedure, $arguments);
$answer = $result->fetchColumn(0);
$result->closeCursor();
return $answer;
}
обратите внимание, как легко клиенту забыть передать аргумент в массиве arguments.Однако, поскольку это низкоуровневая часть абстракции базы данных, я не хочу помещать здесь ограничения для поиска конкретных аргументов.