MYSQL與MSSQL常用用法區別
1、識別符號限定符
SqlServer []
MySql “
2、字串相加
SqlServer 直接用 +
MySql concat(),如:concat(‘my name is’,’jiajia’)
3、isnull()
SqlServer isnull()
MySql ifnull()或者COALESCE(),如:ifnull(insert_dt,0)或者COALESCE(start_dt,0)
注意:MySql也有isnull()函式,但意義不一樣
4、獲取系統當前時間
SqlServer getdate()
MySql now()
5、newid()
SqlServer newid()
MySql uuid()
注:MYSQL中不存在uniqueidentifier型別(一般用char(36)來代替處理),uuid()在建表時不能用作預設值,而MSSQL中卻可以用newid()來做預設值。
6、@@ROWCOUNT
SqlServer @@ROWCOUNT
MySql row_count()
注:MySql的這個函式僅對於update, insert, delete有效,而對於select 則用FOUND_ROWS()。其中,當update更新值與原欄位值相同時,此時row_count()值為0,這點需引起注意,對於這種情況,需先判斷表中是否存在資料的情況。
7、SCOPE_IDENTITY()
SqlServer SCOPE_IDENTITY()
MySql last_insert_id()
8、if……else……
SqlServer:
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]
– 若要定義語句塊,請使用控制流關鍵字 BEGIN 和 END。
MySql:
IF (search_condition)
THEN statement_list
[ELSEIF search_condition THEN statement_list]…
[ELSE statement_list]
END IF;
注意:對於MySql來說,then, end if是必須的。類似的還有其它的流程控制語句,這裡就不一一列出。
9、declare宣告區域性變數
其實,SqlServer和MySql都有這個語句,用於定義變數,但差別在於:在MySql中,DECLARE僅被用在BEGIN ……END複合語句裡,並且必須在複合語句的開頭,在任何其它語句之前。這個要求在寫遊標時,會感覺很BT。
10、遊標的寫法
SqlServer中:
declare @tempShoppingCart table (ProductId int, Quantity int)
insert into @tempShoppingCart (ProductId, Quantity)
select ProductId, Quantity from ShoppingCart where UserGuid = @UserGuid
declare @productId int
declare @quantity int
declare tempCartCursor cursor for
select ProductId, Quantity from @tempShoppingCart
open tempCartCursor
fetch next from tempCartCursor into @productId, @quantity
while @@FETCH_STATUS = 0
begin
update Product set SellCount = SellCount + @quantity where productId = @productId
fetch next from tempCartCursor into @productId, @quantity
end
close tempCartCursor
deallocate tempCartCursor
MySql中:
declare m_done int default 0;
declare m_sectionId int;
declare m_newsId int;
declare _cursor_SN cursor for select sectionid, newsid from _temp_SN;
declare continue handler for not found set m_done = 1;
create temporary table _temp_SN
select sectionid, newsid from SectionNews group by sectionid, newsid having count(*) > 1;
open _cursor_SN;
while( m_done = 0 ) do
fetch _cursor_SN into m_sectionId, m_newsId;
if( m_done = 0 ) then
– 具體的處理邏輯
end if;
end while;
close _cursor_SN;
drop table _temp_SN;
注意:為了提高效能,通常在表變數上開啟遊標,不要直接在資料表上開啟遊標。
11、分頁的處理
SqlServer:
create procedure GetProductByCategoryId(
@CategoryID int,
@PageIndex int = 0,
@PageSize int = 20,
@TotalRecords int output
)
as
begin
declare @ResultTable table
(
RowIndex int,
ProductID int,
ProductName nvarchar(50),
CategoryID int,
Unit nvarchar(10),
UnitPrice money,
Quantity int
);
insert into @ResultTable
select row_number() over (order by ProductID asc) as RowIndex,
p、ProductID, p、ProductName, p、CategoryID, p、Unit, p、UnitPrice, p、Quantity
from Products as p
where CategoryID = @CategoryID;
select @TotalRecords = count(*) from @ResultTable;
select *
from @ResultTable
where RowIndex > (@PageSize * @PageIndex) and RowIndex <= (@PageSize * (@PageIndex+1));
end;
當然,SqlServer中並不只有這一種寫法,只是這種寫法是比較常見而已。
MySql:
create procedure GetProductsByCategoryId(
in _categoryId int,
in _pageIndex int,
in _pageSize int,
out _totalRecCount int
)
begin
set @categoryId = _categoryId;
set @startRow = _pageIndex * _pageSize;
set @pageSize = _pageSize;
prepare PageSql from
‘select sql_calc_found_rows * from product where categoryId = ? order by ProductId
desc limit 2;
execute PageSql using @categoryId, @startRow, @pageSize;
deallocate prepare PageSql;
set _totalRecCount = found_rows();
end
12、MYSQL儲存過程中宣告區域性變數,併為其賦值。
declare var_name type [default value];
select filed_name into var_name from table_name;
另一種賦值方法:
select @str:=fild_name from table_name limit 1;
select @str;
13、查詢儲存過程的建立指令碼
show create procedure pr_name;
14、查詢表的建立指令碼
show create table tab_name;
15、顯示資料庫中所有儲存的儲存過程基本資訊,包括所屬資料庫,儲存過程名稱,建立時間等
show procedure status;
16、建表指令碼中的自增列
MYSQL:AUTO_INCREMENT
MSSQL:IDENTITY(1,1)
17、時間型別
MYSQL:TIMESTAMP
MSSQL:DATETIME
18、date_add()函式
MYSQL:DATE_ADD(NOW(),INTERVAL 2 DAY); 或者 TIMESTAMPADD(DAY,2,NOW());
MSSQL:DATEADD(dd,2,getdate());
19、TIMESTAMPDIFF函式
MYSQL:TIMESTAMPDIFF(DAY,’2013-03-19’,NOW());
MSSQL:datediff(dd,startdate,enddate);
20、執行儲存過程
MYSQL:CALL PR_NAME(PARA1,PARA2,…);
MSSQL:exec pr_name para1,para2,…;
21、convert()函式
MYSQL:CONVERT(value,type);如:CONVERT(NOW(),char(20))
其中type支援型別如下:
二進位制,同帶binary字首的效果:BINARY
字元型,可帶引數: CHAR()
日期: DATE
時間: TIME
日期時間型: DATETIME
浮點數: DECIMAL
整數: SIGNED
無符號整數: UNSIGNED
MSSQL:convert(varchar(20),getdate(),20);
22、獲取本月第一天
格式為:YYYY-MM-DD
MYSQL:select DATE_ADD(curdate(),interval -day(curdate())+1 day);
MSSQL:select convert(varchar(10),dateadd(dd,-day(getdate())+1,getdate()),120);
格式為:YYYYMMDD
MYSQL:select DATE_FORMAT(DATE_ADD(curdate(),interval -day(curdate())+1 day),’%Y%m%d’);
MSSQL:select convert(varchar(10),dateadd(dd,-day(getdate())+1,getdate()),112);
23、獲取本月最後一天
格式為:YYYY-MM-DD
MYSQL:select DATE_ADD(DATE_ADD(curdate(),INTERVAL 1 MONTH),interval -day(curdate()) day);
MSSQL:select convert(varchar(10),dateadd(dd,-day(getdate()),dateadd(m,1,getdate())),120)
格式為:YYYYMMDD
MYSQL:select DATE_FORMAT(DATE_ADD(DATE_ADD(curdate(),INTERVAL 1 MONTH),interval -day(curdate()) day),’%Y%m%d’);
MSSQL:select convert(varchar(10),dateadd(dd,-day(getdate()),dateadd(m,1,getdate())),112)
24、判斷某個變數或表示式是否為數值
由於MYSQL中沒有像MSSQL中isnumeric函式來判斷一個字串中是否字元,因此只好通過自定義函式來實現類似的函式功能。
MYSQL:
建立自定義函式的指令碼為:
– 返回0表示為非數值或含有非數值字元,返回1表示為數值
CREATE FUNCTION ISNUMERIC(myVal VARCHAR(1024))
RETURNS TINYINT(1) DETERMINISTIC
RETURN myVal REGEXP ‘^(-|\+)?([0-9]+\.[0-9]|[0-9]\.[0-9]+|[0-9]+|[0-9]+\.[0-9]e\+[0-9]+|[0-9]\.[0-9]+e\+[0-9]+|[0-9]+e\+[0-9]+)$’;
MSSQL:select isnumeric(expression)=0(表示 expression 中含有字元,反之為數值)
25、錯誤及異常處理
由於MYSQL中沒有類似MSSQL中@@error的函式來捕捉執行sql語句時產生的錯誤或異常,所以需要採用一些替代方法來實現。當然你也可以通過查詢@@error_count和@@warning_count(如:select @@error_count,@@warning_count)來達到判斷的目的,但warning_count 的值可能會比 SHOW WARNINGS 顯示的結果記錄數大,因為系統變數 max_error_count 被設定的比較小,因此沒有把所有的資訊都存下來。
例如:
DECLARE _err int default 0;
DECLARE continue handler for sqlexception, sqlwarning, not found set _err=1;
MYSQL:
MYSQL中異常及錯誤捕捉測試儲存過程如下:
DROP PROCEDURE IF EXISTS pr_testerror;
CREATE PROCEDURE pr_testerror(
)
proc_start:BEGIN
DECLARE _err int default 0;
DECLARE continue handler for sqlexception, sqlwarning, not found set _err=1;
INSERT INTO persons(name,age,tel,edate,sex)
SELECT ‘juanzi’,22,18729273781,NOW(),f;
IF _err=1
THEN
LEAVE proc_start;
END IF;
END proc_start
MSSQL:select @@error 或者if (@@error<>0 )… 來捕捉錯誤及異常。
26、延時時間處理
MYSQL:SLEEP(5); 表示延時5秒鐘。測試:SELECT SYSDATE(),SLEEP(5),SYSDATE();
MSSQL:waitfor delay ‘00:00:03’; 表示延時3秒鐘,另外,waitfor time ‘11:20:46’;表示等到11點20分46秒後才執行。
27、取日期單獨部分
MYSQL:SELECT DATE_FORMAT(NOW(),’%Y’);
MSSQL:select datepart(yy,getdate());
28、判斷表是否存在
MYSQL:if exists(select 1 from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=’db_name’ and TABLE_NAME=’table_name’);
MSSQL:if exists(select 1 from sysobjects where id=object_id(‘db_name.table_name’) and type=’U’);
29、迴圈中的中斷和繼續處理
MYSQL:break用LEAVE處理,continue用iterate處理。如:whl1:while … do …break whl1…end while whl1;
MSSQL:用break和continue直接處理。
30、FULL OUTER JOIN
目前MYSQL暫時還不支援full outer join的聯接操作,等待後面的版本會支援該操作。
MYSQL:
涉及兩個表時(需求實現如select a.col1,b.col2 from t1 a full outer join t2 b on a.id=b.id):
select a.col1,b.col2 from t1 a left join t2 b on a.id=b.id
union
select a.col1,b.col2 from t1 a right join t2 b on a.id=b.id
涉及三個表時(需求實現如select a.col1,b.col2,c.col3 from t1 a full outer join t2 b on a.id=b.id full outer join t3 c on b.id=c.id):
select a.col1,b.col2,c.col3 from t1 a left join t2 b on a.id=b.id left join t3 c on b.id=c.id
union
select a.col1,b.col2,c.col3 from t1 a right join t2 b on a.id=b.id left join t3 c on b.id=c.id
union
select a.col1,b.col2,c.col3 from t1 a right join t2 b on a.id=b.id right join t3 c on b.id=c.id;
MSSQL:select a.col1,b.col2 from employee a full outer join master b on a.id=b.id;
31、實現將某一欄位值以逗號分隔成一行
MYSQL: SELECT uid,GROUP_CONCAT(name SEPARATOR ‘,’) FROM persons;
動態行轉列示例:
SET @EE=”;
SELECT @EE:=GROUP_CONCAT(@EE,’sum(if(zone=\”,zone,’\”,’,tel,0)) as ‘,””,zone,””) from (select DISTINCT zone from t_tmp)a;
SET @str=CONCAT(‘select ‘,@EE,’ from t_tmp group by tel’);
PREPARE stmt from @str;
EXECUTE stmt;
MSSQL:
declare @tt varchar(300)
select @tt=”
select @[email protected]+name+’,’ from persons
select @tt
32、定時執行作業計劃
MYSQL: 通過事件(event)來實現定時執行作業計劃,但需要保證事件排程器的正常啟用。
MSSQL: 通過作業(job)來實現定製執行作業計劃,但需要保證代理伺服器正常啟用。