首頁 > 軟體

Mysql中自定義函數的建立和執行方式

2023-03-11 06:02:32

Mysql自定義函數的建立和執行

假設students表中包含id和name兩個欄位,建立一個函數,函數的作用是根據id查詢name

1.建立表,插入資料

create table students(id int,name varchar(100));
insert into students(id,name) values(1,'annie'),(2,'bell'),(3,'danny');

2.建立函數

DELIMITER //
create function find_student(id int) returns varchar(100)
READS SQL DATA
begin
    declare sname varchar(100) default '';
    select students.name into sname from students where students.id=id;
    return sname;
end //
DELIMITER ;

需要注意的事項:

1)使用DELIMITER//修改分隔符

mysql的預設語句結束符號是分號,當mysql遇到分號時就自動執行當前語句。因為函數定義時包含多條sql語句,所以使用DELIMITER //先將分隔符設定為//,等函數建立語句完成後,再將分隔符改回分號即可。

2)READS SQL DATA

之前我沒寫這句話,但是建立時mysql報錯,提示Error Code: 1418. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)

上網查了一下,意思是沒有宣告mysql函數的型別:

mysql開啟了bin-log, 我們就必須指定我們的函數是否是哪種型別:

  • 1 DETERMINISTIC 不確定的
  • 2 NO SQL 沒有SQl語句,當然也不會修改資料
  • 3 READS SQL DATA 只是讀取資料,當然也不會修改資料
  • 4 MODIFIES SQL DATA 要修改資料
  • 5 CONTAINS SQL 包含了SQL語句
  • 所以我加上了READS SQL DATA

3)使用區域性變數

變數定義:我這裡使用declare sname varchar(100) default ‘’;定義了區域性變數sname,

變數使用:

可以使用select students.name into sname from students where students.id=id;為變數賦值

也可以直接使用set語句來賦值,如set sname=‘test’

3.執行函數:select 函數名(引數值);

select find_student(3);

Mysql自定義函數建立失敗問題

案例

目前在專案中,執行建立mysql的函數出錯,

mysql 建立函數出錯資訊如下:

Caused by: java.sql.SQLException: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3976)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3912)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:871)
    at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:2373)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2739)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2482)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2440)
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:845)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745)
    ... 35 more

這是因為有一個安全引數沒有開啟,log_bin_trust_function_creators 預設為0,是不允許function的同步的,開啟這個引數,就可以建立成功了。

檢視是否開啟:

show variables like '%func%';
+---------------------------------+-------+ 
| Variable_name     | Value | 
+---------------------------------+-------+ 
| log_bin_trust_function_creators | ON | 
+---------------------------------+-------+ 
1 row in set (0.00 sec) 

為on則是開啟了

set global log_bin_trust_function_creators = 1;

可以通過這個命令設定,但是MySQL重啟後就失效了。

所有最後是通過修改MySQL資料庫的組態檔

在組態檔/etc/my.cnf的[mysqld]設定log_bin_trust_function_creators=1

修改完後重啟MySQL。

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com