- PR -

ADO.NETでADOと同じ動きをさせるには

1
投稿者投稿内容
Hiro
常連さん
会議室デビュー日: 2003/08/26
投稿数: 28
投稿日時: 2003-08-26 17:36
いつもお世話になります。
以前にADO+OLEDBでAS/400のプログラムを実行するプログラムを
作成してました。
今回ADOを利用していた部分をADO.NETに記述し直したのですがうまく
動作しません。
ADOで記述されたものと同じ動作をするようにADO.NETでも記述した
つもりなのですがどこがおかしいのでしょうか?
御教示願います。

ADO(正常に実行される)=============================================
ADODB.Connection con = new ADODB.ConnectionClass();
ADODB.Command cmd = new ADODB.CommandClass();

try
{
con.Open("Provider=IBMDA400;Data Source=AAA;","AAA","AAA",-1);
cmd.ActiveConnection = con;
cmd.Prepared = true;
cmd.CommandText = "{{call AAALIB.HIROTEST(?,?)}}";
cmd.Parameters.Append(cmd.CreateParameter("VAL1",ADODB.DataTypeEnum.adDecimal,
ADODB.ParameterDirectionEnum.adParamInputOutput,0,3));
cmd.Parameters.Append(cmd.CreateParameter("VAL2",ADODB.DataTypeEnum.adDecimal,
ADODB.ParameterDirectionEnum.adParamInputOutput,0,5));
cmd.Parameters["VAL1"].Precision = 1;
cmd.Parameters["VAL1"].NumericScale = 0;
cmd.Parameters["VAL2"].Precision = 1;
cmd.Parameters["VAL2"].NumericScale = 0;
object oret = null;
cmd.Execute(out oret,ref oret,-1);
Console.WriteLine(cmd.Parameters["VAL2"].Value);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
con.Close();
}
=================================================================
ADO.NET==========================================================
OleDbConnection con = new OleDbConnection();
OleDbCommand cmd = new OleDbCommand();
try
{
con.ConnectionString = "Provider=IBMDA400;Data Source=AAA;";
con.Open();
cmd.Connection = con;
cmd.Parameters.Add("VAL1",OleDbType.Decimal,0);
cmd.Parameters[0].Direction = ParameterDirection.InputOutput;
cmd.Parameters[0].Precision = 1;
cmd.Parameters[0].Scale = 0;
cmd.Parameters[0].Value = 3;
cmd.Parameters.Add("VAL2",OleDbType.Decimal,0);
cmd.Parameters["VAL1"].Direction = ParameterDirection.InputOutput;
cmd.Parameters["VAL1"].Precision = 1;
cmd.Parameters["VAL2"].Scale = 0;
cmd.Parameters["VAL2"].Value = 5;
cmd.CommandText = "{{call AAALIB.HIROTEST.PGM(?,?)}}";
cmd.Prepare();
cmd.ExecuteNonQuery(); <=== ここでエラー(オブジェクトが参照されていない)
Console.WriteLine(cmd.Parameters["VAL2"].Value);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
con.Close();
}
=================================================================
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-08-27 08:47
cmd.CommandType = CommandType.StoredProcedure;
を入れてみたら??

Decimal val1 = 3;
Decimal Val2 = 5;
cmd.Parameters["VAL1"].Value = val1;
cmd.Parameters["VAL2"].Value = val2;
って、変更してみたら??

それぞれどうなります?
Hiro
常連さん
会議室デビュー日: 2003/08/26
投稿数: 28
投稿日時: 2003-08-27 10:55
Jittaさんレスありがとうございます。
>cmd.CommandType = CommandType.StoredProcedure;
>を入れてみたら??
cmd.Prepare()で
{"SQL0104: トークン{は正しくない。有効なトークンは: <IDENTIFIER>です。?\b\r\n原因−−トークン{で構文エラーが検出されました。トークン{は正しいトークンではありません。有効なトークンは: <IDENTIFIER>です。このリストはトークンまでのステートメントが正しいと見なします。エラーはステートメントの始めの方にある可能性がありますが,この点まではステートメントの構文が正しいように見えます。回復手順−−次の1つまたは複数を実行して,要求をやり直してください。--トークン{のところのSQLステートメントを検査してください。ステートメントを訂正してください。エラーの原因は,コンマまたは引用符の脱落,つづりの間違った語,あるいは文節の順序にあると思われます。--エラー・トークンが<ステートメントの終わり>である場合には,SQLステートメントが正しい文節で終了していないので,SQLステートメントを訂正してください。??" }
というエラーが発生してしまいます

>Decimal val1 = 3;
>Decimal Val2 = 5;
>cmd.Parameters["VAL1"].Value = val1;
>cmd.Parameters["VAL2"].Value = val2;
>って、変更してみたら??
以前と同様に
cmd.ExecuteNonQuery()で
{"オブジェクト参照がオブジェクト インスタンスに設定されていません。" }
というエラーが発生してしまいます。

何が原因なのでしょうか
再度御教示頂けないでしょうか

変更したソースです=============================================================
OleDbConnection con = new OleDbConnection();
OleDbCommand cmd = new OleDbCommand();

try
{
con.ConnectionString = "Provider=IBMDA400;Data Source=AAA;";
con.Open();
cmd.Connection = con;
//cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("VAL1",OleDbType.Decimal,0);
cmd.Parameters[0].Direction = ParameterDirection.InputOutput;
cmd.Parameters[0].Precision = 1;
cmd.Parameters[0].Scale = 0;
Decimal val1 = 3;
cmd.Parameters[0].Value = val1;

cmd.Parameters.Add("VAL2",OleDbType.Decimal,0);
cmd.Parameters[1].Direction = ParameterDirection.InputOutput;
cmd.Parameters[1].Precision = 1;
cmd.Parameters[1].Scale = 0;
Decimal val2 = 5;
cmd.Parameters[1].Value = val2;

cmd.CommandText = "{{call AALIB.HIROTEST(?,?)}}";
cmd.Prepare();

cmd.ExecuteNonQuery();

Console.WriteLine(cmd.Parameters["VAL2"].Value);

}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
con.Close();
}
==============================================================================
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-08-27 11:28
cmd.CommandType = CommandType.StoredProcedure;
は、たぶん、
cmd.CommandText = "AALIB.HIROTEST(?,?)";


Decimalとか、5という数字は値型なので、オブジェクトへの参照がないため、ですね。返値を入れようとすると、値が入っているので変更ができない、ということだと思います。
Object val1 = 3D;
Object val2 = 5D;
で、どうですか?VB.NETでは、3や5の後にDをつけるとDecimal値となるのですが、C#でも一緒かな?
Hiro
常連さん
会議室デビュー日: 2003/08/26
投稿数: 28
投稿日時: 2003-08-27 12:06
Jittaさんお世話になります。
Jittaさんの指示とおりにやったつもりですが
同様のエラーが発生してしまいます。
ソースをのせますので確認して頂けないでしょうか
宜しくお願いします。
========================================================
OleDbConnection con = new OleDbConnection();
OleDbCommand cmd = new OleDbCommand();

try
{
con.ConnectionString = "Provider=IBMDA400;Data Source=AA;";
con.Open();
cmd.Connection = con;
//cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add("VAL1",OleDbType.Decimal,0);
cmd.Parameters[0].Direction = ParameterDirection.InputOutput;
cmd.Parameters[0].Precision = 1;
cmd.Parameters[0].Scale = 0;
object val1 = System.Convert.ToDecimal(3);
cmd.Parameters[0].Value = val1;
cmd.Parameters.Add("VAL2",OleDbType.Decimal,0);
cmd.Parameters[1].Direction = ParameterDirection.InputOutput;
cmd.Parameters[1].Precision = 1;
cmd.Parameters[1].Scale = 0;
object val2 = System.Convert.ToDecimal(5);
cmd.Parameters[1].Value = val2;

cmd.CommandText = "{{call AALIB.HIROTEST(?,?)}}";
cmd.Prepare();

cmd.ExecuteNonQuery();
Console.WriteLine(cmd.Parameters["VAL2"].Value);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
con.Close();
}
============================================================
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-08-28 09:27
AS/400ってのがわからないので、『確認して頂けないでしょうか』っていわれても困るのですが。。。

 Oracle相手に入出力パラメータを持つストアドプロシジャを作ってやってみたところ、「不明なエラー」とでました。Oracleの文書を漁ると、DataReaderで読んでいたので、AS/400とは挙動が異なるようです。

 Hiroさんの方は「オブジェクト参照がオブジェクト インスタンスに設定されていません。」なので、AS/400ではこの通りで動作するように思います。問題は、設定しているオブジェクトが参照でないこと、だと思います。stringなど、オブジェクト参照になるものに変更して、試してみました?

 MSDNを「ボックス化」で検索すると、こんな方法が・・・

decimal dval1 = 3;
decimal dval2 = 5;
object val1 = dval1;
object val2 = dval2;
1

スキルアップ/キャリアアップ(JOB@IT)