Shell指令碼和Informix的互動實現技巧

來源:互聯網
上載者:User

在Linux/Unix下一些程式是命令列或者服務程式,一般都有一個設定檔來描述其運行規則,而這些規則通常會儲存在資料庫中,由其它應用程式來維護。這就牽涉一個問題,如何從資料庫中擷取最新的規則來驅動背景程式。同樣背景程式運行結束後,產生的結果有時需要寫回資料庫,以便其它應用程式讀取。

  通過閱讀本文章,讀者能瞭解Shell指令碼和Informix互動的一些常用技巧和方法,實現諸如查詢、增加、刪除、修改資料功能,最終實現資料庫、背景程式之間的資訊互動。

  1. Informix簡要介紹

  Informix是IBM公司出品的關聯式資料庫管理系統(RDBMS)家族。作為一個整合解決方案,它被定位為作為IBM線上交易處理(OLTP)旗艦級資料服務系統。 IBM對Informix和DB2都有長遠的規劃,兩個資料庫產品互相吸取對方的技術優勢。目前最新版本的是Informix 11.7,這個最新的版本在未來十年對IBM Informix繼續提供力量,其引擎有效解決OLTP,決定了可以更好的支援各種規模的企業和夥伴的決策支援應用。

  2.Linux/Unix Shell簡要介紹

  Linux/Unix Shell也叫做命令列介面,是一種控制系統的指令碼語言。它是Linux/Unix作業系統下傳統的使用者和電腦的互動介面。使用者直接輸入命令來執行各種各樣的任務,隱藏了作業系統低層的細節。

  Shell的主要功能:命令執行、輸入/輸出重新導向、環境控制、幕後處理、Shell指令碼。

  3.Shell與Informix互動的基本方法

  Shell通過調用dbaccess在Informix上執行各種SQL,而通過調用dbload可以將檔案載入到資料庫中。

  3.1. 通過dbaccess串連資料庫

  dbaccess提供了用於輸入、執行和調試結構化查詢語言 (SQL)(SQL)語句與預存程序語言(SPL)常式的使用者介面。假設聯機的資料庫伺服器包含一個名為mystores的資料庫,要使mystores資料庫成為當前資料庫,可以通過db2access mystores來啟動DB-Access.也可以通過命令dbaccess //xyz/newstores 串連到xyz資料庫伺服器上的newstores資料庫(未聯機)。

  3.2. 通過dbaccess執行SQL

  當從命令列調用dbaccess時,可以指定某個資料庫作為當前的資料庫、執行包含一個或多個SQL語句的檔案以及顯示多個層級的錯誤資訊。

  例1:dbaccess test insert.sql

  表示:在test資料庫執行名為insert.sql的檔案中SQL語句的命令。

  例2:dbaccess - insert.sql

  表示:在insert.sql上檔案中指定的資料庫上執行檔案中的SQL語句的命令。

  下面函數被調用後,調用dbaccess來執行相關的SQL並將結果輸出到標準輸出中。

  清單1

  ExecuteSqlSelect()

  {

  sqltxt="$1";

  pre_sql="output to pipe cat without headings ";

  sqltxt=$pre_sql"$sqltxt";

  echo "$sqltxt"|dbaccess test 2>/dev/null;

  }  

       在清單1的代碼中,$1 表示函數的第1個參數,在這裡第1個參數為要執行的SQL語句;pre_sql變數中的代碼是用來屏蔽dbaccess執行時輸出的作業記錄資訊,如果不加此設定,不會影響函數執行結果,只是執行過程中出現很多dbaccess作業記錄資訊。

  echo "$sqltxt"|dbaccess test 2>/dev/null

        表示用dbaccess命令串連test資料庫,然後執行$sqltxt語句,並將錯誤輸出到/dev/null。

  上面函數在Shell中調用方式如下:

  User_name=`ExecuteSqlSelect "select user_name from t_test;"`;  

3.3. 利用Shell調用dbaccess匯出記錄

  下面函數被調用後,會執行傳入的SQL並將結果匯出到一個檔案中。

  清單2

  ExecuteSqlUnloadFile()

  {

  sqltxt="$1";

  unload_file="$2";

  temp_file="$3";

  pre_sql="unload to $unload_file delimiter ',' ";

  post_sql="";

  echo $pre_sql > $temp_file;

  echo "$sqltxt" >> $temp_file;

  echo $post_sql >> $temp_file;

  dbaccess testdb < $temp_file 2>/dev/null;

  rm -f $temp_file;

  }  

       在清單2的代碼中,$1 、$2 、$3表示函數的第1個、第2個、第3個參數。

  第1個參數為SQL語句。

  第2個參數為輸出檔案名稱。

  第3個參數為臨時檔案名稱(執行結束會被刪除)。

  unload to $unload_file delimiter ',' 表示記錄匯出時存為檔案名稱為$unload_file的檔案,在這裡記錄之間的分隔字元用逗號表示。

  $temp_file檔案為臨時檔案,用來儲存SQL語句,在函數執行末尾其內容將被刪除。

  dbaccess testdb < $temp_file 2>/dev/null表示用dbaccess命令串連testdb資料庫,然後執行$temp_file檔案中的SQL語句,並將錯誤輸出到/dev/null。

  上面函數在Shell中調用方式如下:

  ExecuteSqlUnloadFile "select c1,c2 from t_test" "t_test.dat" "t_test.tmp";

  3.4. 利用dbload匯入檔案

  dbload的功能是將一至多個ASCII檔案中的資料傳送到一至多個已有的表中。

  文法為:dbload [-d dbname ] [-c cfilename] [-l logfile] [-e errnum] [-n nnum] [-i inum] [-s] [-p] [-r] [-k] [-X]。

  其中主要選項說明如下:

  -d dbname 指定接收資料的資料庫名

  -c cfilename 指定指定dbload命令檔案的檔案名稱

  -l logfile 指定錯誤記錄檔檔案的檔案名稱

  -r 在裝入資料期間允許其他使用者修改表中資料(裝入資料期間不封鎖表)

  -s 指示dbload 檢查命令檔案中語句的文法,而不插入資料

  -i inum 指示dbload忽略指定數目的行數

  -n nnum 指示dbload在插入指定數目的新行後提交操作

  -e errnum 指定dbload 中止前可讀入的壞行數

  -p 如果壞行數超過了極限,給出提示資訊,請使用者指定解決方案

  例如: dbload -d testdb -c load.ctl -n 10000 -l error.log。這個命令表示將按照load.ctl控制檔案的指示,載入資料到testdb 資料庫中, 每10000條記錄提交一次,錯誤資料將寫入error.log檔案。以下是load.ctl控制檔案的內容。

  清單3

  FILE crm.dat DELIMITER '|' 3;

  INSERT INTO data_crm_list;  

       清單3中的內容表示將crm.dat資料檔案載入到data_crm_list表中,分隔字元是'|', 資料欄位個數為3。

 

4. Shell與Informix互動執行個體
  通過第三章的介紹,讀者已經基本瞭解Shell與Informix的互動方式。在本章中,作者將通過一個具體執行個體展現Shell與Informix互動過程。

  4.1. 情境概述

  指令碼名稱:test.sh

  示範步驟:

  A:先在Informix中建立2個表,分別為t_test和t_test2;

  t_test表結構:

  CREATE TABLE t_test

  (

  user_code VARCHAR(20),

  user_name VARCHAR(20),

  user_desc VARCHAR(50)

  )  t_test2表結構:

  CREATE TABLE t_test2

  (

  user_code VARCHAR(20),

  user_name VARCHAR(20),

  user_desc VARCHAR(50)

  )  B:在t_test中插入2條記錄;

  insert into t_test values('1001','test','this is a test')

  insert into t_test values('1002','guess','this is a test')  C:在Linux終端下執行test.sh指令碼。

  運行結果:

  A:指令碼會讀取t_test表中的2條記錄,並匯出為檔案t_test.dat;

  B:t_test.dat檔案被匯入t_test2表中,此時t_test2記錄數和t_test一樣。

  4.2. 完整代碼和注釋

  #!/usr/bin/env bash

  DBTOOL="dbaccess"

  DBCONNT="test"

  #功能說明:執行SQL並將結果匯出到一個檔案中

  #參數說明:

  # 第1個參數為SQL語句

  # 第2個參數為輸出檔案名稱

  # 第3個參數為臨時檔案名稱(執行結束會被刪除)

  ExecuteSqlUnloadFile()

  {

  sqltxt="$1";

  unload_file="$2";

  temp_file="$3";

  pre_sql="SET LOCK MODE TO WAIT 10 ;unload to $unload_file delimiter ',' ";

  post_sql="";

  echo $pre_sql > $temp_file;

  echo "$sqltxt" >> $temp_file;

  echo $post_sql >> $temp_file;

  $DBTOOL $DBCONNT < $temp_file 2>/dev/null;

  rm -f $temp_file;

  }

  #功能說明:執行SQL

  #參數說明:

  # 第1個參數為SQL語句

  ExecuteSqlSelect()

  {

  sqltxt="$1";

  pre_sql="SET LOCK MODE TO WAIT 10 ;output to pipe cat without headings ";

  sqltxt=$pre_sql"$sqltxt";

  echo "$sqltxt"|$DBTOOL $DBCONNT 2>/dev/null;

  }

  #功能說明:去掉變數的前後空白

  trim()

  {

  echo $1 |sed 's/^ \+//'|sed 's/ \+$//'

  }

  #功能說明:得到t_test指定記錄中某個欄位的值

  get_username_bycode()

  {

  user_code="$1";

  EXECSQL="select user_name

  from t_test

  where user_code="$user_code";";

  echo $EXECSQL

  user_name=`ExecuteSqlSelect "$EXECSQL"`;

  user_name=`trim $user_name`;

  echo "user_name:["$user_name"]";

  }

  #功能說明:得到t_test中所有記錄,並匯出為檔案t_test.dat

  get_all_username()

  {

  EXECSQL="select user_code,user_name,user_desc

  from t_test;";

  echo $EXECSQL

  ExecuteSqlUnloadFile "$EXECSQL" "t_test.dat" "username.tmp";

  }

  #功能說明:產生入庫設定檔

  #參數說明:

  # 第1個參數為需入庫的表名稱

  # 第2個參數為待入庫的檔案名稱

  # 第3個參數為檔案分隔字元

  # 第4個參數為檔案列個數

  make_loader()

  {

  table_name=$1

  data_name=$2

  sep=$3

  tab_num=$4

  echo "file \"$data_name\" delimiter \"$sep\" $tab_num;" > $CTL_FILE;

  echo "insert into $table_name;" >> $CTL_FILE;

  }

  #功能說明:按照入庫配置要求,將資料匯入表中

  #參數說明:

  # 第1個參數為bad檔案

  # 第2個參數為log檔案

  start_loader()

  {

  badfile_name=$1;

  logfile_name=$2;

  #這裡的10000是指多少條資料commit一次,可以根據實際情況調節大小。

  dbload -d $DBCONNT -c "$CTL_FILE" -l "$badfile_name" -n 10000;

  }

  run()

  {

  #得到使用者編號為1001的使用者名稱稱

  get_username_bycode "1001";

  #得到t_test表中使用者編號、使用者名稱稱、使用者描述資訊,並儲存到t_test.dat檔案中

  get_all_username;

  #通過awk將t_test.dat最後一列轉換為大寫字母

  `cat t_test.dat | awk -F',' -v OFS=',' '{print $1,$2,toupper($3)}' > t_test2.dat`

  CTL_FILE="./t_test2.ctl"

  #產生入庫配置

  make_loader "t_test2" "./t_test2.dat" "," "3";

  #執行入庫

  start_loader "./t_test2.bad" "./t_test2.log";

  }

  #--------------------主程式--------------------

  run;

 

4.3. 運行結果與分析
  test @ dwserver : /home/test /sgy $ ls -l

  總計 4

  -rwxr-xr-x 1 testtest 2683 05-04 14:37 test.sh

  test @ dwserver : /home/test /sgy $ ./test.sh --------執行test.sh

  select user_name from t_test where user_code=1001;----49行代碼輸出

  user_name:[test] ----52行代碼輸出

  select user_code,user_name,user_desc from t_test; ----59行代碼輸出

  DBLOAD Load Utility INFORMIX-SQL Version 10.00.UC5 ---DBLOAD運行輸出

  Copyright IBM Corporation 1996, 2004 All rights reserved

  Software Serial Number AAA#B000000

  Table t_test2 had 2 row(s) loaded into it.

  test @ dwserver : /home/test /sgy $ ls -l

  總計 16

  -rwxr-xr-x 1 testdba 2683 05-04 14:37 test.sh

  -rw-r--r-- 1 test dba 0 05-04 14:38 t_test2.bad

  -rw-r--r-- 1 test dba 59 05-04 14:38 t_test2.ctl

  -rw-r--r-- 1 test dba 51 05-04 14:38 t_test2.dat

  -rw-r--r-- 1 test dba 53 05-04 14:38 t_test.dat

  test @ dwserver : /home/test /sgy $ head t_test2.ctl ----入庫設定檔

  file "./t_test2.dat" delimiter "," 3;

  insert into t_test2;

  test @ dwserver : /home/test /sgy $ head t_test.dat ----匯出的t_test記錄

  1001,test,this is a test

  1002,guess,this is a test

  test @ dwserver : /home/test /sgy $ head t_test2.dat ----經過99行awk處理後的記錄

  1001,test,THIS IS A TEST

  1002,guess,THIS IS A TEST  運行結束後,t_test2表中多出2條記錄,且user_desc欄位的值為大寫。

  結束語

  本文主要介紹了Linux/Unix下Shell如何?Informix資料庫的互動。文章首先對Informix和Shell進行了簡單介紹,然後通過介紹dbaccess和dbload兩個應用程式的用法來使讀者對Shell和Informix互動有一個基本認識。文章最後以一個完整的執行個體來展示Shell和Informix的各種互動,使讀者加深理解,在例子中會用到awk、sed來對資料格式化,這些工具的加入使得Shell處理很多應用時更加強大,所以在實際各種應用中,Shell會結合awk、sed等工具來實現對資料庫中匯出的資訊格式化,或者在檔案匯入資料庫之前對檔案中記錄進行格式化。

  作者介紹

  張曉丹,IBM CDL軟體工程師, 具有豐富的自動化測試經驗、RQM應用經驗、BI項目測試經驗、以及Web application開發經驗。

  程平平,IBM CDL 軟體工程師,主要從事 Optim Query Tuner 產品開發工作,在Eclipse外掛程式開發有一定的經驗。

  王蘋, IBM CDL 軟體工程師,主要從事 DB2 for z/OS產品功能測試工作,在資料庫應用和自動化測試載入器開發方面有一定的經驗。

 

 

     

本篇文章來源於 Linux公社網站(www.linuxidc.com)  原文連結:http://www.linuxidc.com/Linux/2012-06/63345.htm

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.