[seasar-dotnet:2235] Re: 【S2Dao.Net】OracleのNCHARまたはNVRCHAR2の取扱について

李 い [E-MAIL ADDRESS DELETED]
2013年 2月 19日 (火) 09:37:15 JST


小谷さんへ

李です。ご返事ありがとうございます。

>文字化けが起きているプロパティの型はどのようになっているでしょうか?

 Entity内のプロパティの型は「String」です。

>(stringであればUnicode用のSystem.DbType.Stringが使用されるはずなのですが。。。)

 こちらもいろいろ調べました。問題が発生した箇所もわかりました。
>>        Dim pBiko As New OracleParameter("biko", OracleDbType.NVarchar2)
この記述は、下記の意味となり:
        pBiko.ParameterName = "biko"
        pBiko.OracleDbType = OracleDbType.NVarchar2
しかし、Seasar.Extension.ADO.Types.BaseValueType にのロジックは、
        pBiko.DbType = System.Data.DbType.String
の意味になりました。

 OracleDbTypeを設定しないと文字化けが発生するみたいです。
だが、OracleDbType はODP.NETの属性なので、ADOのインタフェースにはありません。

 Seasar.Extension.ADO.Types.BaseValueTypeの中に、OleDbの対応ソースが見つかりましたので、
それをまねて修正してみました:
        public void BindValue(
            IDbCommand cmd,
            string columnName,
            object value,
            DbType dbType,
            ParameterDirection direction
            )
        {
            IDbDataParameter parameter = cmd.CreateParameter();
            parameter.ParameterName = columnName;
            parameter.DbType = dbType;
            if ("OleDbCommand".Equals(cmd.GetType().Name) && dbType == DbType.String)
            {
                OleDbParameter oleDbParam = parameter as OleDbParameter;
                oleDbParam.OleDbType = OleDbType.VarChar;
            }

            //【ODP.NET】オラクルのNCHAR、NVARCHAR2の対応
            if ("OracleCommand".Equals(cmd.GetType().Name) && dbType == DbType.String)
            {
                InitForODP();
                if (asmOracleODP != null)
                {
                    // CHAR,VARCHAR2のカラムに対して、OracleDbType.NVarchar2を設定しても正しく動く
                    pInfoOracleDbType.SetValue(parameter, oracleDbTypeNVarchar, null);
                }
            }

            parameter.Value = GetBindValue(value);
            parameter.Direction = direction;
            cmd.Parameters.Add(parameter);
        }

        //【ODP.NET】
        private static Assembly asmOracleODP = null;
        //【ODP.NET】
        private static PropertyInfo pInfoOracleDbType = null;
        //【ODP.NET】
        private static Object oracleDbTypeNVarchar = null;

        /// <summary>
        /// ODP.NET用内部変数初期化
        /// </summary>
        /// <returns></returns>
        private void InitForODP()
        {
            if (asmOracleODP == null)
            {
                Assembly[] asms = AppDomain.CurrentDomain.GetAssemblies();
                foreach (Assembly assembly in asms)
                {
                    if (assembly.GetName().Name == "Oracle.DataAccess")
                    {
                        asmOracleODP = assembly;
                        break;
                    }
                }
                if (asmOracleODP != null)
                {
                    pInfoOracleDbType = asmOracleODP.GetType("Oracle.DataAccess.Client.OracleParameter").GetProperty("OracleDbType");

                    Type t = asmOracleODP.GetType("Oracle.DataAccess.Client.OracleDbType");
                    FieldInfo f = t.GetField("NVarchar2");
                    oracleDbTypeNVarchar= f.GetValue(null);
                }
            }
        }

うまく行けたみたいです。現在、他のところに影響があるかどうかをテスト中です。
もし何かアドバイスがあればありがたいです。



-----Original Message-----
From: seasar-dotnet-bounces @ ml.seasar.org [mailto:seasar-dotnet-bounces @ ml.seasar.org] On Behalf Of kotani.k
Sent: Monday, February 18, 2013 10:57 PM
To: seasar-dotnet @ ml.seasar.org
Subject: [seasar-dotnet:2234] Re: 【S2Dao.Net】OracleのNCHARまたはNVRCHAR2の取扱について

李さん

小谷です。

S2Dao.NETのupdate処理に渡すEntity内のプロパティのうち、
文字化けが起きているプロパティの型はどのようになっているでしょうか?
(stringであればUnicode用のSystem.DbType.Stringが使用されるはずなのですが。。。)

また、
>②正常に更新するパターン:
>        Dim cmd As New OracleCommand("UPDATE BIKO SET BIKO=:biko
WHERE KEY='07'", conn)
>        cmd.BindByName = True
>        Dim pBiko As New OracleParameter("biko", OracleDbType.NVarchar2)
>        pEmpno.Value = "㎥"
>        cmd.Parameters.Add(pBiko)
>        cmd.ExecuteNonQuery()

>四行目の「pEmpno」、というのは「pBiko」の間違い、ですよね?

そうです。書き間違いました。=_=


以上です。


2013年2月15日 9:54 李 い <liyi @ kssinet.co.jp>:
> いつもお世話になります、李と申します。
>
>  Visual Studio 2010
>  VB.Net
>  .NetFramwork 4.0
>  S2Container.NET 1.4.0 RC3
>  ODP.Net 2.112.1.0
> で開発しています。
>
> DB環境は下記となります:
>  DBサーバはWindows Server2008、Oracle11g(11.1.0.7.0)です。
>  NLS_CHARACTERSET:       JA16SJISTILDE
>  NLS_NCHAR_CHARACTERSET: AL16UTF16
>
> テスト用のテーブル定義:
> CREATE TABLE Biko
> (
>         key   NCHAR(10)     NOT NULL,
>         biko  NVARCHAR2(50),
>         CONSTRAINT Biko_PK PRIMARY KEY (key) USING INDEX
> )
> ※備考にUnicodeも入力するため、NVRCHAR2を採用します。
>
>
>  現象:
> DBの既存レコードから読み込みの場合、Unicode文字が正しく読み込まれ、画面に表示できます。
> しかし、画面で入力されたUnicode文字をDBに更新する時、「?」に化けてしまいました。
>
>
>  調査:(S2Dao.Netを利用せず、ODP.Netでサンプルを作って調査する)
> 【ソースの抜粋】
> ①「?」に化けるパターン:
>         Dim cmd As New OracleCommand("UPDATE BIKO SET BIKO=:biko WHERE KEY='07'", conn)
>         cmd.BindByName = True
>         cmd.Parameters.Add("biko", "㎥")
>         cmd.ExecuteNonQuery()
> ②正常に更新するパターン:
>         Dim cmd As New OracleCommand("UPDATE BIKO SET BIKO=:biko WHERE KEY='07'", conn)
>         cmd.BindByName = True
>         Dim pBiko As New OracleParameter("biko", OracleDbType.NVarchar2)
>         pEmpno.Value = "㎥"
>         cmd.Parameters.Add(pBiko)
>         cmd.ExecuteNonQuery()
>
>  調査結果:パラメータバンティングの時、カラムのタイプを指定しなければ、文字化けが発生します。
>
>
>  質問:
> S2Dao.Netで、パラメータバンティングの時、カラムのタイプを指定できる方法がありませんか?
>
>
> よろしくお願いします。
> _______________________________________________
> seasar-dotnet mailing list
> seasar-dotnet @ ml.seasar.org
> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
_______________________________________________
seasar-dotnet mailing list
seasar-dotnet @ ml.seasar.org
https://ml.seasar.org/mailman/listinfo/seasar-dotnet
-------------- next part --------------
$BJ8;z%3!<%I;XDj$NL5$$E:IUJ8=q$rJ]4I$7$^$7$?(B...
$BL>A0(B: BaseValueType.cs
URL:  <http://ml.seasar.org/archives/seasar-dotnet/attachments/20130219/1d1833e5/attachment.ksh>


seasar-dotnet メーリングリストの案内