2013年11月13日 星期三

Oracle - Update Join 又失敗~~~again ORA-01779


之前因為用 Join 要更新 table 失敗,
查了一下,只要用子查詢的方式就可以了,
Oracle - Update 不可以用 Join ?

但是今天又不行了,
跳出了 ORA-01779 的錯誤訊息!
查了一下,說是子查詢 Join 出來的不是唯一,
可能會有多筆資料的意思!

就是說要 Update A 然後 A Join B 出來的資料 A 跟 B 不是 一對一,
可能 A 會對到兩筆 B,不過明明我已經把所有的 Key 都加上去了,
不曉得會不會是因為我的 A, B 是同一個 Table 的關係?

查到別的文章都說要加 key, index,
不過這個我原本就有 pk 啊?

所以最後我就採用了跳過不檢查的選項啦!

UPDATE (
SELECT /*+BYPASS_UJVC*/A.*, B.VALUE AS VALUE_B
FROM A JOIN B ON A.KEY = B.KEY
)
SET VALUE = VALUE + VALUE_B;

不過這樣代表有一定的危險性,
我是會先下SELECT來看看資料是不是我要的啦!
所以請小心服用!

參考:【解决ORA-01779错误


2013年8月14日 星期三

Oracle Compile 卡住?感謝阿輝熱情支援~~~

今天要修改一支 SP,
只不過改了一下 cursor 之後,其他的都還沒修改,
想說先 compile 一下好了,
沒想到居然 compile 了 十幾分鐘還沒結束,
我就覺得大事不妙了,
拿了原來還沒修改過的 SP 也是相同狀況!!!
把 Oracle Service 重新啟動~~~不行!!
VM 從新開機~~~不行!!!
阿好咧~~~拿之前的 VM snapshot 來用,還原OK~~~
但是 compile 又是一樣的結果~~~掛!
八點了~~~不想弄了,一陣亂關之後~~~
幹的好~~ VM 整個壞掉了~~~
回家再試的時候還是起不來~~~
還好敗家好朋友自願幫我處理,因為他想看我的開箱文.....
但是我沒空啊~~~因為~~~~對話大概是下面這樣...

沒空啊~~~Oracle DB 卡住了~~好像有殺不掉的 Session, 連 Service 重啟都沒用....
給我 ip, 我連進去幫你搞定啦!不要糟蹋我們家的產品。

沒~~~今天在公司的時候就壞了compile 一隻 procedure 的時候居然 compile 不完~~~是不是亂砍 session ,所以還在rollback?


還沒砍之前就壞了~~~


有辦法用 sqlplus 進去下指令嗎?


我用 pl/sql dev 應該是一樣的吧?


不一樣Plsql dev 走 sqlnet有要用特別的帳號嗎?
普通的帳號進去了

你直接在 vm 的 console 裡,下 sqlplus "/ as sysdba"

哈哈~~~不行

普通帳號進去,那就在 sqlplus 下: connect / as sysdba

ora-12560

listener 的錯誤吧

反正系統管理員進去後,先 shutdown abort

然後再重新 startup再 shutdown normal這樣應該就會正常了如果你今晚還要寫程式...不過我會建議你開箱比較適當讓 vm 休息一下不行~~~~看來應該還要 startup 吧
我要先還原環境啦~~~你正常關機 ( shutdown normal ),應該可以很順利拉起來也應該要很好連進去別忘了開 listener

有啦~~~進去了

不用ㄟ~~~我再直接startup之後就可以了


那就快開箱吧!希望我洗完澡就可以看到開箱照!
這個傢伙重點完全放在開箱~~~
只能說~~~還好我買的東西今天有到~~~

整個重點整理就是....
用 sql plus 連進去之後轉換成 sysdba
connect / as sysdba
然後關掉失敗的....(我猜的)
shutdown abort
然後起來一次
startup
然後在正常關機
shutodwn normal
最後在起來一次就OK啦~~~
就這麼簡單~~~~當個水美妹就這麼簡單....
(我好愛用這句啊~~)

2013年7月29日 星期一

Oracle - ORA-01658 解決方式


話說上次從客戶那邊抓了基本資料要倒到自己的DB,
沒想到一直失敗,看了一下出現了 ORA-01658 的錯誤訊息!
是說我看不太懂這個意思是啥啦...

上網估狗了一下,應該是 TABLESPACE 滿了的意思,
不過我覺得很奇怪,明明我就是先刪除資料後再匯入,
這樣應該要有空間才是啊?怪~~~
算了,反正我覺得 ORACLE 怪也不是第一遭了~~~

用下面的查詢查一下空間

SELECT A.TABLESPACE_NAME, A.BYTES / 1024 / 1024 "Sum MB",
       (A.BYTES - B.BYTES) / 1024 / 1024 "used MB", B.BYTES / 1024 / 1024 "free MB",
       ROUND(((A.BYTES - B.BYTES) / A.BYTES) * 100, 2) "percent_used"
FROM (SELECT TABLESPACE_NAME, SUM(BYTES) BYTES
       FROM DBA_DATA_FILES
       GROUP BY TABLESPACE_NAME) A,
     (SELECT TABLESPACE_NAME, SUM(BYTES) BYTES, MAX(BYTES) LARGEST
       FROM DBA_FREE_SPACE
       GROUP BY TABLESPACE_NAME) B
WHERE A.TABLESPACE_NAME = B.TABLESPACE_NAME

ORDER BY ((A.BYTES - B.BYTES) / A.BYTES) DESC

每個都是滿的,但是看上面的訊息,其實我應該是 INDEX 的 TABLESPACE 滿了吧!

 嗯~~~很棒!
安裝的時候我很聰明的覺得 200MB 應該是夠用了,沒想到滿了!

SELECT A.TABLESPACE_NAME, A.BYTES / 1024 / 1024 "Sum MB"
FROM (SELECT TABLESPACE_NAME, SUM(BYTES) BYTES
       FROM DBA_DATA_FILES

       GROUP BY TABLESPACE_NAME) A


而且我還沒讓他可以自動長大~~~~@@;a 幹的好!

SELECT FILE_ID, FILE_NAME, TABLESPACE_NAME, AUTOEXTENSIBLE, INCREMENT_BY
FROM DBA_DATA_FILES

ORDER BY FILE_ID DESC;


看來解決方式只能另外再多加一個 INDEX 的 TABLESPACE 了,
然後這次不要自作聰明了,讓他可以自動長大~~~

ALTER TABLESPACE INDEX_NAME
ADD DATAFILE 'C:\APP\FRANKIE\ORADATA\TEST1\DATAFILE\O2_MF_INDE_NAME_.DBF'

SIZE 200M AUTOEXTEND ON MAXSIZE 1G;

調整完之後就變成 400 了!匯入資料也沒問題了~~~

2013年6月25日 星期二

Oracle - Update 不可以用 Join ?


總之就是以前在 SQL Server 上面寫的方式不能用了 @@"
以前都是這樣寫的(印象中)...

update a
set a.co = nvl(b.co, 'not found')
from table_a a

left join table_b b on a.id = b.id

但是在 Oracle 不可以這樣寫,會有錯誤 ╮(╯3╰)╭
估狗了一下是說有兩種方式可以處理,
一個是用子查詢的方式,另一種是用 View 的方式,
子查詢遇到資料量大的時候效能會變成笑能,所以~~~OUT!!!
修改成 View 的結果如下:

update (
select nvl(b.co, 'not found') as b_co, a.co
from table_a a
left join table_b b on a.id = b.id
)

set co = b_co

其實也沒有比較麻煩,
只是把原來的 Select 用 Update 包起來而已。

參考:Einzig Mir: Oracle SQL使用兩個Table進行Update的方法

2013年4月18日 星期四

Oracle - 資料表筆數、大小的計算方式

總而言之、言而總之,因為要調效能的關係,
第一步要先抓到資料筆數比較多跟Size比較大的資料表,
所以找到了一些SQL的寫法,如下:



/* 資料筆數 */
SELECT TABLE_NAME, AVG_ROW_LEN, NUM_ROWS
  FROM DBA_TABLES
  WHERE NUM_ROWS > 1000000
  ORDER BY NUM_ROWS DESC;

/* Table size */       
SELECT SEGMENT_NAME AS TABLE_NAME,
    ROUND(SUM(BYTES) /(1024*1024*1024),2) AS TABLE_SIZE_GB
  FROM USER_EXTENTS
  GROUP BY SEGMENT_NAME
  HAVING ROUND(SUM(BYTES) /(1024*1024*1024),2) > 0.5
  ORDER BY ROUND(SUM(BYTES) /(1024*1024*1024),2) DESC;

/* Data size */
SELECT TABLE_NAME, AVG_ROW_LEN, NUM_ROWS,
    ROUND (AVG_ROW_LEN * NUM_ROWS /(1024*1024*1024),2) AS DATA_SIZE_GB
  FROM DBA_TABLES  
  WHERE ROUND(AVG_ROW_LEN * NUM_ROWS /(1024*1024*1024),2) > 0.1
  ORDER BY ROUND(AVG_ROW_LEN * NUM_ROWS /(1024*1024*1024),2) DESC;


有聽過不太會寫PL/SQL,然後要來調效能的八卦嗎?

2013年1月14日 星期一

C# - 如何知道泛型的型態? 趴兔

最近在測試 Oracle 的資料庫,
簡單的說就是要把底層改成連到 Oracle 去,
但是又不想 hard code 直接把所有的 SqlConnection 改成 OracleConnection,
然後就想到上次那個泛型的寫法【C# - 如何知道泛型的型態?】,
但是不幸的是...原來上次那個寫法只能用在基本資料型態,
所以我沒有辦法依照上次那樣寫來區分 SqlConnection 跟 OracleConnection,
但是我想應該是有辦法的才對,所以又要找好朋友估狗了!
後來測試出可以用 typeof 的方式寫,
先改涵式的宣告,如下:

private T GetConnection<T>

在程式裡面可以用下面的方式這樣判斷:

if (typeof(T) == typeof(OracleConnection))
if (typeof(T) == typeof(SqlConnection))