如果 2308 與 '2308',一個是數字,一個是字串,這兩個相比較,是否相等?
測試結果是:在mysql 裡面,是相等的。
本網誌記錄網站設計的一些內容筆記。 網站設計需要整合很多工具與概念。 我畢業自淡江電子計算機科學學系,算是科班出身。但我們那個年代(50年代,唉!LKK了!),網路還只是剛開始,相關的技術都是出社會以後陸續接觸學習。 網站的建立與設計,牽涉的範圍真的很廣泛。 網站的目地是甚麼?銷售網頁、電子購物、廣告、社群經營、互動、教學、客戶服務、網站應用程式、...... 需要整合的人才,程式設計師、資料庫管理師、網頁美編、文字編輯、多媒體製作等等。 這裡將記錄一個LKK對網站系統重新學習與複習,還有教學使用的一些資料。
https://www.geeksforgeeks.org/difference-between-identifying-and-non-identifying-relationships/
https://matthung0807.blogspot.com/2018/03/er-model-identifying-relationships-non.html
結論:簡單說:
實的關聯 (identifying relationships):一個是母表 vs 子表,外部關聯鍵 foreign key的值,是不能為NULL,一定要有值!
虛的關聯 (non-identifying relationships):foreign key 可以為 NULL
要記得 SQL 如果有 SUM等函數,要加上 IFNULL(sum(num_field), 0)
否則,就會產生 NULL 的可能,導致後面如果有再拿資料處理的時候,就會發生錯誤。
記得喔!
SELECT IFNULL(sum(c_profit),0) as v_sum_profit, count(*) as v_count, IFNULL(sum(c_profit)/count(*),0) as v_avg
FROM max_orders
WHERE date(updated_at_in_ms)='2023-07-08'
and state='done'
and side='sell';
MySQL資料庫,現在新的資料庫,最好都直接用 utf8mb4 了!
collate 用 utf8mb4_unicode_ci
當建立一個新的專案的時候,要先留意把這個資料庫的字元設定好,全部一致,這樣可以減少很多後面的一大堆麻煩!
以下提供的是一般在大量倒資料時,會用到的,請僅慎使用!!
================================================================
IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue') THEN
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
ELSE
INSERT INTO Table1 VALUES (...)
END IF;
================================================================
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF @@ROWCOUNT=0
INSERT INTO Table1 VALUES (...)
MySQL 產生 sql_mode=only_full_group_by
這是我做一個 View 裡面有 GROUP BY
在我的 Local MySQL沒有問題,上傳到 Server 就有問題了。
這一定就是版本不同的緣故。
於是網路搜尋:
https://www.gushiciku.cn/pl/pFxA/zh-tw
https://www.twle.cn/c/yufei/mysqlfav/mysqlfav-basic-sql_mode2.html
修改了 Server 上面 /etc/my.cnf
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
加上這段,重新啟動MySQL 就好了!
IF not exists (SELECT * FROM funit WHERE fu_id = in_myfu_id) THEN
ROLLBACK;
SET out_ret_code = CONCAT("ERROR: 操作人經營單位不存在資料庫中!",in_myfu_id);
CALL system_log(out_ret_code);
LEAVE proc_label;
END IF;
ERROR 1292 (22007): Truncated incorrect DOUBLE value
這個 Warning產生了。
經查是我這個個案是資料型態不一致造成的。
程式裡面,做了一個變數
DECLARE v_variable VARCHAR(100);
SET v_variable = IFNULL((SELECT abc FROM table WHERE id = 'aaa'),0);
IF (v_variable = 0) THEN
.........................
ELSE
...................
END IF;
v_variable 資料型態是文字,將他設為數字 0!
後面又拿文字來跟數值比較!所以產生了這個警告!
修改一下,就好了。
DECLARE v_variable VARCHAR(100);
SET v_variable = (SELECT abc FROM table WHERE id = 'aaa');
IF (v_variable IS NULL) THEN
.........................
ELSE
...................
END IF;
一、資料庫部分
二、程式部分
使用英文名稱
Comment 盡量不要使用
先處理參數正確性檢查
先處理不用寫資料庫的運算
最後要寫資料庫時,再
START TRANSACTION
COMMIT;
ROLLBACK;*/
START TRANSACTION;
/*
資料庫更新動作
*/
SET out_ret_code = "SUCCESS";
COMMIT;
END;
IF NOT EXISTS(SELECT * FROM People) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'OMG PANIC';
END IF;
DECLARE v_exit INT DEFAULT FALSE;
DECLARE cur_table CURSOR FOR
SELECT field1, field2 FROM table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_exit = TRUE;
OPEN cur_table;
my_fetch: LOOP
FETCH cur_table
INTO v_field1, v_field2;
IF v_exit THEN
LEAVE my_fetch;
END IF;
<process code here...>
END LOOP my_fetch;
CLOSE cur_table;
<?php
$mysqli = new mysqli("localhost","my_user","my_password","my_db");
if ($mysqli -> connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli -> connect_error;
exit();
}
// Escape special characters, if any
$firstname = $mysqli -> real_escape_string($_POST['firstname']);
$lastname = $mysqli -> real_escape_string($_POST['lastname']);
$age = $mysqli -> real_escape_string($_POST['age']);
$sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$firstname', '$lastname', '$age')";
if (!$mysqli -> query($sql)) {
printf("%d Row inserted.\n", $mysqli->affected_rows);
}
$mysqli -> close();
?>
像下面這個例子: $lastname 裡面的值有單引號。這樣進入 SQL 就會發生錯誤,應該要避開。
就使用這個函數:mysqli_real_escape_string(),就可以把單引號等避開了!
<?php
$lastname = "D'Ore";
$sql="INSERT INTO Persons (LastName) VALUES ('$lastname')";
// This query will fail, cause we didn't escape $lastname
if (!$mysqli -> query($sql)) {
printf("%d Row inserted.\n", $mysqli->affected_rows);
}
?>
https://www.w3schools.com/php/func_mysqli_real_escape_string.asp
https://www.php.net/manual/en/mysqli.real-escape-string.php
每個企業,都有他的企業商業規則,Business Rules。
這些商業規則,應該要獨立的存放在 MySQL資料庫中。
設計師應該要記住:商業規則不應該放在應用程式中。
商業規則,可以被應用程式使用,但不是把他寫死在營用城市裡面。
原因:
1- 商業規則是不斷發展中的
2- 情況是會改變的,例如有了新的規則
3-這個商業規則可能會使用在不同的應用程式裡面。
負責商業規則的程式設計師,要建立一個兩層的應用程式:
1 - 商業規則層
2 - 應用程式層
使用 MySQL 資料庫系統就是一個建立商業規則層的明顯選擇。
就是因為他可以使用大部分的程式語言,而且程式設計師可以:
1 - 將商業規則資訊存放在 資料表 Table中
2 - 使用 stored function/procedure 來執行商業規則。
使用 MySQL 建立好的商業規則,可以很便利的為使用各種不同的程式語言寫得贏用程式來呼叫使用。包括在網路上的應用程式。
商業規則本身,可以使用 MySQL的函數來建立。
很明顯的,這些規則可以使用 if.. then..else 指令來完成。
例如:根據輸入的項目,而採取不同的行動,程式:
delimiter //
drop function if exists business_rule;
create function business_rule (status varchar(50)) returns varchar(50)
deterministic
begin
declare new_status varchar(50);
if status = "new" then
set new_status = "case opened - send to engineer";
elseif status = "fixed" then
set new_status = "problem solved - inform customer";
elseif status = "nofix" then
set new_status = "problem unresolved - sent to engineer";
elseif status = "raise" then
set new_status = "problem escalated - inform manager";
elseif status = "close" then
set new_status = "case closed";
else set status = "undefined";
end if;
return new_status;
end
//
delimiter ;
這個函數,可以被應用程式呼叫使用:
echo "select business_rule('new')" | mysql -uuser -ppassword business_rules_db
這樣一來,
1. 這些商業規則,可以被不同語言的應用程式使用,或任何可以使用MySQL的應用程式
2. 商業規則可以被獨立更新或修改、增加而不需要更動應用程式。
最後,程式設計師可以有一個有力且可適應修改商業規則,而與使用他們的應用程式獨立運作。
簡單翻譯自:
https://steemit.com/utopian-io/@haig/how-to-use-business-rules-in-a-mysql-database-using-mysql-functions-to-create-two-tier-business-savvy-applications
mysql 裡面,unique index key如果含有 null,他並未計入唯一的檢查。還是可以接受兩筆以上的 null資料。
如果希望不能兩筆null資料,那就只好將 null 資料,改為 ""、空字串,這樣就可以辨識唯一了。
CREATE TABLE table1 (x INT NULL UNIQUE);
INSERT table1 VALUES (1);
INSERT table1 VALUES (1); -- Duplicate entry '1' for key 'x'
INSERT table1 VALUES (NULL);
INSERT table1 VALUES (NULL);
SELECT * FROM table1;
Insert Into Table(A, B) Values (null, 2);
Insert Into Table(A, B) Values (null, 2);#should fail do to duplicate values
這種情形,mysql 還是允許。
若改成"",就可以由Index來限制唯一了!
Insert Into Table(A, B) Values ("", 2);
Insert Into Table(A, B) Values ("", 2);#should fail do to duplicate values
記得:這樣一來,使用程式在做判斷時,就要使用 empty()來判斷
1. Stop mysql:
systemctl stop mysqld
2. Set the mySQL environment option
systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"
3. Start mysql usig the options you just set
systemctl start mysqld
4. Login as root
mysql -u root
5. Update the root user password with these mysql commands
mysql> UPDATE mysql.user SET authentication_string = PASSWORD('MyNewPassword')
-> WHERE User = 'root' AND Host = 'localhost';
mysql> FLUSH PRIVILEGES;
mysql> quit
*** Edit ***
As mentioned my shokulei in the comments, for 5.7.6 and later, you should use
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';
Or you'll get a warning
6. Stop mysql
systemctl stop mysqld
7. Unset the mySQL envitroment option so it starts normally next time
systemctl unset-environment MYSQLD_OPTS
8. Start mysql normally:
systemctl start mysqld
Try to login using your new password:
7. mysql -u root -p
CREATE FUNCTION `f_xxx`( p_ref_type VARCHAR(50) , ... )
CREATE FUNCTION `f_xxx`( p_ref_type VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, ... )
... END character_set_client: utf8mb4 collation_connection: utf8mb4_unicode_ci Database Collation: utf8_general_ci 1 row in set (0.00 sec)
只要用 if (empty({primary_key})) 就可以知道是否為新增模式了。 如果 {promary_key} 是空白的,那麼就是在新增模式;反之,就是更新模式。 以上。