cdc

导航

(原创)ASP.NET中调用存储过程(Oracle版)

Posted on 2006-04-20 12:55  Chris Chen  阅读(652)  评论(0编辑  收藏  举报

1.源程序如下:
/*
 *存储过程名为kkx_bmyh,该存储过程有两个参数ks_time,js_time
 *类型均为varchar2
 */
void ExecuteStorage()
{
 try
 {
         //数据库连接字符串
  string ConnStr =
   System.Configuration.ConfigurationSettings.AppSettings["conn"].ToString().Trim();

  //建立连接
  OracleConnection m_Conn = new OracleConnection(ConnStr);
  m_Conn.Open();
              
  OracleCommand m_OCmd = new OracleCommand( "kkx_bmyh", m_Conn );
  //设定Command类型为存储过程
  m_OCmd.CommandType = CommandType.StoredProcedure;
              
         //添加参数,和参数类型
  m_OCmd.Parameters.Add("ks_time",OracleType.VarChar);
  m_OCmd.Parameters.Add("js_time",OracleType.VarChar);
  
  //传值,是一个起始时间和结束时间
  m_OCmd.Parameters["ks_time"].Value="2005-01-01";
  m_OCmd.Parameters["js_time"].Value="2005-12-01";
               
  //执行存储过程,成功则返回1
  int res = m_OCmd.ExecuteNonQuery();
  
  
 }
 catch{}
 finally
 {
         //关闭连接,释放资源
         if(m_OCmd != null)
  {
   m_OCmd.Dispose();
  }
  if(m_Conn.State == ConnectionState.Open)
  {
   m_Conn.Close();
  }
 }
}
最开始是参考网上的程序
m_OCmd.Parameters.Add("@ks_time",OracleType.VarChar);
m_OCmd.Parameters["@ks_time"].Value="2005-01-01";
程序运行时,总报错,说是参数类型不正确,后把@去掉,就运行通过,不知其原因^_^~~~~

为便于管理和应用方便,后对上面的程序,进行修改,封装到数据库操作类DBOracle中:
protected OracleConnection m_Conn;
protected OracleCommand m_OCmd;
DBOracle DB = new DBOracle();
public int ExecuteStorage(string StorageName,string[][] Params)
{
 int res = -1;
 try
 {
  Open();
  m_OCmd = new OracleCommand( StorageName, m_Conn );
  m_OCmd.CommandType = CommandType.StoredProcedure;
  int count = Params.Length;
  for(int i=0;i<count;i++)
  {
   m_OCmd.Parameters.Add(Params[i][0],Params[i][1]).Value = Params[i][2];

  }
  res = m_OCmd.ExecuteNonQuery();
 }
 catch(Exception e)
 {
  WriteMessage(e.Message.ToString().Trim(),true,true);
 }
 finally
 {
  Close();
  Dispose();
 }
 return res;
}
//Open(),WriteMessage(),Dispose(),Close()均为DBOracle中封装函数
调用方式如下:
string[][] Params = new string[][] {
  new string[] {"ks_time","OracleType.VarChar","2005-01-01"},
  new string[] {"js_time","OracleType.VarChar","2005-12-01"}
};
DB.ExecuteStorage(kkx_tdyy,Params);
-------------------------------------------------------------------------------------------
参考资料如下:
使用Command执行存储过程
 
在数据驱动的应用程序中,存储过程可以提供很多优点。使用存储过程可以将数据库操作封装到一条简单的命令中,可以优化效能,可以增强安全性。
只需要按照SQL语法在存储过程名后面跟带参数就可以调用该存储过程。使用ADO.NET中Command对象的Parameters属性
你还可以明确的定义和使用output参数和return值。

调用存储过程时,要设置Command对象的CommandType属性为StoreProcedure。
一旦设定了CommandType属性为StoreProcedure,你就可以使用Parameters集合来定义参数,
就像下面的例子。

注意 使用OdbcCommand调用存储过程时要求提供完整的ODBC CALL语法。

SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind");

SqlCommand salesCMD = new SqlCommand("SalesByCategory", nwindConn);
salesCMD.CommandType = CommandType.StoredProcedure;

SqlParameter myParm = salesCMD.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15);
myParm.Value = "Beverages";

nwindConn.Open();

SqlDataReader myReader = salesCMD.ExecuteReader();

Console.WriteLine("{0}, {1}", myReader.GetName(0), myReader.GetName(1));

while (myReader.Read())
{
 Console.WriteLine("{0}, ${1}", myReader.GetString(0), myReader.GetDecimal(1));
}

myReader.Close();
nwindConn.Close();

一个Parameter对象可以使用Parameter构造器创建,也可以通过调用Command对象的Parameters集合的Add方法创建。
Parameters.Add方法的输入参数可以和构造器相同,也可以使用一个存在的Parameter对象。
用System.DBNull.Value设置Parameter的值为空。

如果要设置Parameter为非一般的输入参数时,必须设置ParameterDirection属性为InputOutput,Output,或者ReturnValue。
下面的例子演示了创建Input, Output, 和 ReturnValue参数的差别。

SqlCommand sampleCMD = new SqlCommand("SampleProc", nwindConn);
sampleCMD.CommandType = CommandType.StoredProcedure;

SqlParameter sampParm = sampleCMD.Parameters.Add("RETURN_VALUE", SqlDbType.Int);
sampParm.Direction = ParameterDirection.ReturnValue;

sampParm = sampleCMD.Parameters.Add("@InputParm", SqlDbType.NVarChar, 12);
sampParm.Value = "Sample Value";

sampParm = sampleCMD.Parameters.Add("@OutputParm", SqlDbType.NVarChar, 28);
sampParm.Direction = ParameterDirection.Output;

nwindConn.Open();

SqlDataReader sampReader = sampleCMD.ExecuteReader();

Console.WriteLine("{0}, {1}", sampReader.GetName(0), sampReader.GetName(1));

while (sampReader.Read())
{
 Console.WriteLine("{0}, {1}", sampReader.GetInt32(0), sampReader.GetString(1));
}

sampReader.Close();
nwindConn.Close();

Console.WriteLine(" @OutputParm: {0}", sampleCMD.Parameters["@OutputParm"].Value);
Console.WriteLine("RETURN_VALUE: {0}", sampleCMD.Parameters["RETURN_VALUE"].Value);

在SqlCommand中使用参数
在SqlCommand中使用参数时,参数的名字必须和存储过程中相应参数的名字匹配。
SQL SERVER的.NET Framework Data Provider将存储过程中的参数视为命名参数并且搜索与之匹配的参数标记。

SQL SERVER的.NET Framework Data Provider不支持使用问号标记(?)作为占位符来向SQL语句或者存储过程传递参数。
既然如此,你必须命名参数,就下面一样:

SELECT * FROM Customers WHERE CustomerID = @CustomerID
在OleDbCommand 和OdbcCommand中使用参数
在OleDbCommand或者OdbcCommand中使用参数时,参数添加到Parameters集合中的顺序必须和存储过程中参数定义的顺序匹配。
OLE DB和ODBC的.NET Framework数据供应程序将存储过程的参数视为占位符,按照顺序来给参数赋值。
另外,返回参数必须是第一个被加入到Parameters集合中的参数。

OLE DB和ODBC的.NET Framework数据供应程序不提供使用命名参数来向SQL语句或存储过程传递参数。为此,你必须使用问号(?)占位符,就像下面一样:

SELECT * FROM Customers WHERE CustomerID = ?
因此,向 Parameters 集合添加 Parameter 对象的顺序必须直接对应于该参数的问号占位符的位置。

导出参数信息
参数也可以使用 CommandBuilder 类从存储过程导出。SqlCommandBuilder 和 OleDbCommandBuilder 类都提供了静态方法 DeriveParameters,
该静态方法将自动使用存储过程中的参数信息填充 Command 对象的 Parameters 集合。请注意,DeriveParameters 将改写 Command 的任何现有参数信息。

导出参数信息时需要经历一个到数据源的附加行程,以获取参数信息。如果参数信息在设计时是已知的,则可以通过显式设置参数来提高应用程序的性能。

以下代码示例显示如何使用 CommandBuilder.DeriveParameters 来填充 Command 对象的 Parameters 集合。

SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;");
SqlCommand salesCMD = new SqlCommand("Sales By Year", nwindConn);
salesCMD.CommandType = CommandType.StoredProcedure;

nwindConn.Open();
SqlCommandBuilder.DeriveParameters(salesCMD);
nwindConn.Close();