2020年5月28日 星期四

mysql 資料庫主鍵設計,盡量使用數值,不要用字元


未來,資料庫設計主鍵時,盡量使用數值型態,不要用char,因為會牽涉到 utf8mb4….等問題

未來會一直升級,現在 utf4.0->utf5.2->utf9.0

作為一個資料表的主鍵 Primary Key,主要的作用就是用來鑑別資料的唯一性,做索引、做比對、做關聯、做union等,都是靠這個主鍵。如果因為 char code的改變,很容易影響到比對等結果,造成資料不正確!
而如果 屬性欄 是 char,如果未來 char code 改變,頂多是無法顯示,或是顯示出來是亂碼,還不至於產生資料庫不一致的問題出來!

codecharge Template把 "
"吃掉?

做了一個 topheader.ccp 準備被 include,但是奇怪:開頭的 <header .....> ....</header> 這對頭尾硬是不出現?硬是被吃掉?
只好在 masterpage.ccp 上做<header ....>...<include topheader.ccp>...</header>這樣就可以?

很是奇怪?

還有待找原因!

2020年5月27日 星期三

Change mysql root password on Centos7


https://stackoverflow.com/questions/33510184/change-mysql-root-password-on-centos7

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

2020年5月26日 星期二

mySQL PDO


1. 連結資料庫:

#連結資料庫

$connection = new PDO('mysql:host=localhost;dbname=pdo_example;charset=utf8', 'root', '12345678');

執行Query
$connection->exec('INSERT INTO pdo VALUES ("","PJCHENder", 12345678)');


#查詢Query的結果
$statement = $connection->query('select * from pdo');

foreach($statement as $row){
    echo $row['user']." ".$row['pwd']."<br>";

}


或:

while($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    echo $row['user'] . ' ' . $row['pwd']."<br>";

}




使用PDO存取資料庫(讀取、查詢、修改、更新)




PHP存取資料庫的方式有很多

這篇要介紹的是,如何使用PDO查詢、修改、更新資料庫

在說明之前,先簡單介紹一下什麼是PDO?



PDO(PHP Data Objects)是一種PHP連接資料庫的使用方法

主要的好處可以避免發生SQL injection相關的問題

同時也優化了許多存取資料庫的性能



下面就直接說明如何使用PDO讀取、查詢、修改、更新資料庫內的資料



       //首先,先來定義資料庫相關存取資料

       $db_host = "localhost";

       $db_user = "root";

       $db_pass = "111111";

       $db_select = "pdo_test";



       //使用PDO存取資料庫時,需要將資料庫依下列格式撰寫,讓程式讀取資料庫

       $dbconnect = "mysql:host=".$db_host.";dbname=".$db_select;

       //建立使用PDO方式連線的物件,並放入指定的相關資料

       $dbgo = new PDO($dbconnect, $db_user, $db_pass);

       //建立查詢資料表的SQL語法

       $sql = "SELECT * FROM pdo_test";

       //執行並查詢,查詢後只回傳一個查詢結果的物件,必須使用fetc、fetcAll...等方式取得資料

       $result = $dbgo->query($sql);

       //取出第一筆資料,以此例來說就是最先存入資料庫的那一筆資料

       $row=$result->fetch();

       //抓出全部但是除了使用欄位名稱存成陣列之外,還會依照順序再另外存成一組陣列,結果如下

       $row=$result->fetchAll();

       //Array ( [0] => Array ( [pdo_id] => 1 [0] => 1 [pdo_name] => stanley [1] => stanley [pdo_mail] => stanley@domain.com [2] => stanley@domain.com [pdo_login] => 0 [3] => 0 )  )



       //加入FETCH_ASSOC,代表要將取出的資料已關聯性的方式存成陣列,同時也適用於各式抓取資料的方法(如上面提到的fetch),結果如下

       $row=$result->fetchAll(PDO::FETCH_ASSOC);

       //Array ( [0] => Array ( [pdo_id] => 1 [pdo_name] => stanley [pdo_mail] => stanley@domain.com [pdo_login] => 0 )





       //如果需要做的是執行SQL語法的工作(例如插入、更新、修改),則必須使用下面的方式執行SQL語法

       //首先下列這是要執行插入的語法

       $sql_insert = "INSERT INTO `pdo_test` (`pdo_id`, `pdo_name`, `pdo_mail`, `pdo_login`) VALUES (NULL, 'stanley', 'stanley@domain.com', '0')";

       //方法一:可直接使用exec的方法,把要執行的SQL語法放入exec函式內

       $dbgo->exec($sql_insert);

       //方法二:必須先將要執行的語法放入prepare函數中,等到需要執行的時候再使用execute的方法來執行

       $inserert_2 = $dbgo->prepare($sql_insert);

       $inserert_2->execute();



       最後大家看看自家的資料表是不是有資料被輸入或網頁正常顯示,就知道是不是成功了

       據說PHP7之後,PHP就會捨棄過去mysql_query的方式去存取資料表,但目前仍找不到資料出處

       (碎碎念:目前史丹利用PHP5.5版測試時,只要是使用mysql_query存取,就會出現警告訊息,因此很有可能是真的)

       所以大家還是先預先準備,學習PDO存取資料庫的方法



       如果覺得對你有幫助的話. 請幫小弟按個讚吧~

Sample:


$hostname = 'localhost';
$username = 'user';
$password = 'password';
$db_name="drupaldb";

try{
    $db=new PDO("mysql:host=".$hostname.";
                dbname=".$db_name, $username, $password,
                array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
                //PDO::MYSQL_ATTR_INIT_COMMAND 設定編碼
             
    //echo '連線成功';
    $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); //錯誤訊息提醒
 
    //Query SQL
    $sql="Select * from act where num=3";
    $result=$db->query($sql); 
    while($row=$result->fetch(PDO::FETCH_OBJ)){ 
        //PDO::FETCH_OBJ 指定取出資料的型態
        echo $row->num."\n";
        echo $row->cn_title."\n";
    }
 
    //Insert
    $count=$db->exec("insert into act(cn_title,eng_title) values('新聞', 'troy')");
    echo $count;     
 
 
    //Update
    $count=$db->exec("update act set cn_title='中文' where num=3");
 
    $db=null; //結束與資料庫連線
}
catch(PDOException $e){
    //error message
    echo $e->getMessage();
}
?>


2020年5月25日 星期一

1267 - Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='

今天有个SQL执行不了,通过错误输出查到了问题,大致SQL如下:
SELECT * FROM `table` WHERE `field1`=`filed2`
这个SQL看起来是一点错误都没有,但是缺爆出了下面这个错误:
Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
意思就是编码不一致不能用“=” 运算符。那怎么办呢。。。还用说就是转换编码了,还好MySQL也有相关的函数。
CONVERT(table-colum USING utf8) COLLATE utf8_unicode_ci
比如是field1编码是utf8_unicode_ci,filed2编码是utf8_general_ci那么就会出现,那么SQL语句应该修改成这样子。
SELECT * FROM `table` WHERE `field1`=CONVERT(`filed2` USING utf8) COLLATE utf8_unicode_ci
这样编码就统一了,不过这个只是临时解决。最终还是根解决最好,直接修改字段的本身编码。






The default collation for stored procedure parameters is utf8_general_ci and you can't mix collations, so you have four options:
Option 1: add COLLATE to your input variable:
SET @rUsername = aname COLLATE utf8_unicode_ci; -- COLLATE added
CALL updateProductUsers(@rUsername, @rProductID, @rPerm);
Option 2: add COLLATE to the WHERE clause:
CREATE PROCEDURE updateProductUsers(
    IN rUsername VARCHAR(24),
    IN rProductID INT UNSIGNED,
    IN rPerm VARCHAR(16))
BEGIN
    UPDATE productUsers
        INNER JOIN users
        ON productUsers.userID = users.userID
        SET productUsers.permission = rPerm
        WHERE users.username = rUsername COLLATE utf8_unicode_ci -- COLLATE added
        AND productUsers.productID = rProductID;
END
Option 3: add it to the IN parameter definition:
CREATE PROCEDURE updateProductUsers(
    IN rUsername VARCHAR(24) COLLATE utf8_unicode_ci, -- COLLATE added
    IN rProductID INT UNSIGNED,
    IN rPerm VARCHAR(16))
BEGIN
    UPDATE productUsers
        INNER JOIN users
        ON productUsers.userID = users.userID
        SET productUsers.permission = rPerm
        WHERE users.username = rUsername
        AND productUsers.productID = rProductID;
END
Option 4: alter the field itself:
ALTER TABLE users CHARACTER SET utf8 COLLATE utf8_general_ci;
Unless you need to sort data in Unicode order, I would suggest altering all your tables to use utf8_general_ci collation, as it requires no code changes, and will speed sorts up slightly.
UPDATE: utf8mb4/utf8mb4_unicode_ci is now the preferred character set/collation method. utf8_general_ci is advised against, as the performance improvement is negligible. See https://stackoverflow.com/a/766996/1432614









I spent half a day searching for answers to an identical "Illegal mix of collations" error with conflicts between utf8_unicode_ci and utf8_general_ci.
I found that some columns in my database were not specifically collated utf8_unicode_ci. It seems mysql implicitly collated these columns utf8_general_ci.
Specifically, running a 'SHOW CREATE TABLE table1' query outputted something like the following:
| table1 | CREATE TABLE `table1` (
`id` int(11) NOT NULL,
`col1` varchar(4) CHARACTER SET utf8 NOT NULL,
`col2` int(11) NOT NULL,
PRIMARY KEY (`col1`,`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
Note the line 'col1' varchar(4) CHARACTER SET utf8 NOT NULL does not have a collation specified. I then ran the following query:
ALTER TABLE table1 CHANGE col1 col1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
This solved my "Illegal mix of collations" error. Hope this might help someone else out there.





如何判斷現在FORM是在 insert mode? 還是 update mode?

只要用  if (empty({primary_key})) 就可以知道是否為新增模式了。 如果 {promary_key} 是空白的,那麼就是在新增模式;反之,就是更新模式。 以上。