我希望能够针对 oracle 存储过程运行我的 SqlDataProvider。我可以使用 Microsoft 的 Oracle Provider,但这不允许我调用存储过程。有没有人能让这个工作?我特别希望能够使用声明性数据绑定。我已经能够以编程方式创建一个 DataTable,但我想在 .aspx 中以声明方式执行此操作。
2 回答
System.Data 命名空间中的 SqlDataProvider、SqlConnection 和其他以 Sql 为前缀的类几乎普遍指的是 SQL-Server 特定的实现。但是,可以使用 Microsoft 发布的 System.Data.oracleClient 库调用存储过程。
请确保在构造 OracleCommand 时传入 CommandType。存储过程。否则,数据库引擎将默认为“表直接”访问,并且由于它找不到具有存储过程名称的表,因此它会失败。
这是一些关于如何在幕后工作的示例代码:
using (OracleConnection conn = new OracleConnection("connection string here"))
{
conn.Open();
OracleCommand command = conn.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "DATABASE_NAME_HERE.SPROC_NAME_HERE";
// Call command.Parameters.Add to add your parameters.
using (OracleReader reader = command.ExecuteReader())
{
while(reader.Read())
{
// Process each row
}
}
}
使用 ASP .NET 时,您可以使用 SqlDataSource 访问 oracle 客户端,其连接字符串定义如下:
<add name="OracleConnectionString"
connectionString="Data Source=YourServer;Persist
Security Info=True;Password="******";User ID=User1"
providerName="System.Data.OracleClient" />
请注意,我们在那里有 OracleClient 位。然后在 SqlDataSource 上将其上的 Select CommandType设置为ASPX 页面中的 StoredProcedure,其余的工作几乎与 SQL Server 类似(实际上,您实际上必须这样做才能调用 SQL Server 版本)。
结果看起来有点像:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:OracleConnectionString %>"
ProviderName="<%$ ConnectionStrings:OracleConnectionString.ProviderName %>" SelectCommand='TEST_ONE' SelectCommandType="StoredProcedure" ></asp:SqlDataSource>
Here are the steps to return a table-like select statement::
1) You should return a cursor for the select, then add in the parameters io_cursor IN OUT CURSOR
2) When you Consume it add ANOTHER parameter
<asp:Parameter Name="io_cursor" Direction="Output" />
3) Add event procedure for 'selecting' event
4) protected void SqlDataSource1_Selecting (object sender, SqlDataSourceSelectingEventArgs e) { ((System.Data.OracleClient.OracleParameter)e.Command.Parameters[0]).OracleType = System.Data.OracleClient.OracleType.Cursor; }
Now it would work fine.