这段代码似乎是MySQL的动态SQL,可以通过以下方式进行优化:
1. 可以使用`INSERT INTO ... SELECT ...`语句的简写方式,避免使用动态SQL。
2. 可以使用`GROUP_CONCAT`函数的`SEPARATOR`参数避免在`SELECT`语句中使用`UNION ALL`连接查询结果。
3. 可以在动态SQL中使用参数来引用表名,以提高代码的可重用性。
下面是一个可能的优化版本:
```
SET @cols_sql = (
SELECT GROUP_CONCAT(
CONCAT(
'JSON_OBJECT(',
' ''', column_name, ''', OLD.', column_name, ',',
' ''', column_name, ''', NEW.', column_name,
')'
)
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = @target_table
);
SET @sql = CONCAT(
'INSERT INTO log (table_name, action_type, old_data, new_data) ',
'SELECT ''', @target_table, ''', ''UPDATE'', ',
'JSON_OBJECTAGG(column_name, old_column_value), ',
'JSON_OBJECTAGG(column_name, new_column_value) ',
'FROM (',
'SELECT column_name, old_column_value, new_column_value ',
'FROM JSON_TABLE(',
' JSON_OBJECT(',
' ''old_data'', JSON_ARRAY(', @cols_sql, '),',
' ''new_data'', JSON_ARRAY(', @cols_sql, ')',
' ),',
' ''$[*]'',',
' COLUMNS(',
' column_name VARCHAR(255) PATH ''$.''',
' old_column_value JSON PATH ''$.''',
' new_column_value JSON PATH ''$.''',
' )',
') AS t',
') AS data',
'GROUP BY NULL'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
```
这个版本首先将查询列名和值的部分存储在`@cols_sql`变量中,然后使用`JSON_ARRAY`函数将它们包装成数组。最后,在`JSON_TABLE`函数中引用这些数组,并将查询结果按列名称和旧/新值分组。