Friday, December 03, 2010

修改SharePoint網站之清單"建立者"欄位

Environment
Server: Win2003 + SharePoint Service 3

需求: 當透過WSS UI的「儲存清單為範本」+「包括內容」選項將清單匯出後,再匯入時,所有清單項目的「建立者」欄位都會變成匯入人的名字。如果資訊人員佛心來的想替使用者改掉... 是可以做的,寫程式囉。

利用Microsoft提供的SharePoint API: Microsoft.SharePoint.dll。這支dll可以在SharePoint server上的\\Computer_Name\Drive$\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI 內找到。

但是,如果你覺得把他複製出來到自己本機開發那就錯了。這麼做應該會遇到「無法載入檔案或組件或其相依性的其中之一」的錯誤,就像這篇SharePoint Forums上的討論,請直接在裝有SharePoint Service的server上做開發.. 如果有測試機器是再好不過的,就可以參考這篇文章(Can we update the values of “Created By”, "Modified By” columns in SharePoint lists?)直接在Visual Studio上參考上述組件做開發。

如果你正好沒有測試環境,而且也無法在production上安裝VisualStudio這麼龐大的怪物的話,就參考這篇文章(Updating the “Created By” and "Modified By” Columns in SharePoint lists using POWERSHELL)。沒錯! 就是用POWERSHELL。這也是我用的方法。

script:

   1:  # Get the SharePoint Assembly 


   2:  # You will need to run this on the SharePoint Server


   3:  [Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") 


   4:   


   5:  # create a new object called $SPSite


   6:  # Make sure you have the last “/” in the url on the site 


   7:  # allow $SPWeb to be the OpenWeb from the site


   8:  $SPSite = New-Object Microsoft.SharePoint.SPSite("http://server-name/")


   9:  $SPWeb = $SPSite.OpenWeb() 


  10:   


  11:  # Get the list ModifyCreatedBy 


  12:  $SPList = $SPWeb.Lists["ListName"] 


  13:   


  14:  # Get the Collection of the List Items


  15:  $SPListItemCollection = $SPList.Items 


  16:   


  17:  # iterate the Collection


  18:  foreach ($ListItem in $SPListItemCollection) 


  19:  {


  20:   


  21:    # The user in this case was UserA with id of 8 from the SPWeb users 


  22:    $SPFieldUserValue = New-Object Microsoft.SharePoint.SPFieldUserValue($SPWeb,8,"UserA") 


  23:   


  24:    $ListItem["Author"] = $SPFieldUserValue


  25:   


  26:    # Note: Editor will be the account that you are running the Powershell under unless you update Editor as well 


  27:    # ListItem["Editor"] = $SPFieldUserValue


  28:   


  29:    $ListItem.Update() 


  30:  } 


  31:   


  32:  $SPWeb.Update() 


  33:   


  34:  # Still TODO Disposes, Error Checking, Change to take Parameters, etc


  35:   



 
上面的script是改了整個指定清單的建立者欄位,如果你還需要先判斷是那些文件,可以參考一下MSDN Library看看SPListItem還有哪些properities可以用。若是powershell語法不熟的話(尤其他又喜歡跟一般語法同.... 特別是比較運算子...),請參考reference#4, #5,或自行google。



嗯.. 大概就以上資訊,即可作業!!



Ref:




  1. [SharePoint Forums] Could not find Microsoft.SharePoint.Library.dll


  2. [MSDN Blog] Can we update the values of “Created By”, "Modified By” columns in SharePoint lists?


  3. [MSDN Blog] Updating the “Created By” and "Modified By” Columns in SharePoint lists using POWERSHELL


  4. [TechNet 技術文件庫] Running Windows PowerShell Scripts


  5. [賴榮樞的軟體資訊誌] scripting_PowerShell tag


  6. [MSDN Library] Microsoft.SharePoint Namespace

Monday, November 15, 2010

poppassd + roundcube on FreeBSD

最近因為被roundcube的美貌所吸引,所以正在考慮是否拿它來當webmail。roundcube最大的特點就是: 相當美+相當陽春。

紀錄一下poppassd跟roundcube怎麼搭配,讓使用者可以在web介面上直接改密碼,而不需要登入freebsd系統.. roundcube的安裝部分就不介紹了,直接來poppassd的部分。

Environment:
OS: FreeBSD 8.1-RELEASE-p1
roundcube: 0.4.2
poppassd: 4.0_3

STEP1: Install poppassd

# cd /usr/ports/mail/poppassd/
# make install clean

By default, you can find the binary in /usr/local/libexec

STEP2: Startup setting

# man poppassd

Modify /etc/inetd.conf AND /etc/services AND /etc/syslog.conf as describe in the man page.

STEP3: Auto-start inetd when reboot
Modify /etc/rc.conf AND add:

# inetd

inetd_enable="YES"

STEP4: restart inetd

# /etc/rc.d/inetd restart

 

STEP5: Config roundcube plugin
Modify /usr/local/www/roundcube/plugins/password/config.inc.php

// Select a driver to use, see README for more driver name

$rcmail_config['password_driver'] = 'poppassd';

STEP6: Add roundcube plugin
Modify /usr/local/www/roundcube/config/main.inc.php

// List of active plugins (in plugins/ directory)
$rcmail_config['plugins'] = array('password');

STEP FINAL: Restart roundcube and apache

 

Ref:

  1. [FRESH ports] poppassd
  2. Poppassd – Installation and Management Guide
  3. roundcube wiki – plugins/password
Thursday, October 21, 2010

iSCSI target crash when selecting ‘Device’ node

OS: Windows Storage Server 2003 R2
iSCSI target version: 3.1.3412

如題,一個很久以前就注意到的問題,不過因為沒有急迫性,就一直不理他XD。這兩天因為要整理一些空間出來用,只好處理一下。

於是找到一篇HP論壇裡的討論串,裡面有人提到是微軟的一個更新造成的...

請找KB973507

這個更新是2009/8/11出來的,如果有人遇到同樣的問題,大概也是這個時點之後,把這個更新移除後重開機,iSCSI target就可以正常使用了~

另外也有一份文件提到:

Issue: Installing Microsoft security update KB973507 results in the Microsoft iSCSI Software Target not displaying
iSCSI target devices when the Devices node is selected in the iSCSI Target management console.

Ref:

  1. [HP IT Resource Center Forums] AiO 600 - problem with Microsoft iSCSI target snapin
  2. [pdf] HP StorageWorks P4000 Unified NAS Gateway Release Notes
Thursday, September 30, 2010

Oracle shutdown hangs: forgot the ‘immediate’ option

一個簡單的小問題,不過還滿常發生的=   =||

一般需要關閉資料庫時,都會下'shutdown immediate’指令,有了immediate選項,Oracle不需等待所有連線關閉。反之,若只有下'shutdown'指令,也就是'shutdown normal',Oracle就會等到所有連線都結束後才關閉,通常都關不下來... 這時候就算又開了新的連線想重下指令,都會收到類似"Not connected to Oracle"這類的訊息.. 這時候!!

可以另外開一個新連線這麼做:

SQL> conn sys as sysdba
輸入密碼:
連線至閒置的執行處理.
SQL> startup force
已啟動 ORACLE 執行處理.
……(資料庫已掛載./資料庫已開啟.)
SQL> shutdown immediate

這樣就可以成功的把資料庫關下來囉~

另一邊原本正在shutdown的視窗可能會看見如下過程:

SQL> shutdown
ORA-03113: 通訊通道上出現 EOF

SQL> ^F^D
SP2-0042: 未知的命令 "" - 此行的剩餘部份被略過不予處理

完工!

Thursday, September 16, 2010

office: 使用萬用字元進行尋找/取代作業

今天發現office的尋找功能還滿強大的,介紹一些使用萬用字元搜尋/取代的方法:首先最基本的就是要會打開「尋找及取代」的視窗XD,在「更多(M)>>」選項裡把「使用萬用字元(U)」選項給勾起來。

  • 尋找符合「HH:MM:SS」的時間格式: 最簡易且不嚴謹的寫法可以用「??:??:??」。「?」表示任何單一字元,所以如果你的文件裡有「AA:BB:CC」這樣的字串,它也會符合尋找目標,但卻不符合我們只想尋找時間格式的目的。所以可以改寫成「[0-9]{2}:[0-9]{2}:[0-9]{2}」,就是三組「[0-9]{2}」被兩個冒號隔開來,其中「[0-9]」表示0到9之間的其中一個數字,「{2}」表示前一個字元或運算式必須出現2次。所以利用三組「[0-9]{2}」與冒號就可以找出符合的格式。
  • 在找到的「HH:MM:SS」時間格式前後加上「*」: 這時候就要需要取代功能的搭配了。在取代的頁籤裡,「取代為」的表示式該怎麼寫呢? 我希望找到所有的符合的時間格式並在他前後加上星號,卻不希望更改了時間的值。一開始嘗試用「*[0-9]{2}:[0-9]{2}:[0-9]{2}*」,結果他就把所有時間格式整個直接取代成「*[0-9]{2}:[0-9]{2}:[0-9]{2}*」的字樣OTZ。正確做法應該是把尋找目標寫成「([0-9]{2}):([0-9]{2}):([0-9]{2})」, 取代寫成「*\1:\2:\3*」。「\1」, 「\2」, 「\3」依序代表尋找目標的三組括號裡的值! 這個技巧主要用在你真正的目的不是「取代」,而是利用尋找到的目標再做一些位置上的變化或像此處加上其他字元符號的應用。

以上兩個就是今天有用到的精隨啦~ 當然還有很多種變化,像是{2,}則表示前面的字元或運算式至少要出現2次,若是{2,4}就表示前面的字元或運算式須出現2-4次。另外在不使用萬用字元的情況下也可用「代碼」來尋找特殊的格式或字元:

  • 將空白行去除: 搜尋目標以「^p^p」表示(記得不必勾「使用萬用字元(U)」)。一個「^p」表示一個換行符號,兩個「^p^p」就會空一行,所以將「^p^p」取代為「^p」,就可以將空白行去掉了。

其他還有許多用法請參閱reference。

 

Ref:

  1. Office產品支援中心: 尋找及取代文字或其他項目
Wednesday, September 01, 2010

(ORA-01031) Cannot create/edit view with the owner of the schema

environment: enterprise linux + oracle11gr2

前情提要:
userA先生在9i的時代運作得相當正常,當然包含本篇所要探討的小小新建一個view的動作。升級到11g之後某天,卻發現userA再也無法在自己的schema下create view... 這麼小小一件事情都辦不到!!! 檢查了權限也跟9i時代完全相同(就是CONNECT, RESOURCE, UNLIMITED TABLESPACE這麼簡單,所以也沒把腦筋動到權限上),なんで??? 當時為了應急直接用dba帳號幫他處理掉了,今天又遇到一次,該是要面對的時候了..

一開始看到的都是在說"物件的權限需要直接grant給指定的人,不要透過角色(ROLE)來做"這件事情,因為在所有stroe procedures或PL/SQL block裡,角色權限是不會起作用的(All roles are disabled inside stored procedures.)等,不過這並不是我的情況..

無意間看到這篇文章在探討Oracle的Role包含了那些權限,才恍然大悟...

9ir2的CONNECT角色裡包含了"CREATE VIEW"的權限,但在11g裡,CONNECT的角色卻只剩下"CREATE SESSION"的權限... 就這麼簡單... 所以在11g要另外把CREATE VIEW的權限grant給userA先生,這樣就可以正常新建/修改view了... 就這樣orz

若要詳細列出角色所包含的權限,可使用以下查詢:

SQL> select * from ROLE_SYS_PRIVS where role='CONNECT';
(ROLE_SYS_PRIVS: 列出登入帳號所有擁的角色,及角色所包含的系統權限)

或者也可以這樣查:

SQL> select * from DBA_SYS_PRIVS where grantee='CONNECT';
(DBA_SYS_PRIVS: 列出所有user/role所擁有的系統權限)

Wednesday, August 25, 2010

Error: 5243: An inconsistency was detected during an internal operation.

Environment: WinServer2008 SP2+SQL Server 2008

昨天檢查SQL Server的時候在記錄檔裡看見一整串長相不凡的訊息... 大概長這樣:

ex_raise2: Exception raised, major=52, minor=43, state=8, severity=22, attempting to create symptom dump
Using 'dbghelp.dll' version '4.0.5'
***Stack Dump being sent to D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\LOG\SQLDump0001.txt
... (略)
錯誤: 5243,嚴重性: 22,狀態: 8。
An inconsistency was detected during an internal operation. Please contact technical support.

最明顯的訊息大概就最後兩行了吧... 另外一個dump file內容更是人類無法閱讀=   =,明顯是要給機器讀的。

先是找到這篇: M$技術支援, Article ID:828337: An assertion or Msg 7987 may occur when an operation is performed on an instance of SQL Server.
標題看起來不怎麼有關係,不過內容確實有一些蛛絲馬跡。最早在SQL Server2000執行SELECT或UPDATE之類的transact-SQL時,就可能會有3624的錯誤訊息,而同樣的錯誤在SQL Server2005, 2008則是錯誤5242或5243。

造成5242/5243錯誤的原因只有簡單一小行: The problem may occur if inconsistencies exist in the databases on the instance of SQL Server....
還好相當有良心的還有solution..

  1. On the instance of SQL Server where the failure occurred, run the DBCC CHECKDB Transact-SQL command on all the databases.
  2. If the DBCC CHECKDB Transact-SQL command reports errors that indicate database inconsistencies, resolve the errors.

哈哈哈(乾笑三聲)... 一點都沒有好人做到底,送佛送到西的精神XD,連CHECKDB都不認識請參閱這兒(2000)或這兒(2008)。

所以就找了時間針對SQL Server裡的每個資料庫跑了下面這串指令。

DBCC CHECKDB(‘DB_NAME’) WITH ALL_ERRORMSGS;

(如果資料庫真的相當龐大,建議加個PHYSICAL_ONLY選項..)
結果每個資料庫的檢查結果都正常@_@a.. 雖然是個好消息,不過還是滿令人錯愕的阿XD 資料庫不會平白無故地耍人吧OTZ,所以不死心又多看了幾篇文章,終於,Paul S. Randal先生(SQL Server MVP, 撰寫2005 DBCC CHECKDB的人,這篇文章最後有簡介)給了個比較讓人釋懷的說明

基本上5242跟5243是一樣的錯誤,不過5242會明確指出資料庫的哪個地方出了問題,5243卻是不明原因,資料庫無法指出的錯誤所丟出來的。雖然記錄檔紀錄了相關的訊息,這中間有可能其他的維護作業重建了索引,currupt pages被釋放,所以事後跑checkdb就看不出有任何錯誤。

大致上就這樣囉~

Ref:

  1. Microsoft Support KB828337
  2. MSDN: DBCC CHECKDB (SQL Server2008)
  3. Corruption errors: Msg 5242, Level 22
Thursday, August 05, 2010

[Mobile Phone] EDGE, 3G and HSDPA

筆記一下行動電話通訊技術:

  • GSM(Global System for Mobile Communication), 全球行動通訊系統
    GSM是目前傳統行動電話最廣泛使用的通訊標準,1990年由歐洲電信標準協會(ETSI)制定出第一版標準,發展至今。GSM也是我們熟知的2G--二代行動通訊;二代與前代的最大差異就是在他的信號與語音通道都是數位的。也因為GSM標準的廣泛使用,使全球行動電話廠商間可簽訂"漫遊協定",讓用戶於不同國家也能使用行動電話(使用漫遊服務)。
  • GPRS(General Packet Radio Service), 通用封包無線服務
    GPRS是GSM行動電話用戶可用的一種移動數據服務,約於2000年開始商用,被視為是2.5G。它使用GSM網路中未被使用的TDMA通道,使得GSM系統能夠以效率更高的"封包"方式提供數據通訊,也就是說多個用戶可以共享一個相同的傳輸通道,每個用戶只有在傳輸數據的時候才會佔用通道;所以其計費方式也不同於電路交換的以秒計費,而是以KB計。
  • EDGE(Enhanced Data rates for GSM Evolution), GSM數據速度增強版
    EDGE約於2003年開始商用,亦不屬於GSM網路中,可視為GSM(2G)和GPRS(2.5G)的延伸,所以有時稱為2.75G。EDGE也可寫作EGPRS, Enhanced GPRS, 因為它引進一個GPRS所沒有使用的技術: Incremental Redundancy, 此技術使用更多的冗於資訊來與接收端連接,取代重新發送受干擾的封包,藉此提高解碼的正確性。雖是介於2G與3G間,但是EDGE的數據傳輸最大理論值473.6Kbps已經達到3G標準。
  • 3G(3rd-Generation), 第三代行動通訊
    3G,也就是IMT-2000,是國際電信聯盟(ITU)定義的第三代無線通訊的全球標準,於1988年開始由3GPP制定規範。3G將無線通訊與國際網際網路等多媒體通訊結合,能同時傳送聲音(通話)及數據資訊(電子郵件、即時通訊等)。無線網路必須能夠支持不同的數據傳輸速度,也就是說在室內、室外和行車的環境中能夠分別支持至少2Mbps、 384kbps以及144kbps的傳輸速度。由於採用蜂巢式行動通訊技術,3G標準的通訊質量較之前大幅改善。
  • HSDPA(High-Speed Downlink Packet Access), 高速下行封包存取
    3.5G, 基於3G網路系統,可提供高達7.2mbit/s的數據傳輸速度。

Ref:

  1. [Wiki] GSM
  2. [Wiki] GPRS
  3. [Wiki] EDGE
  4. [Wiki] 3G
  5. [Wiki] HSDPA
  6. [Clove] Guide to GSM, GPRS, EDGE, 3G and HSDPA

The lost July..

消失的七月.. XD 相當不長進的一篇文章都沒有。

Friday, June 11, 2010

Q: What are SQLCODE and SQLERRM and why are they important for PL/SQL developers?

[類別] PL/SQL
[問題] 什麼是SQLCODE與SQLERRM,為什麼他們對PL/SQL開發者而言很重要?

Answer:

SQLCODE與SQLERRM都是用在exception handler裡。

SQLCODE會回傳exception的號碼,SQLERRM則是錯誤訊息內容。
最常見的用法就是搭配WHER OTHERS EXCEPTION使用:

DECLARE

   v_code NUMBER;

   v_errm VARCHAR2(64);

BEGIN

   ………

EXCEPTION

   WHEN OTHERS THEN

        v_code := SQLCODE;

        v_errm := TO_CHAR(SQLERRM(v_code));

        DBMS_OUTPUT.PUTLINE(‘ERRCODE ’ || v_code);

        DBMS_OUTPUT.PUTLINE(‘ERRMSG ’ || v_errm);

END;

重要性? 當然是... 你可以處理exceptions,知道更詳細的訊息囉。

vSphere Client: parsing the server “servername” “clients.xml” file

今天是2010/6/11,如果你在昨天或前天安裝了windows update,而且也有使用vSphere Client,恭喜,他死了=   =

2010-06-11_0012010-06-11_002好似確定是windows update(980773)造成的溜,vm的knowledge base有寫:

vSphere Client does not open on any Windows operating systems with the error: parsing the server "<servername>" "clients.xml" file

並且也在昨天釋放出新版的tools了,記得去更新的溜~

Wednesday, June 09, 2010

新手上路之: read/write NTFS driver for Linux

在進行了一個月的笨蛋異地備份方法之後,實在是受不了了...=   = 用WinSCP透過網路連到linux系統去拉檔案時在是太麻煩了... 尤其單個檔案很大時,超容易失敗OTZ

其實事情好像也滿容易解決的,只是因為對方是production,時在不敢直接在上面做實驗,只好花了兩天自己裝了一台機器,在上面做測試,成功!!

Environment: enterprise linux release5(update5)+ntfs-3g-2010.5.22

  1. 先下載NTFS-3G
  2. 丟到系統內並解壓縮
  3. 直接進入解壓縮的資料夾內,依照文件以root身份做一下三件事情:

    # ./configure
    # make
    # make install

  4. 沒錯! 這個moment就已經完成安裝了
  5. 接著就可以接上USB硬碟,並且辨識一下他的裝置名稱。這本書說linux會把USB視為scsi裝置,所以他的device name會是/dev/sd?(視你原本系統的裝置決定,像我的系統是用IDE硬碟,裝置是hda, hdb開頭,所以第一個scsi裝置就會是sda)
  6. 確定好裝置名稱之後,就可以把它mount起來(以/usb為mountpoint)

    # mount –t ntfs-3g /dev/sda1 /usb

  7. 完工!! =D

Ref:

  1. NTFS-3G
  2. 在Linux下使用USB拇指碟及外接式硬碟
Tuesday, June 01, 2010

Q: When is a DECLARE statement needed?

[類別] PL/SQL
[問題] 什麼時候需用到DECLARE語法?

Answer:
DECLARE是用在PL/SQL區塊(block)內。一個PL/SQL block被DECLARE, BEGIN, EXCEPTION, END四個關鍵字分成三個部份:

DECLARE

  -- Declarative part(optional)

  -- for declartions of local types, variables, subprograms

BEGIN

  -- Executable part(required)

  -- statements

  EXCEPTION

    -- Exception-handling part(optional)

END;

所以,當你有需要宣告變數等,就會把它放在DECLARE的區塊內。

Friday, May 28, 2010

Q: Describe the use of PL/SQL tables.

混了一個禮拜... 該是回來面對這系列問題的時候了... 其實我也不是故意要跳過的=P。因為上禮拜的問題是: "What packages (if any) has Oracle provided for use by developers?" .... 這.. 就算我去讀了一些文件,還是認為自己無法具體的回答... 所以就放棄這題了.. (如果我在面試的時候被問到這個,大概也沒時間拖過一個星期XD)

[類別] PL/SQL
[問題] 請描述PL/SQL tables該如何使用

Answer:
先講講揪竟PL/SQL table(又叫index-by tables)是什麼? 這是它在9iR2以前的稱呼,9iR2起稱為"associative arrays”。他是一種:

  • collection型別
  • 有index
  • 可用BINARY INTEGER或VARCHAR2做索引(indexed/associated)

他跟另一個collection型別: PL/SQL nested tables很相似:

  • 是一維陣列(one-dimensional arrays)
  • 無(大小)限制(unbounded, 理論上...只要記憶體夠大)
  • 同質性(homogeneous, 就是array裡的每個element要一樣型別的意思..)

先來看一下宣告語法,先定義一個型別,接著才宣告變數:

TYPE 型別名稱 IS TABLE OF 一已知存在型別 INDEX BY [BINART_INTEGER | VARCHAR2(5)];

變數名稱 型別名稱;

ex:

TYPE position_table IS TABLE OF VARCHAR2(30) INDEX BY VARCHAR2(10);

who_list position_table;

所以上面我們就定義了一個position_table(使用者定義)data type, 是以字串(string)作index, 然後宣告變數who_list是這個型別。該怎麼使用呢?

who_list('CEO') := ‘Fisher Liang’;

who_list('CDO') := ‘Aileen Wu';

DBMS_OUTPUT.PUT_LINE('The CEO is ' || who_list('CEO'));

這樣~ 'CEO', 'CDO'就是index,而且是unique的,若是重複指定,就是取代舊有值的意思。雖然是個array,用起來卻很像是有index的table對巴~?

PL/SQL Tables/associative arrays只做暫時存放資料用,也不是一個真正的table,並無法對其使用insert或select into等SQL statement。不過可以做到session level的life cycle, 就是把以上宣告及使用放在package裡。

完畢!

Ref:

  1. PLSQL Tutorial – PLSQL Collections
  2. PLSQL Tutorial – Oracle PLSQL Collection Types
  3. PL/SQL User’s Guide and Reference – PL/SQL Collections and Records
  4. [Oracle-Base] Associative Array in Oracle9i Release 2
Thursday, May 20, 2010

Batch file – Delete files by date, count the output of other commands

介紹個相當好用的指令: Forfiles

用途: 檔案選取,並可針對篩選出來的檔案再下其他指令
注意: WinSvr2003, R2, SP1, PS2才有此指令
常用參數: /m SearchMark: Searches files according to SearchMask.
             /c command: Runs the specified Command on each file.
             /d [{+ | -}] [{MM/DD/YYYY | DD}]

假如某個資料夾下每天都會有一個(以上)檔案產生,並且希望定期清理,只保留一個月份的檔案量時,可以用forfiles:

下面這個指令就是刪除日期為30天以前的檔案

> forfile /D –30 /C “cmd /c del @file”
  • /C 這參數預設值是"cmd /c echo @file",也就是只列出檔名。
  • "cmd /c" 是下指令固定的寫法。
  • "@file" 是可以用在/C參數內的變數之一,@file表示檔案名稱。其他還有變數可以列出檔案副檔名(@ext)、完整路徑(@path)、相對路徑(@relpath)、判斷是否為目錄(@isdir)、檔案大小(@fsize)、日期(fdate)、時間(@ftime)等。
  • /D 這參數用法有很多變化(詳請參考reference),"-30"的意思就是30天前。

另外一個是For...DO迴圈語法,用來跟上面的forfiles搭配,可以先計算出forfiles總共篩選出幾個檔案:

> set cnt=0
> FOR /F %G IN(‘forfile /D -10’) DO set /a cnt+=1
  • 上面即是先以forfile找出10天前的檔案,並丟進去for迴圈內
  • DO裡針對每個forfile都把變數cnt加1,所以最後只要echo %cnt%即可得到檔案數目
  • for-do的詳細用法也請參考reference

Ref:

  1. Forfiles
  2. For(loop)
Tuesday, May 18, 2010

Using binding vareable with “LIKE” condition

這感覺就是一個相當簡單又會很常用到的東西... 卻一時寫不出來OTZ

通常我們用到LIKE時,大多就是想做模糊搜尋吧...

像下面這個SQL是要找名字裡包含大寫SM的人:
SELECT * FROM EMPLOYEE WHERE NAME LIKE ‘%SM%’

像上面這樣寫,就變成傳說中的hard coding,有時候為了效能考量,我們要把值的地方以變數(:variable)取代,所以這兩種組合揪竟該怎麼兜在一起呢!?

這樣… LIKE '%:variable%'          (X, :variable直接被當成字串=   =)
這樣… LIKE ''%:variable%''        (X, :variable終於不被當成字串,還是失敗)
這樣… LIKE '%'||:variable||'%'     (O, 原來要自己組....)

Friday, May 14, 2010

BUG! “Environment variable ORACLE_UNQNAME not defined”

Environment:
DB version: Oracle 11gr2
Platform: Linux RedHat EL5

今天本來是在做"Automating Database Startup and Shutdown on Linux" setp by step。照著文件做,也處理了最後"Known Issues"的部分後,發現.... Oracle em(dbconsole)的服務並沒有起來...

也不是什麼大問題,就是dbstart這支script裡並沒有把他寫進去而已,於是自己把他補在"/etc/init.d/dbora"(依照上面文件做的一個檔案)裡面:

su - $ORA_OWNER -c "$ORA_HOME/bin/dbstart $ORA_HOME"
su - $ORA_OWNER -c "$ORA_HOME/bin/emctl start dbconsole” ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^上面這行

補了一行code之後又重機一次,發現竟然還是一樣... 失敗了=   =,如果以oracle的身分直接去跑"emctl start dbconsole"是可以成功的,但是如果一開始是以root的身分切換到oracle去下指令(就是補上的那一行做的事情),會被抱怨:

Environment variable ORACLE_UNQNAME not defined. Please set ORACLE_UNQNAME to database unique name.

ORACLE_UNQNAME... 還真沒看過這個東西... 結果在oracle文件裡看到這是一個BUG(Bug 1716161)!! 不過他只跟你說,把ORACLE_UNQNAME這個環境變數的值設成db_unique_name這個初始化參數而已... how!?!?

再來看另一篇文章,他也是做一樣的事情,並且在最後一個步驟(6.)說明:
在"/etc/profile"裡補上一段code即可!!

if [ $USER = "oracle" ] ; then
if [ $SHELL = "/bin/ksh" ] ; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
export ORACLE_UNQNAME=db_unique_name
umask 022
fi

真的只是個bug!!!!

Ref:

  1. [ORACLE-BASE] Automating Database Startup and Shutdown on Linux
  2. [Oracle Database Readme] section38 “Open Bugs”
  3. [JOBACLE] Automatic Start/stop in 11g release 2
Thursday, May 13, 2010

Q: Describe the use of %ROWTYPE and %TYPE in PL/SQL

[類別] PL/SQL
[問題] 請描述%ROWTYPE跟%TYPE該如何使用

Answer:
%ROWTYPE可以用來宣告一個record跟
(1)資料庫內某個table/view  OR  (2)從cursor fetch出來  的資料列有相同結構。
宣告語法如下:

變數名稱 表格名稱(OR view名稱 OR cursor名稱)%ROWTYPE;

ex: tmpRow employee%ROWTYPE;

如上就會有一個tmpRow結構跟employee(這個表格)裡的列一樣,包括欄位名稱資料型別。但並不繼承constraints!!

%TYPE可以用來宣告一個data item跟
(1)已宣告的變數  OR  (2)表格裡的某欄位  有相同的資料型別。
宣告語法如下:

變數名稱 表格名稱.欄位名稱%TYPE;

ex: tmpItem employee.salary%TYPE;

以上面的例子,tmpitem是所謂的referencing item,而employee.salary是referenced item。

使用%TYPE一定會繼承資料型別,但不一定會繼承contraints。當referenced item是資料庫表格的欄位時,就不會繼承。

Linux例行性工作排程by crontab

env: Red Hat Enterprise Linux 5

如果要在linux上排定一些類似檔案備份的例行性排程,可以利用crontab這指令。

step1: 準備好要下的指令,通常都會先編一個.sh file, 像這樣:

[say_hello.sh]

#!/bin/bash

echo say hello `date` >> log.txt

    上面這個檔案會印一行say hello跟系統時間在log.txt這個檔案裡
    像這樣: say hello Wed May 12 16:20:01 CST 2010

step2: 使用crontab排程

$ crontab -e

-e是edit的意思。下了這個指令後會進入vi編輯畫面。都未曾使用過crontab的話內容就是一片空白。

step3: 新增工作排程

crontab的內容有固定格式,一個工作一行,大概長像這樣:

20 16 * * * /home/oracle/say_hello.sh

先簡單說一下這條工作內容: 每到16:20執行say_hello.sh
指令的結構是這樣(詳細說明請參閱[鳥哥]基礎文件CH16)

指令
0-59 0-23 1-31 1-12 0-7 指令=  =

這邊要注意指令裡有用到任何檔案,都要用絕對路徑。
編輯完存檔退出後,會有一行訊息: crontab: installing new crontab
表示排程已經排定。如果要檢視所有排定的工作,可以下:

$ crontab -l

step4: 就等囉~

等到已經排定的時間,你可能會發現.... 失敗了=   =,並且會收到一封mail,由root(Cron Deamon)寄出,內容最後有一行類似這樣的訊息:

/bin/sh: /home/oracle/say_hello.sh: Permission denied

permission denied… 也不知道在deny什麼鬼,因為明明可以在自己的環境裡直接下"sh /home/oracle/say_hello.sh"執行這個script。一直以為是路徑的問題(阿不就是寫完整路徑!?),改來改去就是不行。

最後發現竟然真的是權限問題,下"ls -l"可以看到新建的script檔權限長這樣:
-rw-r--r--
owner自己竟然沒權限執行.... orz||,chmod一下

$ chmod u+x /home/oracle/say_hello.sh

確認一下執行權限-rwxr--r--
再重新安排一次時間比較近的排程試試看,應該就OK囉。

linux排程初體驗,成功!!!

Ref:

  1. [鳥哥] 第十六章、例行性工作排程 (crontab)
  2. Disable The Mail Alert By Crontab Command
Friday, May 07, 2010

My favorite chrome extensions

沒看到google提供收藏最愛extensions的功能.. 只好自己做個記錄順便分享一下。

  1. SearchPreview for Google: 可以替google搜尋結果加上網站預覽的小圖
  2. Auto Replay for YouTube: 提供youtube自動replay功能
  3. Tab Menu: 條列所有開啟的tab
  4. IE Tab: 以ie核心開啟網頁(沒辦法~ 有些網站就是不得不)
  5. Google 文件 PDF/PowerPoint 檢視器 (由 Google 提供): 以google文件檢視器直接開啟PDF、PPT等文件

本來就很容易分心,所以沒有裝更多其他有的沒的XD。另外列一些個人感興趣還沒使用的:

  1. MegaUpload DownloadHelper: (另有RapidShare的)免倒數~ cool
  2. Turn Off the Lights: 觀看有影片的網頁時,可以把背景都變黑,讓你有置身於電影院內的感覺XD
  3. Robot Theme, inspired by Android™: 只是一個android佈景主題,好似很可愛
  4. Clickable Links: 將原本不是做成超連結的url或e-mail add變成clickable links
  5. Google Tasks: 相當簡潔的待做清單囉(應該是只有local啦)
  6. 迅雷、快车、旋风专用链自动破解: 不想解釋=P
  7. JoinTabs: 這個好!!! 在開了許多tab之後,可以把相關的另外拉成一個chrome window。不知道好不好用~
  8. Eye Dropper: 網頁選色工具,也有color picker

Q: What is a mutating table error and how can you get around it?

相當慚愧的... 在看到這題以前,我也完全沒聽過mutating tabel這東西OTZ

[類別] PL/SQL
[問題] 什麼是mutating table error? 該如何處理這類錯誤?

Answer:
在回答什麼是mutating table error前,先來說說什麼是"mutating error"。當一個表格正在被UPDATE, DELETE或INSERT語法修改(也就是這個statement尚未commit, 表格正在"變更中"),或是一個table有可能是DELETE CASCADE的對象時,就是所謂的mutsting table。

只有row-level trigger(定義時使用FOR EACH ROW子句)嘗試要查詢或更新一個mutating table時,才會發生mutating table error! 主要是為了避免trigger存取不一致的資料。這時候trigger本身還有觸發trigger的語法(triggering statement)都會被rollback。

中文講的好爛請參閱英文講解 orz

A mutating table error (ORA-4091) occurs when a row-level trigger tries to examine or change a table that is already undergoing change (via an INSERT, UPDATE, or DELETE statement).

Mutating table error的中文訊息長這樣:

ORA-04091: 表格 Schema.Table 正在變更中, 觸發程式/函數無法檢視它

一般避免mutating table error最常見的方法是:

使用compound triggers或temporary tables(or views),讓同一session update/select不同表格

喋喋不休版
舉個會發生mutating table error的實例: 假如hr.employee的表格上有定義一個row-level的trigger: 每次有row被刪除時,會計算employee的總筆數。所以當你對hr.employee下一個SQL去刪除某列資料的同時(此時employee就是一個mutating table),也會觸發該trigger,這個trigger嘗試要存取employee,以上條件(mutating table, row-level trigger),即會發生mutating table error。

(It WORKS!)“could not create directory for unzipping” when installing chrome extensions

上篇只找到一個暫時有用的方法之後,過了不久,chrome越來越破爛,只好循重新安裝一途,沒想到重安裝之後,連想換個不景主題都會遇到一樣的問題... 真是晴天霹靂,完全不可接受,只好又花了點時間找找別的方法。

看到好多篇說要修改TEMP/TMP環境變數的,個人雖然相當不願意做這件事情,不過試了發現對我還是無效,最後找到一個相當簡易的方法!!! 只要在開啟chrome的捷徑內容幫他加個參數就好了:

2010-05-07_001

沒錯,就是" --no-sandbox" 記得參數前要有一個空白。

重新啟動chrome之後就可以正常安裝主題還有擴充功能囉喔喔喔~ 不過因為個人對這個參數的意義相當不解,所以建議安裝完之後還是把這個參數拿掉吧... 有需要的時候再加回來使用。

Ref: [SECI 知識轉換] [GC] 暫時解決無法安裝擴充功能問題

(補) sandbox

Chrome 擴展也有使用 Sandbox 技術,即每個擴展是獨立運行的。在安裝一些擴展後你可發現 task manager 內會有較多的 chrome.exe 在運行。獨立運行的好處,是一個擴展死掉不會拖累另一個。
from: http://www.hksilicon.com/kb/articles/3764/1/Chrome-Extension-/Page1.html

Thursday, May 06, 2010

設定PowerBuilder連接oracle資料庫之.ini file

environment

PB version: PB11 
Local computer: Oracle 10g/11g client

Pb application原本是使用ODBC來與資料庫連線:

[DataBase]
DBMS=ODBC

DbParm=ConnectString='DSN=test;UID=user_id;PWD=user_pwd'

不知道什麼原因,有少數datawindow的效率相當不好,因此想要將連線改為PB提供的oracle driver(版本對照請參考這兒)。步驟如下:

Step1: 開啟PB > Tools > Database Profile…

1_open

 

Step2: 選擇PB所提供最新的oracle driver(O10 Oracle10g),按右鍵選擇”New Profile…”

2_dbprof

 

Step3: 設定新連線內容

3_setconn

    Profile Name: 新連線名字
    Server: net manager裡設定的"服務命名"
    Login ID / Password: 資料庫user帳號密碼

4_setsys

    PowerBuilder Catalog Table Owner: 就是oracle的schema owner

5_setsyntax

    Enclose Table and Column Names in Quotes: 這個選項如果勾起,SQL語法的表格名稱還有欄位會自動被放在雙引號裡,這有時候會造成一些問題(像ORA-00904),可以視需求勾選。

Step4: Preview and test

6_test

點 "Test Connection"看設定是否正確,沒問題就可以Apply並且OK。

Step5: 最後把設定檔export成*.ini檔

7_exp

在剛設定好的連線按右鍵 > Export Profile(s)... 將檔案存到目的資料夾內

Step6: 檢視匯出的內容揪竟長怎樣

[DBMS_PROFILES]
Profiles=test

 

[Profile test]
DBMS=O10 Oracle10g (10.1.0)
Database=
UserId=
DatabasePassword=
LogId=user_id

LogPassword=user_pwd
ServerName=test
DBParm=PBCatalogOwner='Owner_name',DelimitIdentifier='No'
Lock=
Prompt=FALSE
AutoCommit=FALSE
NewLogic=TRUE

前3行要刪掉,改放[DataBase],其他設定就隨自己需求增減,最後整個ini file大概會長這樣:

[DataBase]

DBMS=O10 Oracle10g (10.1.0)
LogId=user_id
LogPassword=user_pwd
ServerName=test
DBParm=PBCatalogOwner='Owner_name',DelimitIdentifier='No'

完工!

Friday, April 30, 2010

Materialized views: read-only, updatable, writeable

一直對oracle replication的機制不是相當了解,今天看了幾個章節,稍微有些心得,雖然還是不知道replication group存在的真正目的,不過到是對materialized view多了些認識。

Materialized view可以是read-only, updatable, writeable這三種模式。read-only相當好理解,不過updatable跟writeable兩個就... ?

Read-only
要做一個read-only的materialized view,就是不要使用"FOR UPDATE"這個子句(clause)即可。如其名,不可以對這類views執行任何DML語法。而且!!! 它也不需要屬於任何一個materialized view group。

Updatable
跟read-only相反,可以在這類views上執行DML語法,而這些變更也可以透過排程或其他方法更新回target master(可能是一個master table或master materialized view);不過有一個前提: 就是updatable materialized view必須放在一個materialized view group裡。

Writeable
writeable的materialized view跟updatable一樣,會用到"FOR UPDATE"子句。唯一差別是,他不會放在materialized view group內,換句話說,即使可以對writeable的materialized view執行DML,但是變更並不會更新回target master。(那幹嘛不用read-only就好=   = 所以這類materialized view也比較少用)

整理如下:

  Read-only Updatable Writeable
created with “FOR UPDATE” clause? N Y Y
perform DML operation? N Y Y
placed in a materialized view group? N Y N
changes be pushed back to master? N Y N
Tuesday, April 27, 2010

"could not create directory for unzipping" when installing chrome extension

※ 本篇只能"暫時"讓你安裝擴充功能而已,重新開啟chrome後該功能即會消失。另一解法請參考這理,works for me!! --2010/5/7

前陣子就發現在安裝google chrome extensions時會遇到這樣的錯誤(可是剛開始用的時候不會orz||),今天終於有一個extension讓我有動力想解決這個問題。

step1: 直接把extension下載下來,檔案的副檔名會是".crx"

2010-04-27_001

step2:  用解壓縮軟體直接把該檔案解壓縮
2010-04-27_002

step3: 回到chrome瀏覽器,在網址列輸入"chrome://extensions/"

step4: 點選右上角"開發人員模式" > "載入為封裝擴充功能"
2010-04-27_005 done~!

(補)不過後來發現,這個方法只能"暫時"使用extension而已,每次關掉瀏覽器再開啟,那個擴充功能就消失了,還是要再做一次上面的步驟才可以繼續使用 orz||

Ref: Fixing the Chrome Error: “Could not create directory for unzipping”

Q: Difference between oracle procedure, function and anonymous pl/sql block?

耶!! 前陣子的"回答oracle interview questions計畫"終於要開始惹!!
先簡單說明一下,基本上這些問題會用中文來回答,但是專有名詞的部分... 還是維持它原本的面貌... 因為我根本不知道他中文是要翻成什麼鬼=  =… 而且這些東西翻成中文感覺反而會失去原本的意思或被誤解。

[類別] PL/SQL
[問題] procedure, function還有anonymous pl/sql block間有什麼不同?

Answer
procedure跟function最大的差別在於function會有一個回傳值(a single value)。而anonymous pl/sql block如他字面上定義,是一段沒有名字的pl/sql,通常直接用在像SQL*PLUS這樣的工具裡,來叫用procedure, function或package。

喋喋不休版
procedure跟function兩者可以合稱為"subprogram",特色是具名、可以給予參數、可以有回傳值(only function);存在schema層級的subprogram又叫做standalone stored subprogram,而定義在package內的就叫package subprograms。

Anonymous blocks由三個部分組成: 宣告(declarative part)、執行(executable part)、例外處理(exception handlers),其中宣告與例外處理可有可無。特色是不具名(也就無法永久存於資料庫內),只做暫時之用(不像procedure跟function可以重複被叫用)。

比較表:

  Anonymous Blocks Subprograms
具名? N Y
每次使用時都進行編譯? N N
存於資料庫內? N Y
可被其他應用程式呼叫? N Y
可回傳bind variable值? Y Y
可回傳函數值? N Y
可接受參數? N Y

*bind variable就是"連結變數"... 就是我們sql語法裡為了效能考量寫成”column_value=:v”的這個:v

Friday, April 23, 2010

[Study] Oracle 9i Space Management Demystified (2)

(續) [Study] Oracle9i Space Management Demystified (1)
[原文] Original file here

9i提供給DBA的利器之二: Automatic Undo Management

這是原文的第一個part,旨在介紹undo tablespace/undo segment。在讀這篇文章以前,心裡一直有訊息就是: 9i以前存放undo data的叫做rollback segment,9i稱為undo segment。以為只是名稱上的不同,作用機制應該一樣。現在終於清楚了解是不同的!於是相當三八的畫了圖,就來看圖說故事吧XD

雖然名字不同、作用機制不同,不過目的是一樣的:

purpose

 

Rollback Segment Reviewed

rollbackSegment(點圖見原始大小) Rollback segment由一個transaction table(存放在header)與兩個以上的extents(由undo blocks)組成。每個extent可以被多個transaction存取,但同一時間只能由單一transaction寫入。

Extent是循環使用的。每個transaction會嘗試使用下一個"有空"的extent,如果每個extent都已經被佔用,server會再配置新的extent。

Automatic Undo Management

autoUnodManagement(點圖見原始大小)9i的這個新功能是透過undo tablespace來實現,tablespace裡的segment就叫undo segment(header同樣有一個transaction table),segment再往下的邏輯架構同rollback segment。

Undo tablespace啟用時,部份undo segments也同時online。每個transaction建立時,server會嘗試配給一個undo segment(transaction table)。當online的undo segments不夠用時,剩餘offline的undo segments 也會online來使用。若還是不夠,server會嘗試再配置新的undo segments,直到undo tablespace的空間不足了,才可能讓transaction共享同一個undo segment(最閒的那個)。

以上,就是rollback segment跟undo segment的差異。所以這樣的差異如何可以讓DBA的生命更美好呢XD?

  1. 只要create一個夠大的undo tablespace,undo segment的數量與大小oracle server都會接手,自動依需求動態調整。若是9i以前,rollback segments的數量與大小都需要仔細考慮,才能降低因transaction佔用而導致效率下降的問題。
  2. 跟auto undo management搭配的還有一個參數: UNDO_RETENTION。透過設定這個參數(秒數),可以決定undo data需要被保留至少多久的時間。如果有long run query,可以降低ORA-1555(shapshot too old)的錯誤。不過要特別注意的是,這個參數要undo tablespace的大小配合。否則你希望保留較久的undo data,可是允許的空間不足的話... 只能說: 巧婦難為無米之炊XD
  3. 承第一點,比起固定大小的rollback segment,因為undo segment大小動態調整,對於整個tablespace的空間利用也就較有效率。

所以如果是oracle 9i用戶,只要透過設定以下兩個初始化參數,就可以使用automatic undo management囉~

UNDO_MANAGEMENT=AUTO
COMPATIBLE=9.0.0

Sizing Undo Tablespace

所以,undo tablespace該給多大顯然是個重要的議題... 最簡單的方法是,如果我知道三件事情,那麼就可以決定"至少"要給多大的空間:

  1. 資料庫平均每秒需要用到多少個undo blocks?
  2. 每個undo block(data block)多大?
  3. 政策上要保留多久時間(秒)以前的undo data?

以上,2跟3都很好解決,就是初始化參數的DB_BLOCK_SIZE跟上面提到的UNDO_RETENTION。1呢... 我們可以從V$UNDOSTAT這個view裡得到答案。

V$UNDOSTAT這個表每十分鐘就會多一筆資料,統計每十分鐘產生了多少個undo blocks以及最久的query時間。數學上是這樣: "每十分鐘吃掉X個糖果,每秒吃幾個?" XD,不過當然是全部數據拿來平均比較準。最久的query時間也有點用處,可以讓DBA們參考決定undo_retention要設多久。

所以得到以上三個數字後,相乘,可以得到一個byte數,那就是最小需要的undo tablespace的大小囉~

呼~ 大致上就這樣,最基本的概念介紹完畢。原文裡還有其他資訊,請自閱。

Tuesday, April 13, 2010

[ORA-00845]: MEMORY_TARGET not supported on this system

environment:

Oracle Database 11g Release 11.2.0.1.0 – 64bit
Red Hat Linux Server

人哪.. 如果閒著沒事幹就會替自己找麻煩=   =,今天把準備拿來當production的oracle shutdown下來,再重開。馬上就被賞了個大禮。說是大禮,因為要是今天沒發現... 等到真的上線了才手忙腳亂,也沒時間整理文件囉~ =P

先來說說11g的新變革:
Automatic Memory Management(AMM)是11g的新功能,需要額外的shared memory(/dev/shm)還有一些file descriptors來實現,透過MMAN這支process來管理動態管理SGA與PGA的大小。

比較一下11g跟10g以前的記憶體管理設定參數:

  11g before 10g
memory size MEMORY_TARGET
SGA_TARGET
PGA_AGGREGATE_TARGET
limit MEMORY_MAX_TARGET SGA_MAX_TARGET

(當MEMORY_TARGET或MEMORY_MAX_TARGET其中一個有指定值時,SGA_MAX_TARGET會自動設成大的那個)

嗯... 簡單介紹到這,接著該來講正事: ORA-00845
在startup oracle時,若

  1. /dev/shm not mounted
  2. mounted with available size less then MEMORY_TARGET(系統內shared memory(/dev/shm)比設定的MEMORY_TARGET還要小)

就會丟出ORA-00845這個錯誤。同時去檢查alert log,也可以看見相關訊息,而且他也會建議適合的大小給你設定。

Starting ORACLE instance (normal)
WARNING: You are trying to use the MEMORY_TARGET feature. This feature requires the /dev/shm file system to be mounted for at least 2097152000 bytes. /dev/shm is either not mounted or is mounted with available space less than this size. Please fix this so that MEMORY_TARGET can work as expected. Current available is 2071711744 and used is 0 bytes. Ensure that the mount point is /dev/shm for this directory.
memory_target needs larger /dev/shm

要判斷自己是哪種情況可以先下"df -k"這個指令來查看/dev/shm是否有mount,若正常,應該可以看到如下:

[...]$ df –k
檔案系統          1K-區段      已用        可用       已用%    掛載點
tmpfs             3145728   1062256   2083472    34%      /dev/shm

 

若確定有掛載,那就是大小問題,可以調大mountpoint size:

# mount -t tmpfs shmfs -o size=7g /dev/shm

 

為了讓每次server重開機時,可以自動分配同樣的大小,需要修改/etc/fstab這個檔案,請讓他看起來長的像這樣:
tmpfs     /dev/shm       tmpfs   size=3g    0 0

這樣就一切大功告成!! 祝startup愉快~ =D

Ref:

  1. [Oracle Doc] Oracle Release Notes > Known issues
  2. [Oracle Doc] Preinstallation Requirements > Hardware Requirements > Memory Requirements > Automatic Memory Management(AMM)
  3. (need login) [Metalink] ORA-00845: MEMORY_TARGET not supported on this system - Linux Servers [ID 465048.1]
  4. [Ask Tom] ORA-00845: …
  5. [鳥哥] /etc/fstab
Monday, April 12, 2010

Oracle Role and Privileges

介紹一些跟角色(role)還有oracle系統權限(privileges)相關的view:

VIEW Description
DBA_ROLES All Roles which exist in the database
DBA_ROLE_PRIVS Roles granted to users and roles
ROLE_ROLE_PRIVS Roles which are granted to roles
ROLE_SYS_PRIVS System privileges granted to roles
ROLE_TAB_PRIVS Table privileges granted to roles


個人覺得最實用的是ROLE_SYS_PRIVS,在授予使用者角色時,用這個表可以看出ROLE包了哪些system privileges。

另外加贈兩個不錯的view: DBA_TAB_COMMENTS, DBA_COL_COMMENTS分別可以看表格或表格欄位的說明~

Friday, April 02, 2010

[Study] Oracle 9i Space Management Demystified (1)

[原文在此] Original file here

今天早上找到的好文章。版本老是老了點,不過有很多概念是一直延續的,個人認為這篇還有讀的價值。

開場白就說了database administrator花了他們大部分的時間在做space utilization, 而oracle 9i相當好心的提供了3個改革來改善DBA們的生命XD。
  • Automatic Undo Management
  • Locally Managed Tablespace
  • Auto Segment Space Management
因為我是在找tablespace fragmentation相關議題的時候看到這篇文章的,所以會先從Locally managed tablespace這塊讀起。

Locally Managed Tablespace
首先介紹名字的由來,Locally Managed Tablespace是針對extents管理的一個改革。傳統的tablespace management方法是利用data dictionary (tables) 來追蹤extents的使用狀況(所以稱為dictionary-managed tablespace),因為data dictionary屬於SYS, 是在不同的tablespace裡,所以整個資料庫內extents被分配或釋放時,都要集中在SYS tablespace裡記錄,還會有資源搶用(contention)的問題。
Dictionary Managed
Locally Managed
space managed bydata dictionary (SYS)bitmap (datafile header)
generate undo info.yesno
auto coalesce free spacenoyes

使用Locally managed tablespace還有分兩種決定extent size的方法: AUTO ALLOCATE跟UNIFORM EXTENT。
AUTO ALLOCATEUNIFORM EXTENT
size decisionby Oracle automaticallyDBA
decision factorcorresponding segment?: base on db utilization
initial extentsmaller (64K)? (default 1M)
when enough free space not availableauto allocates smaller extentsfail
which mode to use1. objects in tablespace vary drastivally in size
2. growth pattern is expected to be highly dynamic
only if all objects in the db are going to be of the same size and grow in a uniform manner

整體上看來,還是建議使用AUTO ALLOCATE模式即可。許多人可能認為使用UNIFORM EXTENT可以保證被釋放的extnets一定可以再被重新利用,因此也比較能減少fragment的現象。但其實不然,就像上面表格裡建議的,若是tablespace裡的物件經常性的建立還有刪除(像是暫時建了Table當作資料處理的中繼站),那麼使用uniform就相當浪費空間,因為不管表格大或小,他就是會佔去一個固定大小的extent。反過來看auto allocate模式下的extents,雖然大小各不相同,但是他們基本上還是follow一個基本的模式在增長,通常是initial extent的倍數,所以再被重新利用並不難。

造成fragmentation的現象的主因並非extents size不同,而是因為tablespace裡的objects follow不同的extent sizing policy,而導致被釋放的extent很難再被重新利用。所以要用auto還是uniform mode? 基本上還是視資料庫的使用情形決定。

整體上看來,locally managed tablespace有兩大優點:
  1. 效能較好: 因為少了data dictionary的搶用;還有他對space的管理方式,也是提升效能的關鍵之一(long running queries, add and drop objects)。
  2. 較少fragmentation: 如上述。
OK!!! 這就是locally managed tablespace的部分,是這三個主題裡篇幅最少的一個惹~ XD
Thursday, April 01, 2010

Interview Questions with Answers for Oracle, DBA, and developer candidates

Interview Questions with Answers for Oracle, DBA, and developer candidates
今天看資料的時候忽然找到這個網站,感覺起來滿有趣的,他把問題分為8大類:
  1. PL/SQL
  2. DBA
  3. SQL/SQL PLUS
  4. Tuning
  5. Installation/Configuration
  6. Data Modeler
  7. UNIX
  8. Oracle Troubleshooting
花了一些時間把他們整理起來。然後我決定... 要回答全部的問題!!! (好大的願望XD),目前預計能將進度控制在每個禮拜回答一題XDD(沒辦法,我還有半本Oracle DBA Fundamentals還沒讀完Q_Q)。至於開始時間呢... 就看什麼時候開始回答第一題吧~ =P (最近好懶散..)
敬請期待!!!
Wednesday, March 31, 2010

Web Parser

以前沒寫過,也沒去想過一個撈資料的工具該怎麼運作。這兩天閒著(其實已經閒了快一個月惹=    = ),不如花點時間研究一下,也找到一個算是有用的輔助工具,分享一下。
> HTML Agility Pack:簡單好用的快速 HTML Parser

開始前稍微瞭解了一下最基本的原理。
  1. 跟我猜想的一樣,利用HTML tag。 如果網頁寫的好、夠結構化,那撈資料的作業也比較好進行。遺憾的是,HTML就是可以不嚴謹,標籤不一定成對,只能祈求還能從中找到一些規律了XD
  2. 第1點用的是比字串的方法,據說效能不好(因為還沒大量撈資料,我實在感覺不出來=   =)。另一個方法是利用Regular Expression。 但是這對剛入門的人來說實在是... 門檻相當高,想要寫出一個可用的regular expression,還必須先好好了解每個符號的意義。而且就我這次的經驗(撈一層包一層的HTML tags),似乎派不上用場。
第一次寫web parser,對像是PTT WebBBS,他單篇文章的HTML架構還滿簡潔的,簡單到... 反而讓人困擾XDD,要將表頭(作者、標題、時間)、內文、推文分開還比較難,因為他們全部放在一組div裡,就沒其他tag了XDD。

文章列表就比較有挑戰性一點,不過這個挑戰用上面推薦的HTML Agility Pack就搞定了XD

因為parser這東西是針對不同網站,解析的寫法就完全不同,應該說是完全客製化了吧,所以,就不介紹code的部分了~ 沒事可以玩玩,還滿有趣的 =D
Wednesday, March 24, 2010

[Study] Oracle Extended ROWID & Base-64 Decode

最近讀到ROWID這東西… 費了我不少時間啊 orz。

Introduction
ROWID顧名思義,可以透過他來識別/定位資料庫裡的任何一個row。他並非真正的欄位(column),但是在每個表(table)裡,我們都可以下select ROWID來取得他的值。

Format
先簡單介紹一下Extended ROWID的構成 (在Oracle7以及更早以前的版本是所謂的Restricted ROWID,這裡不討論),ROWID是經過base-64編碼後以18個字元呈現,需用到最大10 byte的儲存空間。


  • Data object #: 6個字元。白話一點說,就是row所在的table。以oracle的邏輯架構來看,table算是一個segment,而透過segment我們可以知道這個row在哪個Tablespace內
  • Relative file #: 3個字元。定位row實際上是在哪個datafile內
  • Block #: 6個字元。定位row所在的data block
  • Row #: 3個字元。定位row本身

ROWID
SQL> select rowed from hr.jobs where job_id='XXX';

實際上select出的ROWID,大概是長這樣 → AAAgwuAAKAAAl7hAAR
拆解各部份套到上面圖示,會是這樣:


原本以為到DBA_OBJECTS內找到相對應的'DATA_OBJECT_ID'欄位也會是"AAAgwu",結果大錯特錯。

SQL> select data_object_id from dba.objects where owner='HR' and object_name='JOBS';

得到的值竟然是一個數字!!! "134190"!!!! what!?!?
嗯… 因為我上面有提到,ROWID的18個字元,是經過base-64編碼的… 必須再處理過,才會是134190這個data object number。

BASE64 to Decimal
其實sys下也有現成的package可用: DBMS_ROWID (This package provides procedures to create ROWIDs and to interpret their contents),只要把rowid丟進DBMS_ROWID.ROWID_INFO內(外加其他幾個承接結果的變數),就可以得到每一段轉換過後的數字。詳細用法可參考這兒

可以得到現成的結果還不錯,不過還是想知道他事實上到底是怎麼換算的,在找了幾篇失敗的解說後,找到了這篇!! 透過他提供的SQL, 就可以了解其中過程。


Create Or Replace Package B64 Is
B64 Varchar2(64):='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
Function Base64_2Dec(Val Varchar2) Return Number;
Function Dec2_Base64(Val Number) Return Varchar2;
End B64;
/
Create Or Replace Package Body B64 Is
Function Base64_2Dec
(Val Varchar2)
Return Number Is
I Pls_Integer;
J Pls_Integer;
K Pls_Integer:=0;
N Pls_Integer;
V_Out Number(38):=0;
Begin
  N:=Length(B64);
  For I In Reverse 1..Length(Val) Loop
    J:=Instr(B64,Substr(Val,I,1))-1;
    If J <0 Then
      Raise_Application_Error(-20001,'Invalid Base 64 Number: '||Val);
    End If;
    V_Out:=V_Out+J*(N**K);
    K:=K+1;
  End Loop;
  Return V_Out;
End;

Function Dec2_Base64
(Val Number)
Return Varchar2 Is
V_In Number;
N Pls_Integer;
V_Out Varchar2(30):='';
Begin
  N:=Length(B64);
  V_In:=Trunc(Val);
  While (V_In>0) Loop
    V_Out:=Substr(B64,Mod(V_In,N)+1,1)||V_Out;
    V_In:=Trunc(V_In/N);
  End Loop;
  Return V_Out;
End;

End B64;
/

(有點懶得解釋= = 請自行閱讀,B64那串字就是base-64的64個字元,請看Ref #3)

所以當我下
SQL> select rowid ,
B64.Base64_2Dec(substr(rowid,1,6)) object_no ,
B64.Base64_2Dec(substr(rowid,7,3)) rel_file_id,
B64.Base64_2Dec(substr(rowid,10,6)) block_no,
B64.BASE64_2DEC(SUBSTR(ROWID,16,3)) ROW_NO
from hr.jobs where job_id='XXX';

可以得到
ROWID                          OBJECT_NO REL_FILE_ID   BLOCK_NO    ROW_NO
------------------                     ----------------     ----------------      --------------       -------------
AAAgwuAAKAAAl7hAAR       134190                10           155361               17


完畢!!

Ref:
  1. 如何使用base64编码解构Oracle rowid信息
  2. Oracle DBMS_ROWID
  3. Base64
Monday, March 22, 2010

[Study] Unicode、Encoding(編碼)


前幾天有篇文章忽然出現在河道上浮浮載載,又身為被點名的「軟體開發者(Software Developer)」,於是相當認真的看了一下… 相當慚愧的,我還是不懂orz

文章在這:

中文版: 每個軟體開發者都絕對一定要會的Unicode及字元集必備知識(沒有藉口!)

英文版: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)


我覺得可能是因為本身對整個編碼的基礎知識相當薄弱,所以造成對內文的理解與接受度也大幅度降低惹... Q口Q,既然是欠缺基礎,還是做點筆記吧… 不過我後來有注意到其實這篇文章已經有點年紀了… 所以不太確定他的內容或是他所提供的參考資料是否還跟的上事實。


Code pages、字元集(character set)、encodings
編碼系統0-127128-255system
ASCII0-31: 控制字元

32-127: 數字、英文字母大小寫、常用符號
未定義使用
ANSI同ASCII似ISO Latin-1Windows 3.x

Windows 95
IBM PC Extended Character Set (ECS)同ASCII定義歐洲字元(European characters)DOS
Roman-8
European characters
HP
ISO Latin-1Web browsers


Unicode
Unicode(統一碼、萬國碼、單一碼、標準萬國碼)是業界的一種標準,它可以使電腦得以呈現世界上數十種文字的系統。在文字處理方面,Unicode的功用是為每一個字元提供一個唯一的代碼(Code Point, 即一組數字),而不是一種字形。換句話說,Unicode是將字元以一種抽象的方式來呈現,而將視覺上的演繹工作(例如字體大小、外觀形狀、字體形態、文體等)留給其他軟體來處理,例如網頁瀏覽器或是文字處理器。


Encodings (編碼)

方法一:UCS-2(UTF-16)
每個字元(的代碼, code point)佔用2個byte(也就是16 bit),所以理論上最多可以以16 bit去定義出65,536個字元(216)。但事實上unicode並為用滿整個16 bit,所以還有擴展空間。而UCS-2又分為high-endian(Big-Endian, 大端序)與low-endian(Little-Endian, 小端序)兩種讀取順序/模式,因為不同機器(CPU)對byte會有不同的理解順序。

方法二:UTF-8
因為UCS-2的編碼方式會造成基本英文字母浪費了相當多的bit空間,於是發展出UTF-8。在UTF-8的系統裡,0-127的基本符號、英數字母都只佔一個byte,128以上的字元則不一定,大部分佔2-3 byte,最多甚至可到6 byte。

補充:
根據wiki上的說法,其實編碼方式跟實現方式是兩回事:上面提到的UCS-2是編碼方式,而Unicode的實現方式稱為Unicode轉換格式(Unicode Translation Format,簡稱為UTF)。

還有許多其他編碼方式都只能正確儲存部分代碼(code points), 其餘他們不認得的編碼會變成問號(?)。通常UTF-7, 8, 16, 32可以正確儲存所有的代碼(code points)。


以上!! 吸收完畢!! 希望是對的=_______=。


Ref:

  1. ASCII Characters for MPE Users
  2. Windows Uses the ANSI Character Set
  3. IBM PC Extended Character Set (ECS)
  4. European Characters in Web Pages
  5. Roman-8 European Characters (HP)
  6. [wiki] Code Page
  7. [wiki] Unicode(中) or [wiki] Unicode
  8. [wiki] Character encoding
Friday, March 19, 2010

Blogger: 在新視窗開啟連結

媽啊!! 終於成功惹!!!

先留個資料,改天再補!!


 

Ref:

  1. Blogger/Blogspot: open all links in new windows
  2. "Better" Standards-based Replacement for target="_blank" in External Links
  3. Standards-based Replacement for target="_blank" in External Links
Tuesday, March 16, 2010

SQL Developer 2.1.1: Font of Code Editor and Data Grids

昨天上oracle去晃晃,忽然發現SQL Developer又有新版本惹~ 二月就出了2.1的patch 1,我整個大delay啊orz.. 所以趕快就抓了新的下來用。

來說說使用半個小時後的感想:

最令人驚艷的是開啟時的速度,效能大增啊!!! 所以還在1.5.5的人相當建議快快更新你的SQL Developer版本~

不過有一點比較不習慣的是,因為年紀有點大XD,我習慣把Code Editor的字型放大,但是這個改變也會一起動到輸出的結果(Script Output Window)與所有資料表檢視(Data Grids)… 可是我並不想看到這麼大字的輸出或是資料表啊Q_Q整個很笨拙的感覺,不過找了一下資料,看來是暫時無法改變這件事情惹..

Ref:

  1. [Sue's Blog… again…] Back to Basics: Changing the Font Setting in SQL Developer
  2. [OTN] Oracle SQL Developer Release 2.1 Patch 1 Release Notes

Monday, March 15, 2010

SQL Developer problem: 某些按鍵(key/button)無作用(not working)

上禮拜在用sql developer的時候,也不知道手滑去按到什麼鍵,他忽然就不接受鍵盤的某些按鍵了!! 像是backspace, delete, ctrl+v等的… 原本以為可能作業系統忽然秀逗了還怎樣,應該重開機就好了(重開機是一切啊~ = =)

不過相當遺憾的,還是失敗了。不過解法相當簡單:

中文版(版本: 1.5.5)
工具> 偏好設定> 快速鍵> 載入預先設定> 選擇Default> 確定

英文版(version: 1.5.5)
Tools -> Preferences -> Accelerators -> Load Preset -> Default -> OK

相當簡單就不附圖了!! 希望有幫助~

Ref:

Oracle SQL Developer problem – backspace / delete button not working – quick fix

Friday, March 12, 2010

Length Semantics for Character Datatypes

How to determine the column length in different database character set and length semantics? For example, you need to define a VARCHAR2 column that can store up to 5 Chinese characters together with 5 English characters.

Database Character Set

Length Semantics

Single byte

Multiple byte

BYTE

10 BYTE

5*3+5*1=20 BYTE

CHAR

10 CHAR

10 CHAR

Tuesday, February 09, 2010

SQL Developer Change UI Language to English

最近在處理資料庫搬家,越來越不喜歡看到工具的介面是中文的= =,中文翻譯反而看不懂在寫啥鬼,一直看英文文件.... 忽然看到中文的,還會懷疑他翻的是這個嘛?XDD

SQL Developer一裝起來就一副中文樣XD,用著也沒什麼不方便,可是每次有跳錯誤或警告,都看不太懂到底是哪裡出錯了= =a。稍微看了一下設定... 好像也沒有直接可以改的地方@_@

後來在Oracle Forums看到也有人問,所以就找到方法了:
  1. 先在sql developer的安裝資料夾下找到
    (sqldeveloper install directory)\ide\bin\ide.conf

  2. 加上這行:
    AddVMOption -Duser.language=en
完畢!!


Monday, February 08, 2010

[Study] Managing Undo Data



Thursday, January 14, 2010

test: word2007 post to blogger

as title, test!!

[Study] Storage Structure and Relationships



Tags

Archivo