簡體   English   中英

MariaDB中生成的列定義中的用戶定義函數?

[英]User Defined Function in generated column definition in MariaDB?

根據文檔,MariaDB 允許在生成的列定義中使用用戶定義的函數https://mariadb.com/kb/en/generated-columns/

User-defined functions (UDFs) are supported in expressions for generated columns. However, MariaDB can't check whether a UDF is deterministic, so it is up to the user to be sure that they do not use non-deterministic UDFs with VIRTUAL generated columns. 

我正在使用 MariaDB 10.3.20 並且我已經創建了一個確定性函數,但是在嘗試創建該字段時,它失敗了。 這是一些示例代碼。

CREATE TABLE `json_virt` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `json_arr` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ;

INSERT INTO json_virt SET json_arr = '["a","b"]' ;
INSERT INTO json_virt SET json_arr = '["c","d"]' ;

DELIMITER //
CREATE OR REPLACE FUNCTION `test`.`json_implode`(`data` TEXT, `sep` TEXT) 
RETURNS text 
CHARSET utf8mb4 
COLLATE utf8mb4_unicode_ci
DETERMINISTIC
SQL SECURITY INVOKER
BEGIN

    DECLARE i INT UNSIGNED DEFAULT 0 ;
    DECLARE v_count INT UNSIGNED DEFAULT JSON_LENGTH(data) ;
    DECLARE v_current_item BLOB DEFAULT NULL ;
    DECLARE v_current_path BLOB DEFAULT NULL ;
    
    DECLARE sep_length INT UNSIGNED DEFAULT CHAR_LENGTH(sep) ;
    
    DECLARE str TEXT DEFAULT '' ;
    
    WHILE i < v_count DO
        SET v_current_path =  CONCAT('$[', i, ']') ;
        
        SET v_current_item = JSON_EXTRACT(data, v_current_path) ;
        SET v_current_item = JSON_UNQUOTE(v_current_item) ;
        
        SET str = CONCAT(str, sep, v_current_item) ;
        
        SET i := i + 1;
    END WHILE;
    
    SET str = SUBSTRING(str, sep_length+1) ;
    
    RETURN str ;
    
END //
DELIMITER ;

SELECT 
json_virt.*,
json_implode(json_virt.json_arr, ', ') AS json_imp
FROM json_virt
;

ALTER TABLE `json_virt` ADD `json_str` TEXT AS (json_implodex(json_arr, ', ')) VIRTUAL ;

ALTER TABLE `json_virt` ADD `json_str1` TEXT AS json_implode('["x","y"]', ', ') VIRTUAL ;

正如您在 SELECT 語句中看到的那樣,json_implode() 函數運行良好,但是當嘗試執行最后兩個 ALTER TABLE 語句時,兩者都失敗了。

我從幾個不同的角度對此感興趣:

  1. 為什么這不起作用?
  2. 什么是適用於生成的列定義的 UDF 示例?
  3. 是否可以在生成的列定義中使用多行或更復雜的代碼?
  4. 有沒有更好的方法來完成我想要做的事情(取一個 JSON 數組的字段並將其內爆,以便每個項目都用逗號分隔為字符串)?

我看到很多開發人員在使用“UDF”時他們的意思是 MySQL/MariaDB 所謂的Stored Function 也就是說,用基於 ANSI SQL 的語言編寫的例程並動態部署在正在運行的 MySQL 服務器上。

而術語 UDF 被 MySQL/MariaDB 用於完全不同的功能。

https://mariadb.com/kb/en/create-function-udf/說:

用戶定義函數 (UDF) 是一種使用新函數擴展 MariaDB 的方法,該函數的工作方式類似於本機(內置)MariaDB 函數,例如 ABS() 或 CONCAT()。

UDF 需要用 C、C++ 或其他使用 C 調用約定的語言編寫,MariaDB 需要動態編譯,並且您的操作系統必須支持動態加載。

請注意,Microsoft SQL Server 將 UDF 用於更像 MySQL/MariaDB 的存儲函數。 這可能是混亂的根源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM