我在mysql 8.0中定义了一个存储函数: 但是每当我尝试使用下面提到的调用来调用该函数时,它都会抛出一条错误消息,#1582 - 调用本机函数“JSON_OBJECT”时参数计数不正确。如何解决?此外,如何使用带有动态 where 子句的准备语句定义选择查询,其中 where 条件的键和值都是动态的?
BEGIN
DECLARE ssoId VARCHAR(255) DEFAULT NULL;
DECLARE emailId VARCHAR(255) DEFAULT NULL;
DECLARE instructorId VARCHAR(255) DEFAULT NULL;
DECLARE firstName VARCHAR(255) DEFAULT NULL;
DECLARE lastName VARCHAR(255) DEFAULT NULL;
DECLARE createdAt TIMESTAMP DEFAULT NULL;
DECLARE updatedAt TIMESTAMP DEFAULT NULL;
DECLARE storedUser JSON DEFAULT NULL;
SET ssoId = JSON_EXTRACT(user,'$.ssoId');
SET emailId = JSON_EXTRACT(user,'$.email');
SET firstName = JSON_EXTRACT(user,'$.firstName');
SET lastName = JSON_EXTRACT(user,'$.lastName');
SET createdAt = JSON_EXTRACT(user,'$.createdAt');
SET updatedAt = JSON_EXTRACT(user,'$.updatedAt');
IF JSON_EXTRACT(user,'$.instructorId') IS NOT NULL THEN
SET instructorId = JSON_EXTRACT(user,'$.instructorId');
ELSE
SET instructorId = JSON_EXTRACT(user,'$.instructorStudentId');
END IF;
IF ssoId IS NOT NULL THEN
SELECT JSON_OBJECT(
"id", id,
"sso_id", sso_id,
"email", email,
"instructor_id", instructor_id,
"first_name", first_name,
"last_name", last_name,
"source_created_at", source_created_at,
"source_updated_at", source_updated_at)
INTO storedUser FROM datahub.users WHERE sso_id = ssoId;
ELSEIF instructorId IS NOT NULL THEN
SELECT JSON_OBJECT(
"id", id,
"sso_id", sso_id,
"email", email,
"instructor_id", instructor_id,
"first_name", first_name,
"last_name", last_name,
"source_created_at", source_created_at,
"source_updated_at", source_updated_at)
INTO storedUser FROM datahub.users WHERE instructor_id = instructorId;
ELSEIF emailId IS NOT NULL THEN
SELECT JSON_OBJECT(
"id", id,
"sso_id", sso_id,
"email", email,
"instructor_id", instructor_id,
"first_name", first_name,
"last_name", last_name,
"source_created_at", source_created_at,
"source_updated_at", source_updated_at)
INTO storedUser FROM datahub.users WHERE email = emailId;
END IF;
RETURN -1;
END;
我测试了你的功能,但我没有看到你描述的错误。
我确实看到了另一个问题。
JSON_EXTRACT() 的结果是一个 JSON 标量,而不是字符串。所以你会在它周围看到双引号,就像任何 JSON 标量字符串一样。
mysql> set @j = '{"key": "value"}';
mysql> select json_extract(@j, '$.key');
+---------------------------+
| json_extract(@j, '$.key') |
+---------------------------+
| "value" |
+---------------------------+
这自然不会匹配您表中的任何值,因为我假设它们不包含双引号字符。
您可以使用 JSON_UNQUOTE() 获取字符串值:
mysql> select json_unquote(json_extract(@j, '$.key'));
+-----------------------------------------+
| json_unquote(json_extract(@j, '$.key')) |
+-----------------------------------------+
| value |
+-----------------------------------------+
您必须在提取 JSON 字段的每一行上执行此操作。
您询问了如何运行动态 SQL 查询。您不能在 MySQL 存储函数中执行此操作,因为存储函数可能会从准备好的查询本身执行。
https://dev.mysql.com/doc/refman/8.0/en/stored-program-restrictions.html 说:
SQL 预处理语句(
、PREPARE
、EXECUTE
)可以用在存储过程中,但不能用在存储函数或触发器中。因此,存储函数和触发器不能使用动态 SQL(您将语句构造为字符串然后执行它们)。DEALLOCATE PREPARE