2016年10月11日 星期二

c# oracle 撈不出資料 但developer撈有資料 | c# oracle can't get data but data can get when query on developer

環境:
VS2013& 類別庫專案 & C# & Oracle.DataAccess 4.121.1.0
情況:
在oracle developer跑一段select  有幾個變數
select blablabla from table where A=:A and B=:B and C=:C
執行結果有資料
但在C#用OracleDataReader撈到DataTable
dt.Load(odr)
撈出來卻沒資料
印出變數跟sql有正確,也沒有跳exception,
查DB的query log也沒看到有執行這段查詢....

解決:
後來發現是變數塞值的時候順序塞錯了
我寫的是
Parameters.Add("A",A)
Parameters.Add("C",C)
Parameters.Add("B",B)
但應該要照順序去塞入
Parameters.Add("A",A)
Parameters.Add("B",B)
Parameters.Add("C",C)
才可以正常的綁定變數

2016年9月1日 星期四

C# 從Oracle db取多個DataTable結果回來 | C# get multi DataTable result from Oracle DB

參考文章:
http://stackoverflow.com/questions/6149836/filling-multiple-datatables-with-1-oraclecommand

簡單來說就是在db上用 SYS_REFCURSOR 輸出結果
用 open cursor for select的方式就可以把結果丟回來
C#端的程式寫法大致上同CALL SP的方式,
參數設定中輸出的資料集是用OracleDbType.RefCursor這個型別


2016年8月9日 星期二

c# 呼叫oracle sp 出現ora-06502 pl/sql 數字或值錯誤 character string buffer too small | c# call oracle sp get ora-06502

寫sp時遇到ora-06502 pl/sql 數字或值錯誤 character string buffer too small

出錯行數是在我的sp的設定輸出參數文字字串訊息那一行

查了一下後發現是c#端在設定輸出參數時要順便指定大小在第三個參數

oc.Parameters.Add("P_MSG", OracleDbType.NVarchar2, 256).Direction=ParameterDirection.Output;

不然預設的buffer好像很小,多塞幾個字就over了

2016年7月22日 星期五

C# 寫入Oracle 加入變數時出現ArgumentOutOfRangeException | C# insert Oracle db get ArgumentOutOfRangeException when add parameter

語言:C#
DLL:Oracle.DataAccess.Client; 4.121.1.0

在做新增資料時,插入一個常數整數變數,就出錯在那一行

private const int _DEFAULT_VALUE = 0;
OracleCommand oc = new OracleCommand();
oc.CommandText = "insert into Table1 (col1) values(:val1)";
oc.Parameters.Add("val1", _DEFAULT_VALUE);--這行出錯


得到ArgumentOutOfRangeException

Google找到一篇文章
http://brianseekford.com/wordpress/?p=100
說在插入0的時候也出錯了
有個解決辦法是這樣

oc.Parameters.Add("val1", (object)_DEFAULT_VALUE);

把變數轉型為object,結果就過了!
我想應該是驅動程式的BUG

20170510補記
自己又遇到同樣問題 狗回來這一篇
不過有新解法
 oc.Parameters.Add(new OracleParameter(){
                                        ParameterName=":FLAG",
                                        Value=(short)0,
                                        OracleDbType=OracleDbType.Int16
                                    });

這樣的方式也是OK

2016年4月14日 星期四

Oracle 中文數字排序 | Oracle order by chinese number

我在處理地址的中文排序
例如一街二街三街....
oracle預設的中文排序好像是照拼音
所以會發生二街(ㄦˋ)比三街(ㄙㄢ)後面的問題
若指定用筆劃排序
又會發現五街(四劃)比四街(五劃)前面的問題
後來問到一個語法叫TRANSLATE

ORDER BY  translate(road,'一二三四五六七八九','123456789');

參考:
http://www.cnblogs.com/huli-DBA/archive/2012/02/13/2348824.html

可以把指定的字元集中的字元一對一替換為替換字元集中的字元
所以就拿來處理中文的一到九
至於一個字的十不能換成10,其實也還好
例如 十四 十五 十六 會變成 十4 十5 十6
二十三 二十四 二十五 會變成 2十3 2十4 2十5
這樣排下去也還算是照著順序

2016年3月9日 星期三

C# Oracle Client 執行多行SQL回傳影響列數為-1 | C# Oracle Client execute multiple line sql number of rows affected return -1

問題:
當執行多行ORACLE SQL、如BEGIN ...END,或者MERGE INTO等指令時會,
ExecuteNonQuery()都只會回傳-1,這樣就無法看出影響列數

解決方法參考
http://stackoverflow.com/questions/32138843/merge-query-returns-1-instead-of-number-of-rows-merged

原本的SQL加上一段
:num := sql%rowcount;
且增加一個OUTPUT變數
OracleCommand cmd = new OracleCommand(sql, myConnection);
  var p = cmd.Parameters.Add(":num", OracleDbType.Int32, ParameterDirection.Output);
  cmd.ExecuteNonQuery();
  Console.WriteLine("Rows affected: " + p.Value);
執行之後讀取變數的值即可得到影響列數

-----------
寫成int回傳方法時
舊的System.Data.OracleClient裡面我這樣寫轉換:
count = (int)p.Value;
是可以跑的,但在新的Oracle.DataAccess.Client裡面
我要這樣轉換
(參考: http://stackoverflow.com/questions/3026036/convert-oracleparameter-value-to-int32 )
Convert.ToInt32((decimal)(OracleDecimal)(cmd.Parameters["successCount"].Value))
轉換時才不會出現InvalidCastException

2016年2月26日 星期五

ORA-01722 invalid number

今天在處理一個卡號欄位,原本是6位數字卡號,
現在新需求是把卡號的主檔裡一些欄位資訊帶出來,
所以理所當然就做一個JOIN就結束,
同時也做了另外幾個相同功能裡面的新需求,
本機+測試DB上跑也正常,
但到了本機+正式機DB測試後卻跳了ORA-01722 invalid number錯誤,

兜了快20分鐘,甚至找歪方向,發現拿掉
ROW_NUMBER() OVER( ORDER BY MY_DATE DESC )
這個行號欄位後就能跑,但實際上問題不在這裡,整個誤導思路...

後來才想通,有新需求才有新BUG,檢視新加的TABLE才想起來,
因為這個卡號欄位後來又塞了不是數字的值,
所以JOIN時文字對上數字,就發生ORA-01722錯誤,
解決辦法就是把主檔TABLE的數字ID轉文字,JOIN就成功了...

不過如果一次只處理一個需求,找問題發生點時或許就可以明確指出是這個TABLE了

2016年1月15日 星期五

asp.net web form updatepanel + jQueryUI dialog 按鈕postback造成textbox文字消失 | button postback cause textbox text missing

功能情境:
一個網頁有查詢區跟查詢結果gridview
GRID的資料行有可以點擊查看明細的按鈕
明細的DIV用jquery UI 的dialog來顯示
明細DIV裡有包在updatepanel裡的明細Grid
並且有一個同意按鈕 跟一個加備註按鈕 和備註文字textbox
原本只設定了按鈕的onClick 後端程式
但是按下按鈕postback時會無法觸發後端事件

所以我找到一篇說
前端的按鈕click事件加上

__doPostBack($('input[id$="按鈕ID"]').attr("id"), null);

的事件來觸發postback

但只有同意按鈕正常運作,需要填備註的按鈕就出問題了
同樣做法會讓備註文字欄的文字在postback後消失,
但是又不想要整個打掉改寫成Ajax 要改太多了,
所以又再找了一下做法,找到以下這篇
http://blog.roonga.com.au/2009/07/using-jquery-ui-dialog-with-aspnet-and.html

解法很簡單就是在dialog設定的open事件中加上

$(this).parent().appendTo("form");


還有updatePanel的屬性加上 ChildrenAsTriggers="true"
就成功觸發後端事件了

PS:記得移除前面那個__doPostBack不然會變成觸發兩次...

2016年1月12日 星期二

jquery ui dialog 關閉按鈕圖案消失 jquery ui dialog button icon missing

問題:
在一個有載入jquery ui跟bootstrap的網頁裡
dialog的關閉按鈕的icon不見了
但同樣的功能別的網頁上都正常

解決:
查了半天發現是css載入順序問題
要先載入bootstrap的css再去載入jquery ui的css
icon就出現了