不同的数据库创建存储过程或函数的方式略有不同。对于HSQLDB来说,我们可以像下面那样创建函数用于返回库表中所有作者。sql.execute """
CREATE FUNCTION SELECT_AUTHOR_INITIALS()
RETURNS TABLE (firstInitial VARCHAR(1), lastInitial VARCHAR(1))
READS SQL DATA
RETURN TABLE (
SELECT LEFT(Author.firstname, 1) as firstInitial, LEFT(Author.lastname, 1) as lastInitial
FROM Author
)
"""
我们可以使用SQL的CALL语句执行函数获取数据def result = []
sql.eachRow('CALL SELECT_AUTHOR_INITIALS()') {
result <
}
assert result == ['DK', 'JS', 'GL']
下面的代码创建另外一个函数,该函数接受一个lastname作为参数。
创建带有参数的函数:sql.execute """
CREATE FUNCTION FULL_NAME (p_lastname VARCHAR(64))
RETURNS VARCHAR(100)
READS SQL DATA
BEGIN ATOMIC
DECLARE ans VARCHAR(100);
SELECT CONCAT(firstname, ' ', lastname) INTO ans
FROM Author WHERE lastname = p_lastname;
RETURN ans;
END
"""
可以使用占位符指定函数的参数和指定函数结果的存放位置:
使用带有参数的函数://第一个问号指定结果的位置,第二个问号指定参数的位置
def result = sql.firstRow("{? = call FULL_NAME(?)}", ['Koenig'])
assert result[0] == 'Dierk Koenig'
最后,创建一个带有输入和输出参数的存储过程sql.execute """
CREATE PROCEDURE CONCAT_NAME (OUT fullname VARCHAR(100),
IN first VARCHAR(50), IN last VARCHAR(50))
BEGIN ATOMIC
SET fullname = CONCAT(first, ' ', last);
END
"""
使用CONCAT_NAME存放存储过程参数,我们使用一个比较特别的调用方式。任何的输入参数都被看做是存储过程的调用参数。对于输出参数,可以像下面的方式输出:sql.call("{call CONCAT_NAME(?, ?, ?)}", [Sql.VARCHAR, 'Dierk', 'Koenig']) {
fullname -> assert fullname == 'Dierk Koenig'
}