1. 程式人生 > >db2命令列整理(二)

db2命令列整理(二)

<pre code_snippet_id="276051" snippet_file_name="blog_20140407_7_6289192" name="code" class="html">

-----



1:將excel中的資料匯入到資料庫中
先將excel儲存為csv格式,然後執行如下命令


import   from   "f:\ls2.csv"  OF   DEL   messages "c:\msg.out" INSERT INTO user(USERID,USERCODE,USERNAME,BRID,SUSERLEVEL,LASTCHECK,PACTBEGINYM,PACTENDYM,CERTFLAG,CERTTYPE,HOMEPHONE)

上面執行的時候有點錯,下面為執行出來的

----

db2 => import FROM  "D:\IFS_USER.csv"  OF   DEL   INSERT INTO IFS_USER2(USERID,U
SERNAME,BRID,SUBBANKID,ROLEID,STAID,POSITION,DEPARTMENT,MOBILEPHONE,OFFICEPHONE,
SEX,EDUCATION,UNIVERSITY,SPECIALTY,USERLEVEL,CERTFLAG,CERTTYPE,QUALITYFLAG)
SQL3109N  實用程式開始裝入檔案 "D:\IFS_USER.csv" 中的資料。


SQL3125W  在行 "130" 列 "5" 中的字元資料被截斷,因為該資料比目標資料庫列更長。


SQL3125W  在行 "151" 列 "5" 中的字元資料被截斷,因為該資料比目標資料庫列更長。


SQL3125W  在行 "152" 列 "5" 中的址荼喚囟希蛭檬荼饒勘曄菘飭懈ぁ?
SQL3125W  在行 "940" 列 "15" 中的字元資料被截斷,因為該資料比目標資料庫列更長。

2:使用者表空間容器的檢視:

db2 list tablespaces
得到使用者表空間的ID(例如2)
db2 list tablespace containers for 2
可看到該表空間中各容器的路徑

3: 關於模式

DB2中預設建立的表的模和是當前聯接使用者的名字一樣,但在表的建立時可以指定;
db2中預設的聯接使用者是使用者例項的使用者,所以預設的模式也是使用者例項的使用者
檢視當前資料庫中有哪些模式:
select distinct tabschema from sysstat.tables

4:刪除資料的幾種方法

如何快速刪除大批量的資料表(test為資料庫表)

最常用也是最多人用的語句:delete from test,但這種做法,效率比較低,花費時間太長,因為在刪除資料時,要記資料庫日誌。

import from /dev/null of del replace into test//先清空,再匯入資料(由於匯入的檔案為空,故相當於清空表資料),這種刪除的速度較快

ALTER TABLE test activate NOT LOGGED initially WITH EMPTY TABLE ;刪除表中的資料,不記日誌,這種處理最快

    5:DB2中檢查表是否已存在

select * from "SYSIBM"."SYSTABLES" where lower(name) ='afa_maintransdtl'

   6:處理db2鎖表問題:

db2 “connect to afa”

db2 “get snapshot for locks on 例項名”

db2 “terminate”

然後檢視相關資訊,找到被鎖定的表,執行以下語句:

db2 “force application(application handle) 注:application handle對應的是一個整數

6.在伺服器上建立儲存過程時:

應為儲存過程指定特定的換行符,然後執行下面的語句:

db2 [email protected] -vf fileName.sql (其中@為儲存過程中指定的換行符)

    7:檢視索引是否起作用

runstats on table afa.yj_jywtk with distribution and detailed indexes all;

8:擷取資料庫快照

db2 "connect to 例項名"

db2 "update monitor switches using lock ON sort ON bufferpool ON uow ON table ON statement ON"

db2 "get snapshot for all on 例項名"

9. 檢視儲存過程

select procname,text from sysibm.sysprocedures;

10.list tables 檢視資料庫表

11.查詢字元在字串中的位置

locate('y','xyz')

查詢'y'在'xyz'中的位置。

12. 計算兩個日期的相差天數

days(date('2007-03-01'))-days(date('2007-02-28'))

days 返回的是從 0001-01-01 開始計算的天數

13. 為一個使用者訪問另一個例項建立表對映

create alias tableName for 例項名. tableName

14.如何查看錶結構

describe table tableName

or

describe select * from table_name

15.如何重新啟動資料庫?

restart database database_name

16.如何啟用資料庫?

activate database database_name

17.如何停止資料庫?

deactivate database database_name

18.如何重命名錶?

rename table_old to table_new

19.如何定義序列?

create sequence orderseq start with 1 increment by 1 no maxvalue no cycle cache24

20.如何檢視一個表的索引

describe indexes for table tableName show detail

21.匯入、匯出資料,支援的檔案有ixf,del檔案

db2 "export to fileName.del of del select * from tableName" //db2中把表中的資料匯入到檔案

db2 "import from fileName.del of del insert into tableName " //db2中把檔案中的資料匯入到表


22.獲取表的前幾行

select * from ifs_custshare fetch first 2 rows only

select * from (
         select ROW_NUMBER() OVER(ORDER BY RIGHTFLAG DESC) AS ROWNUM,t.* from ifs_custshare t) a 
where ROWNUM > 1 and ROWNUM <=3

新增列名:


SELECT ROW_NUMBER() OVER(order by TABNAME) rownum, TABNAME FROM SYSCAT.TABLES 

但是這樣使用會報錯:

SELECT ROW_NUMBER() OVER(order by TABNAME) rownum, TABNAME FROM SYSCAT.TABLES where rownum >2 and rownum <6

SQL0206N  "ROWNUM" 在使用它的上下文中無效。  SQLSTATE=42703

SELECTCATALOG_ID, CATGROUP_ID, CATENTRY_ID, ROW_NUMBER() OVER (PARTITIONBYCATALOG_ID, CATGROUP_ID ORDERBYCATENTRY_IDASC)ASROWNUMFROMCATGPENREL

22.1:擴充套件

說起 DB2 線上分析處理,可以用很好很強大來形容。這項功能特別適用於各種統計查詢,這些查詢用通常的SQL很難實現,或者根本就無發實現。首先,我們從一個簡單的例子開始,來一步一步揭開它神祕的面紗,請看下面的SQL
SELECT  
    ROW_NUMBER() OVER(ORDER BY SALARY) AS 序號,  
    NAME AS 姓名,  
    DEPT AS 部門,  
    SALARY AS 工資  
FROM  
(  
    --姓名    部門  工資  
    VALUES  
    ('張三','市場部',4000),  
    ('趙紅','技術部',2000),  
    ('李四','市場部',5000),  
    ('李白','技術部',5000),  
    ('王五','市場部',NULL),  
    ('王藍','技術部',4000)  
) AS EMPLOY(NAME,DEPT,SALARY);  
   
查詢結果如下:  
   
序號       姓名       部門       工資  
1     趙紅       技術部    2000  
2     張三       市場部    4000  
3     王藍       技術部    4000  
4     李四       市場部    5000  
5     李白       技術部    5000  
6     王五       市場部    (null)  

看到上面的ROW_NUMBER() OVER()了嗎?很多人非常不理解,怎麼兩個函式能這麼寫呢?甚至有人懷疑上面的SQL語句是不是真的能執行。其實,ROW_NUMBER是個函式沒錯,它的作用從它的名字也可以看出來,就是給查詢結果集編號。但是,OVER並不是一個函式,而是一個表示式,它的作用是定義一個作用域(或者可以說是結果集),OVER前面的函式只對OVER定義的結果集起作用。怎麼樣,不明白?沒關係,我們後面還會詳細介紹。

從上面的SQL我們可以看出,典型的 DB2 線上分析處理的格式包括兩部分:函式部分OVER表示式部分。那麼,函式部分可以有哪些函式呢?如下:

ROW_NUMBER  
RANK  
DENSE_RANK  
FIRST_VALUE  
LAST_VALUE  
LAG  
LEAD  
COUNT  
MIN  
MAX  
AVG  
SUM 

上面這些函式的作用,我會在後面逐步給大家介紹,大家可以根據函式名猜測一下函式的作用。

假設我想在不改變上面語句的查詢結果的情況下,追加對部門員工的平均工資和全體員工的平均工資的查詢,怎麼辦呢?用通常的SQL很難查詢,但是用OLAP函式則非常簡單,如下SQL所示:

SELECT  
    ROW_NUMBER() OVER() AS 序號,  
    ROW_NUMBER() OVER(PARTITION BY DEPT ORDER BY SALARY) AS 部門序號,  
    NAME AS 姓名,  
    DEPT AS 部門,  
    SALARY AS 工資,  
    AVG(SALARY) OVER(PARTITION BY DEPT) AS 部門平均工資,  
    AVG(SALARY) OVER() AS 全員平均工資  
FROM  
(  
    --姓名    部門  工資  
    VALUES  
    ('張三','市場部',4000),  
    ('趙紅','技術部',2000),  
    ('李四','市場部',5000),  
    ('李白','技術部',5000),  
    ('王五','市場部',NULL),  
    ('王藍','技術部',4000)  
) AS EMPLOY(NAME,DEPT,SALARY)

查詢結果如下:  
   
序號       部門序號       姓名       部門       工資       部門平均工資       全員平均工資  
1            1          張三       市場部    4000       4500                     4000  
2            2          李四       市場部    5000       4500                     4000  
3            3          王五       市場部    (null)     4500                     4000  
4            1          趙紅       技術部    2000       3666                     4000  
5            2          王藍       技術部    4000       3666                     4000  
6            3          李白       技術部    5000       3666                     4000  

請注意序號和部門序號之間的區別,我們在查詢部門序號的時候,在OVER表示式中多了兩個子句,分別是PARTITION BY 和ORDER BY。它們有什麼作用呢?在介紹它們的作用之前,我們先來回顧一下OVER的作用,還記得嗎?

OVER是一個表示式,它的作用是定義一個作用域(或者可以說是結果集),OVER前面的函式只對OVER定義的結果集起作用。

ORDER BY的作用大家應該非常熟悉,用來對結果集排序。PARTITION BY的作用其實也很簡單,和GROUP BY 的作用相同,用來對結果集分組。

  到此為止,大家應該對OLAP函式的套路有一定的瞭解和體會了吧。大家看一下上面SQL的結果集,發現王五的工資是null,當我們按工資排序時,null被放到最後,我們想把null放在前邊該怎麼辦呢?使用NULLS FIRST關鍵字即可,預設是NULLS LAST,請看下面的SQL:

SELECT  
    ROW_NUMBER() OVER(ORDER BY SALARY desc NULLS FIRST) AS RN,  
    RANK() OVER(ORDER BY SALARY desc NULLS FIRST) AS RK,  
    DENSE_RANK() OVER(ORDER BY SALARY desc NULLS FIRST) AS D_RK,  
    NAME AS 姓名,  
    DEPT AS 部門,  
    SALARY AS 工資  
FROM  
(  
    --姓名    部門  工資  
    VALUES  
    ('張三','市場部',4000),  
    ('趙紅','技術部',2000),  
    ('李四','市場部',5000),  
    ('李白','技術部',5000),  
    ('王五','市場部',NULL),  
    ('王藍','技術部',4000)  
) AS EMPLOY(NAME,DEPT,SALARY);  
   
查詢結果如下:  
   
RN  RK   D_RK     姓名       部門       工資  
1     1     1     王五       市場部    (null)  
2     2     2     李四       市場部    5000  
3     2     2     李白       技術部    5000  
4     4     3     張三       市場部    4000  
5     4     3     王藍       技術部    4000  
6     6     4     趙紅       技術部    2000  

請注意ROW_NUMBER和RANK之間的區別,RANK是等級,排名的意思,李四和李白的工資都是5000,他們並列排名第二。張三和王藍的工資都是4000,怎麼RANK函式的排名是第四,而DENSE_RANK的排名是第三呢?這正是這兩個函式之間的區別。由於有兩個第二名,所以RANK函式預設沒有第三名。

  現在又有個新問題,假設讓你查詢一下每個員工的工資以及工資小於他的所有員工的平均工資,該怎麼辦呢?怎麼?沒聽明白問題?不要緊,請看下面的SQL:

CREATE TABLE IFS_CUSTSHARE  (
		  CUSTID VARCHAR(23) NOT NULL , 
		  OWNERID VARCHAR(23) NOT NULL , 
		  BRID VARCHAR(23) , 
		  SUBBANKID VARCHAR(23) , 
		  RIGHTFLAG VARCHAR(6) ) 
		  
		  SELECT  
    NAME AS 姓名,  
    SALARY AS 工資,  
    SUM(SALARY) OVER(ORDER BY SALARY NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS 小於本人工資的總額,  
    SUM(SALARY) OVER(ORDER BY SALARY NULLS FIRST ROWS BETWEEN  CURRENT ROW AND UNBOUNDED FOLLOWING) AS 大於本人工資的總額,  
    SUM(SALARY) OVER(ORDER BY SALARY NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS 工資總額1,  
    SUM(SALARY) OVER() AS 工資總額2  
FROM  
(  
    --姓名    部門  工資  
    VALUES  
    ('張三','市場部',4000),  
    ('趙紅','技術部',2000),  
    ('李四','市場部',5000),  
    ('李白','技術部',5000),  
    ('王五','市場部',NULL),  
    ('王藍','技術部',4000)  
) AS EMPLOY(NAME,DEPT,SALARY);  

查詢結果如下:  
   
姓名       工資       小於本人工資的總額    大於本人工資的總額    工資總額1     工資總額2  
王五       (null)     (null)             20000              20000            20000  
趙紅       2000       2000               20000              20000            20000  
張三       4000       6000               18000              20000            20000  
王藍       4000       10000              14000              20000            20000  
李四       5000       15000              10000              20000            20000  
李白       5000       20000              5000               20000            20000  

上面SQL 中的OVER部分出現了一個ROWS子句,我們先來看一下ROWS子句的結構:

  1. ROWS BETWEEN <上限條件> AND <下限條件>  
  2. 其中“上限條件”可以是如下關鍵字:  
  3. UNBOUNDED PRECEDING  
  4. <number>  PRECEDING  
  5. CURRENT ROW  
  6. “下線條件”可以是如下關鍵字:  
  7. CURRENT ROW  
  8. <number> FOLLOWING  
  9. UNBOUNDED FOLLOWING  
注意,以上關鍵字都是相對當前行的,UNBOUNDED PRECEDING表示當前行前面的所有行,也就是說沒有上限;<number>  PRECEDING表示從當前行開始到它前面的<number>行為止,例如,number=2,表示的是當前行前面的2行;CURRENT ROW表示當前行。至於其它兩個關鍵字,我想,不用我說,你也應該知道了吧。如果你還不明白,請仔細分析上面SQL的查詢結果。
 OVER表示式還可以有個子句,那就是RANGE,它的使用方式和ROWS 十分相似,或者說一模一樣,作用也差多不,不過有點區別,如下所示:

RANGE BETWEEN <上限條件> AND <下限條件>

其中的<上限條件> 、<下限條件>ROWS一模一樣,如下的SQL演示它們之間的區別:

SELECT  
    NAME AS 姓名,  
    DEPT AS 部門,  
    SALARY AS 工資,  
    FIRST_VALUE(SALARY, 'IGNORE NULLS') OVER(PARTITION BY DEPT) AS 部門最低工資,  
    LAST_VALUE(SALARY, 'RESPECT NULLS') OVER(PARTITION BY DEPT) AS 部門最高工資,  
    SUM(SALARY) OVER(ORDER BY SALARY ROWS BETWEEN 1 PRECEDING  AND 1 FOLLOWING) AS ROWS,  
    SUM(SALARY) OVER(ORDER BY SALARY RANGE BETWEEN 500 PRECEDING AND 500 FOLLOWING) AS RANGE  
FROM  
(  
    --姓名    部門  工資  
    VALUES  
    ('張三','市場部',2000),  
    ('趙紅','技術部',2400),  
    ('李四','市場部',3000),  
    ('李白','技術部',3200),  
    ('王五','市場部',4000),  
    ('王藍','技術部',5000)  
) AS EMPLOY(NAME,DEPT,SALARY);  
   
查詢結果如下:  
   
姓名       部門       工資       部門最低工資       部門最高工資       ROWS    RANGE  
張三       市場部    2000       2000              4000             4400       4400  
趙紅       技術部    2400       2400              5000             7400       4400  
李四       市場部    3000       2000              4000             8600       6200  
李白       技術部    3200       2400              5000             10200     6200  
王五       市場部    4000       2000              4000             12200     4000  
王藍       技術部    5000       2400              5000             9000       5000  

上面SQLRANGE子句的作用是定義一個工資範圍,這個範圍的上限是當前行的工資-500,下限是當前行工資+500。例如:李四的工資是3000,所以上限是3000-500=2500,下限是3000+500=3500,那麼有誰的工資在2500-3500這個範圍呢?只有李四和李白,所以RANGE列的值就是3000(李四)+3200(李白)=6200。以上就是ROWSRANGE得區別。

 上面的SQL 還用到了FIRST_VALUE和LAST_VALUE兩個函式,它們的作用也非常簡單,用來求OVER 定義集合的最小值和最大值。值得注意的是這兩個函式有個引數,'IGNORE NULLS' 或 'RESPECT NULLS',它們的作用正如它們的名字一樣,用來忽略NULL值和考慮NULL值。

  還有兩個函式我們沒有介紹,LAG和LEAD,這兩個函式的功能非常強大,請看下面SQL:

SELECT  
    NAME AS 姓名,  
    SALARY AS 工資,  
    LAG(SALARY,0) OVER(ORDER BY SALARY) AS LAG0,  
    LAG(SALARY) OVER(ORDER BY SALARY) AS LAG1,  
    LAG(SALARY,2) OVER(ORDER BY SALARY) AS LAG2,  
    LAG(SALARY,3,0,'IGNORE NULLS') OVER(ORDER BY SALARY) AS LAG3,  
    LAG(SALARY,4,-1,'RESPECT NULLS') OVER(ORDER BY SALARY) AS LAG4,  
    LEAD(SALARY) OVER(ORDER BY SALARY) AS LEAD  
FROM  
(  
    --姓名    部門  工資  
    VALUES  
    ('張三','市場部',2000),  
    ('趙紅','技術部',2400),  
    ('李四','市場部',3000),  
    ('李白','技術部',3200),  
    ('王五','市場部',4000),  
    ('王藍','技術部',5000)  
) AS EMPLOY(NAME,DEPT,SALARY);  
   
查詢結果如下:  
   
姓名       工資       LAG0      LAG1      LAG2      LAG3      LAG4      LEAD  
張三       2000       2000      (null)   (null)       0       -1        2400  
趙紅       2400       2400       2000    (null)       0       -1        3000  
李四       3000       3000       2400     2000       0        -1        3200  
李白       3200       3200       3000     2400       2000     -1        4000  
王五       4000       4000       3200     3000       2400     2000      5000  
王藍       5000       5000       4000     3200       3000     2400      (null)  

 我們先來看一下LAG 和 LEAD 函式的宣告,如下:

LAG(表示式或欄位, 偏移量, 預設值, IGNORE NULLS或RESPECT NULLS)

LAG是向下偏移,LEAD是想上偏移,大家看一下上面SQL的查詢結果就一目瞭然了。

  到此為止,有關DB2 OLAP 函式的所有知識都介紹給大家了,下面我們再次回顧一下 DB2 線上分析處理 的組成部分,如下:

函式 OVER(PARTITION BY 子句 ORDER BY 子句 ROWS或RANGE子句)

要想熟練掌握這些知識還需要一定的時間和練習,一旦你掌握了,你將擁有一項絕世武學,可以縱橫DB2。

http://www.ibm.com/developerworks/data/library/techarticle/dm-0401kuznetsov/
http://www.cnblogs.com/Fskjb/archive/2011/02/28/1967429.html