游標的作用及屬性
游標的作用就是用于對查詢數據庫所返回的記錄進行遍歷,以便進行相應的操作;游標有下面這些屬性:
??? a、游標是只讀的,也就是不能更新它;
??? b、游標是不能滾動的,也就是只能在一個方向上進行遍歷,不能在記錄之間隨意進退,不能跳過某些記錄;
??? c、避免在已經打開游標的表上更新數據。
實現功能,將數據量比較大的nt_m_gpsdata(3000W+),按日期拆分成如nt_m_gpsdata20170501,nt_m_gpsdata20170502,nt_m_gpsdata20170503等
CREATE?PROCEDURE?`new_procedure`?()
BEGIN
— 需要定義接收游標數據的變量
DECLARE a CHAR(16);
— 定義新建表名
DECLARE tbname CHAR(30);
— 定義存放sql語句的變量
DECLARE sqlstr1 varchar(300);
DECLARE sqlstr2 varchar(300);
— 遍歷數據結束標志
DECLARE done INT DEFAULT FALSE;
— 定義游標
DECLARE cur CURSOR FOR select DISTINCT DATE_FORMAT(ctime,’%Y%m%d’) as ctime from nt_m_gpsdata;
— 將結束標志綁定到游標
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
— 打開游標
OPEN cur;
— 開始循環
read_loop: LOOP
— 提取游標里的數據,這里只有一個,多個的話也一樣;
? ? FETCH cur INTO a;
? ? — 聲明結束的時候
? ? IF done THEN
? ? ? LEAVE read_loop;
? ? END IF;
? ? — 這里做你想做的循環的事件
? ? ? ? set tbname=CONCAT(“nt_m_gpsdata”,a);
? ? ? ? — select tbname;
? ? ? ? — 復制表結構,create table newtable select * from oldtable where 1=2? 只能復制表字段,無法復制字段主鍵、自增、非空等屬性? create table newtable like oldtable 可以復制字段屬性
????set?sqlstr1?=?CONCAT("create?table?",tbname,"?like?nt_m_gpsdata"); ????????set?sqlstr2?=?CONCAT("insert?into?",tbname,"?select?*?from?nt_m_gpsdata?where?deleted=0?and?DATE_FORMAT(ctime,'%Y%m%d')='",a,"'"); ????????set?@firstsql?=?sqlstr1; ????????PREPARE?stmt1?FROM?@firstsql; ????????EXECUTE?stmt1; ????????DEALLOCATE?PREPARE?stmt1; ????????set?@secondsql?=?sqlstr2; ????????PREPARE?stmt2?FROM?@secondsql; ????????EXECUTE?stmt2; ????????DEALLOCATE?PREPARE?stmt2;
END LOOP;
— 關閉游標
CLOSE cur;
END
后來又將這個分表策略應用到一個oracle項目,附上代碼
DECLARE cursor?my_cursors?is?select?DISTINCT?to_char(ctime,'yyyymmdd')?as?ctime?from?NTGIS_GPS_EVENTDATA; mcursor?varchar2(40); begin for?mcursor?in?my_cursors?loop DECLARE tbname?VARCHAR2(50)?:=?'NTGIS_GPS_EVENTDATA'||mcursor.ctime; sqlstr?VARCHAR2(300)?:=?'CREATE?TABLE?'||tbname||'?as?SELECT?*?from?NTGIS_GPS_EVENTDATA?where?to_char(ctime,''yyyymmdd'')='''||mcursor.ctime||''''; BEGIN --dbms_output.put_line(tbname); execute?immediate?sqlstr; END; end?loop; end;