前言
公司要搞國(guó)產(chǎn)化開(kāi)發(fā),數(shù)據(jù)庫(kù)選用達(dá)夢(mèng)數(shù)據(jù)庫(kù),達(dá)夢(mèng)版本為dm8,php版本為7.2,前期在Windows進(jìn)行開(kāi)發(fā)。
數(shù)據(jù)庫(kù)從mysql遷移到達(dá)夢(mèng)數(shù)據(jù)庫(kù)里面,遷移方法和php的擴(kuò)展安裝方法就不講了,這方面網(wǎng)上的資料還蠻多。
不過(guò)php連接達(dá)夢(mèng)數(shù)據(jù)庫(kù)之后的使用操作的資料就比較少了,客服的技術(shù)大家都懂的,資料全靠翻文檔,簡(jiǎn)單給大家提供一下我踩過(guò)的坑,方法都是直接操作數(shù)據(jù)庫(kù),后續(xù)根據(jù)大家自己的喜好去封裝去吧。
簡(jiǎn)單說(shuō)明一下達(dá)夢(mèng)的資料目錄,在達(dá)夢(mèng)的安裝目錄下面的《doc》里面主要是各種使用文檔,《drivers》里面是各種語(yǔ)言的擴(kuò)展,php的so擴(kuò)展就是從這里面取的,我這里主要使用的是php_dm的擴(kuò)展,pdo_dm的資料太少了我就沒(méi)怎么研究。
實(shí)例化數(shù)據(jù)庫(kù)的時(shí)候有兩點(diǎn)需要提醒各位的,字符集和字符串大小寫敏感記得提前設(shè)置好,不要給自己挖坑。
本人經(jīng)歷就是mysql遷移過(guò)來(lái)的數(shù)據(jù)表名和字段名都是小寫,結(jié)果在后面使用的時(shí)候各種坑,后來(lái)發(fā)現(xiàn)大小寫敏感去掉就可以了。
這里就用官方的示例庫(kù)里面的CITY這張表演示php7.2各種使用方法吧。
查詢
廢話不多說(shuō),先上代碼
//連接數(shù)據(jù)庫(kù) $link = dm_connect("localhost", "SYSDBA", "SYSDBA"); if(!$link){ var_dump(@dm_error()); var_dump(iconv("GBK","UTF-8",@dm_errormsg())); } dm_setoption($link,1,12345,1);//設(shè)置 dm 連接和語(yǔ)句的相關(guān)屬性,設(shè)置UTF8 $query = "select * from DMHR.CITY"; $result = dm_exec($link,$query); print " 查詢結(jié)果:</br>"; while ($line = dm_fetch_array($result)){ print_r($line); echo '<br>'; } /* 釋放資源 */ dm_free_result($result); /* 斷開(kāi)連接 */ dm_close($link);
達(dá)夢(mèng)的php官方擴(kuò)展php5和php7的使用方法區(qū)別很大,php5里面很多方法在php7里面用不了,部分方法在php7里面用其他方法替代了,網(wǎng)上的資料大部分都是php5的,在php7里面完全用不了。
查詢語(yǔ)句出來(lái)的中文亂碼的問(wèn)題就是一個(gè)天坑,查了半天文檔才試出來(lái)的這種方法,有其他更優(yōu)雅的方法也歡迎教一下我,大家互相學(xué)習(xí)。
插入
//連接數(shù)據(jù)庫(kù) $link = dm_connect("localhost", "SYSDBA", "SYSDBA"); if(!$link){ var_dump(@dm_error()); var_dump(iconv("GBK","UTF-8",@dm_errormsg())); } dm_setoption($link,1,12345,1);//設(shè)置 dm 連接和語(yǔ)句的相關(guān)屬性,設(shè)置UTF8 $query = "INSERT INTO DMHR.CITY (CITY_ID,CITY_NAME,REGION_ID) VALUES ('JL','吉林','1')"; $result = dm_exec($link,$query); if($result){ echo "插入成功"; //曲線查詢插入id /*$query = "SELECT @@IDENTITY as insert_id"; $result = dm_exec($link,$query); $line = dm_fetch_array($result); echo ',ID:'; print_r($line);*/ } /* 釋放資源 */ dm_free_result($result); /* 斷開(kāi)連接 */ dm_close($link);
官方提供的dm_insert_id()這個(gè)函數(shù)貌似只用php5能用,php7沒(méi)有這個(gè)函數(shù),只能通過(guò)曲線查詢自增的id值,當(dāng)然演示的這張表沒(méi)有自增ID,同時(shí)SELECT @@IDENTITY as insert_id 這句是必定查詢成功的,就算插入失敗也會(huì)返回更前一次插入成功的自增ID,千萬(wàn)不要用自增ID判斷語(yǔ)句是否插入成功。
更新
//連接數(shù)據(jù)庫(kù) $link = dm_connect("localhost", "SYSDBA", "SYSDBA"); if(!$link){ var_dump(@dm_error()); var_dump(iconv("GBK","UTF-8",@dm_errormsg())); } dm_setoption($link,1,12345,1);//設(shè)置 dm 連接和語(yǔ)句的相關(guān)屬性,設(shè)置UTF8 $query = "UPDATE DMHR.CITY SET REGION_ID='2' WHERE CITY_ID='JL'"; $result = dm_exec($link,$query); if($result){ echo "更新成功"; } /* 釋放資源 */ dm_free_result($result); /* 斷開(kāi)連接 */ dm_close($link);
更新就很簡(jiǎn)單了
刪除
//連接數(shù)據(jù)庫(kù) $link = dm_connect("localhost", "SYSDBA", "SYSDBA"); if(!$link){ var_dump(@dm_error()); var_dump(iconv("GBK","UTF-8",@dm_errormsg())); } dm_setoption($link,1,12345,1);//設(shè)置 dm 連接和語(yǔ)句的相關(guān)屬性,設(shè)置UTF8 $query = "DELETE FROM DMHR.CITY WHERE (CITY_ID='JL')"; $result = dm_exec($link,$query); if($result){ echo "刪除成功"; } /* 釋放資源 */ dm_free_result($result); /* 斷開(kāi)連接 */ dm_close($link);
刪除也很簡(jiǎn)單,沒(méi)什么特別注意的地方
事務(wù)
根據(jù)官方文檔介紹:“DM 沒(méi)有提供顯式定義事務(wù)開(kāi)始的語(yǔ)句,第一個(gè)可執(zhí)行的 SQL 語(yǔ)句(除登錄語(yǔ)句外)隱含事務(wù)的開(kāi)始”,這是沒(méi)有定義事務(wù)開(kāi)始方法的原因,不過(guò)當(dāng)我們要從某一段程序開(kāi)始事務(wù)的時(shí)候,可以使用dm_autocommit()函數(shù)將事務(wù)的自動(dòng)提交關(guān)閉,在程序結(jié)束之后在將自動(dòng)提交打開(kāi)
//連接數(shù)據(jù)庫(kù) $link = dm_connect("localhost", "SYSDBA", "SYSDBA"); if(!$link){ var_dump(@dm_error()); var_dump(iconv("GBK","UTF-8",@dm_errormsg())); } dm_setoption($link,1,12345,1);//設(shè)置 dm 連接和語(yǔ)句的相關(guān)屬性,設(shè)置UTF8 $query = "INSERT INTO DMHR.CITY (CITY_ID,CITY_NAME,REGION_ID) VALUES ('JL','吉林','1')"; $result = dm_exec($link,$query); if($result){ echo "插入成功。"; } $result = dm_autocommit($link,false);//事務(wù)自動(dòng)提交關(guān)閉 $query = "UPDATE DMHR.CITY SET CITY_NAME='遼寧' WHERE (CITY_ID='SY')"; $result = dm_exec($link,$query); if($result){ echo "更新成功,回滾。"; } dm_rollback($link);//回滾 //dm_commit($link);//提交 $result = dm_autocommit($link,true);//開(kāi)啟事務(wù)自動(dòng)提交,結(jié)束事務(wù) /* 斷開(kāi)連接 */ dm_close($link);
踩過(guò)的坑
一、在達(dá)夢(mèng)數(shù)據(jù)庫(kù)中獲取時(shí)間戳格式的時(shí)間select DATEDIFF(s, '1970-01-01 00:00:00', GETUTCDATE());
二、如果之前使用的數(shù)據(jù)庫(kù)是mysql,時(shí)間格式 DATETIME 和 TIMESTAMP 這兩種類型后面的標(biāo)度要注意一下,如果不是0的話時(shí)間精度會(huì)更長(zhǎng)
三、有些字段查詢出來(lái)的話會(huì)變成大寫,比如“count”
解決方法:將字段用雙引號(hào)引上例:select count(1) as "count" from "DMHR"."CITY";
四、group by語(yǔ)句的使用很嚴(yán)格(或者說(shuō)mysql的group by過(guò)于放松),select中除聚合函數(shù)之外出現(xiàn)的所有字段必須要在group by里面。
比方舉一個(gè)錯(cuò)誤的例子:
select EMPLOYEE_NAME,JOB_ID from "DMHR"."EMPLOYEE" group by JOB_ID;
EMPLOYEE_NAME和字段沒(méi)在group by 中,執(zhí)行必定失敗
提供一種解決思路:
select * from "DMHR"."EMPLOYEE" where EMPLOYEE_ID in (select min(EMPLOYEE_ID) as minid from "DMHR"."EMPLOYEE" group by JOB_ID)
同樣select中如果有聚合函數(shù)之外的字段,需要加入group by。錯(cuò)誤的例子:
select min(EMPLOYEE_ID),EMPLOYEE_NAME,JOB_ID from "DMHR"."EMPLOYEE";
select中有min()函數(shù)外還有其他字段,執(zhí)行必定失敗。
如果一定要在其他很多字段里面加入聚合函數(shù),提供一種思路:
select t1.EMPLOYEE_NAME,t1.JOB_ID,t2.minid from "DMHR"."EMPLOYEE" t1 left join ( select min(EMPLOYEE_ID) as minid,JOB_ID from "DMHR"."EMPLOYEE" group by JOB_ID ) t2 on t2.JOB_ID=t1.JOB_ID where t1.EMPLOYEE_ID in (select min(EMPLOYEE_ID) as minid from "DMHR"."EMPLOYEE" group by JOB_ID);
結(jié)語(yǔ)
目前踩過(guò)的坑就這些了,希望能夠幫助到大家。
對(duì)于其他問(wèn)題還是要多翻閱官方文檔了。