本节包含一些示例,说明在各种情况下使用 JavaScript 程序的多个不同方面。
以下示例演示了在不同情况下使用 JavaScript 存储程序的多个不同方面。
mysql> CREATE FUNCTION gcd(a INT, b INT)
-> RETURNS INT NO SQL LANGUAGE JAVASCRIPT AS
-> $mle$
$> let x = Math.abs(a)
$> let y = Math.abs(b)
$> while(y) {
$> var t = y
$> y = x % y
$> x = t
$> }
$> return x
$> $mle$
-> ;
Query OK, 0 rows affected (0.01 sec)
以下示例演示了如何使用 JavaScript 存储函数和表列值。 首先,我们定义一个存储函数 gcd()
,它用于查找两个整数的最大公约数,如下所示
mysql> SELECT gcd(75, 220), gcd(75, 225);
+--------------+--------------+
| gcd(75, 220) | gcd(75, 225) |
+--------------+--------------+
| 5 | 75 |
+--------------+--------------+
1 row in set (0.00 sec)
我们可以像这样测试存储函数:
mysql> CREATE TABLE t1 (c1 INT, c2 INT);
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO t1 VALUES ROW(12,70), ROW(17,3), ROW(81,9);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> TABLE t1;
+------+------+
| c1 | c2 |
+------+------+
| 12 | 70 |
| 17 | 3 |
| 81 | 9 |
+------+------+
3 rows in set (0.00 sec)
接下来,我们创建一个表 t1
,它有两个整型列,并用几行数据填充它,如下所示
mysql> SELECT c1, c2, gcd(c1, c2) AS G
-> FROM t1
-> WHERE gcd(c1, c2) > 1
-> ORDER BY gcd(c1, c2);
+----+----+---+
| c1 | c2 | G |
+----+----+---+
| 12 | 70 | 2 |
| 81 | 9 | 9 |
+----+----+---+
8 rows in set (0.01 sec)
现在,我们可以从 t1
中进行选择,使用 gcd()
函数,并将列值作为函数调用中的参数值,如下所示
mysql> SELECT gcd(500.3, 600), gcd(500.5, 600);
+-----------------+-----------------+
| gcd(500.3, 600) | gcd(500.5, 600) |
+-----------------+-----------------+
| 100 | 3 |
+-----------------+-----------------+
1 row in set (0.01 sec)
如果参数值不是指定类型,则在可能的情况下会将其强制转换为正确的类型,如下所示
将浮点数四舍五入为整数是通过使用 Math.round()
完成的;在本例中,500.3 向下舍入为 500,但 500.5 向上舍入为 501。
mysql> CREATE PROCEDURE d1 (OUT res VARCHAR(25))
-> LANGUAGE JAVASCRIPT
-> AS
-> $$
$> let d = new Date().toString()
$> res = d
$> $$
-> ;
Query OK, 0 rows affected (0.01 sec)
接下来,我们使用一个 CREATE PROCEDURE
语句创建一个简单的 JavaScript 存储过程,该语句包含一个 OUT
参数,用于将当前日期和时间以人类可读的格式传递给用户变量。 由于我们不确定此表示形式的长度,因此我们使用 VARCHAR(25) 作为参数的类型。
mysql> SELECT @today;
+----------------------+
| @today |
+----------------------+
| NULL |
+----------------------+
1 row in set (0.01 sec)
mysql> CALL d1(@today);
ERROR 1406 (22001): Data too long for column 'res' at row 1
现在,我们可以测试存储过程,首先验证用户变量 @today 是否尚未设置任何值,如下所示
mysql> DROP PROCEDURE d1;
Query OK, 0 rows affected (0.02 sec)
mysql> CREATE PROCEDURE d1 (OUT res VARCHAR(50))
-> LANGUAGE JAVASCRIPT
-> AS
-> $$
$> let d = new Date().toString()
$> res = d
$> $$
-> ;
Query OK, 0 rows affected (0.01 sec)
该过程在语法上是有效的,但 INOUT
参数 (res
) 的数据类型不允许使用足够数量的字符;存储程序不会截断该值,而是拒绝它。 由于无法就地更改过程代码,因此我们必须删除该过程并重新创建它;这次,我们尝试将 INOUT
参数指定的长度加倍
mysql> SELECT @today;
+----------------------+
| @today |
+----------------------+
| NULL |
+----------------------+
1 row in set (0.01 sec)
现在,我们可以重复测试,如下所示
mysql> CALL d1(@today);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @today;
+-----------------------------------------+
| @today |
+-----------------------------------------+
| Mon Oct 30 2023 20:47:29 GMT+0000 (GMT) |
+-----------------------------------------+
1 row in set (0.00 sec)
注意
运行此示例获得的值可能与这里显示的值有所不同,因为日期的精确表示取决于您的系统区域设置,以及可能的其他设置。 有关更多信息,请参阅 JavaScript Date
对象的文档。
下一个示例演示了如何在触发器中使用 JavaScript 存储函数。
mysql> CREATE TABLE t2 (c1 INT, c2 INT, c3 INT);
Query OK, 0 rows affected (0.04 sec)
首先,我们创建一个表 t2
,它包含三个整型列,如下所示
mysql> delimiter //
mysql> CREATE TRIGGER jst BEFORE INSERT ON t2
-> FOR EACH ROW
-> BEGIN
-> SET NEW.c2 = js_pow(NEW.c1, 2);
-> SET NEW.c3 = js_pow(NEW.c1, 3);
-> END;
-> //
Query OK, 0 rows affected (0.02 sec)
mysql> delimiter ;
mysql>
现在,我们可以为此表创建一个触发器。 这必须使用 CREATE TRIGGER
语句以通常的方式使用 SQL 编写(请参阅 第 27.4 节“使用触发器”),但它可以使用用 JavaScript 编写的存储例程,例如本节前面显示的 js_pow()
函数。
mysql> INSERT INTO t2
-> VALUES
-> ROW(1, NULL, NULL),
-> ROW(2.49, NULL, NULL),
-> ROW(-3, NULL, NULL),
-> ROW(4.725, NULL, NULL);
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
此触发器在将行插入 t2
时生效,它获取插入到第一列的值,并将该值的平方插入到第二列,并将该值的立方插入到第三列。 我们通过将几行插入到表中来测试触发器;由于唯一没有被丢弃的值是我们为 c1
列提供的那个值,因此我们可以为其余两个列简单地使用 NULL
,如下所示
mysql> TABLE t2;
+------+------+------+
| c1 | c2 | c3 |
+------+------+------+
| 1 | 1 | 1 |
| 2 | 4 | 8 |
| -3 | 9 | -27 |
| 5 | 25 | 125 |
+------+------+------+
4 rows in set (0.00 sec)