gpt4 book ai didi

oracle - 在 Oracle 中使用 Dapper QueryMultiple

转载 作者:行者123 更新时间:2023-12-03 20:00:12 25 4
gpt4 key购买 nike

我正在尝试将 dapper 与 Oracle (ODP.NET) 一起使用,并且我想使用“QueryMultiple”功能。

将此字符串传递给 QueryMultiple 方法:

 var query = "Select CUST_ID CustId from Customer_info WHERE CUST_ID=:custId;" +
"Select CUST_ID CustId from BCR WHERE CUST_ID=:custId";

我收到一个 ORA-00911:无效字符错误

有没有办法做到这一点,或者这是不可能的?

塔克斯

最佳答案

OP 现在可能早就解决了这个问题,但截至撰写本文时,这个问题只有一个答案,并没有真正解决使用 Dapper 的 QueryMultiple() 的问题。使用 Oracle 的方法。正如@Kamolas81 正确指出的那样,通过使用官方示例中的语法,确实会得到 ORA-00933: SQL command not properly ended错误信息。我花了一段时间搜索有关如何操作的文档 QueryMultiple()与 Oracle 合作,但令我惊讶的是,真的没有一个地方有答案。我会认为这是一项相当普遍的任务。我想我会在这里发布一个答案来拯救我:) 将来某个时候有人碰巧遇到同样的问题。
Dapper 似乎只是将 SQL 命令直接传递给 ADO.NET 以及正在执行该命令的任何 db 提供程序。在示例的语法中,每个命令由换行符分隔,SQL Server 会将其解释为针对数据库运行的多个查询,它将运行每个查询并将结果返回到单独的输出中。我不是 ADO.NET 专家,所以我可能会弄乱术语,但最终效果是 Dapper 获取多个查询输出,然后发挥其魔力。
但是,Oracle 无法识别多个查询;它认为 SQL 命令格式错误并返回 ORA-00933信息。解决方案是使用游标并在 DynamicParameters 集合中返回输出。例如,SQL Server 版本如下所示:

var sql = 
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";
查询的 Oracle 版本需要如下所示:
var sql = "BEGIN OPEN :rslt1 FOR SELECT * FROM customers WHERE customerid = :id; " +
"OPEN :rslt2 FOR SELECT * FROM orders WHERE customerid = :id; " +
"OPEN :rslt3 FOR SELECT * FROM returns Where customerid = :id; " +
"END;";
对于针对 SQL Server 运行的查询,Dapper 可以从那里处理它。但是,因为我们将结果集返回到游标参数中,所以我们需要使用 IDynamicParameters集合来指定命令的参数。添加额外的皱纹,正常 DynamicParameters.Add() Dapper 中的方法使用 System.Data.DbType 作为可选的 dbType 参数,但查询的游标参数需要是类型 Oracle.ManagedDataAccess.Client.OracleDbType.RefCursor .为了解决这个问题,我使用了@Daniel Smith 在 this answer 中提出的解决方案。并创建了 IDynamicParameters 的自定义实现界面:
    using Dapper;
using Oracle.ManagedDataAccess.Client;
using System.Data;

public class OracleDynamicParameters : SqlMapper.IDynamicParameters
{
private readonly DynamicParameters dynamicParameters = new DynamicParameters();

private readonly List<OracleParameter> oracleParameters = new List<OracleParameter>();

public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction, object value = null, int? size = null)
{
OracleParameter oracleParameter;
if (size.HasValue)
{
oracleParameter = new OracleParameter(name, oracleDbType, size.Value, value, direction);
}
else
{
oracleParameter = new OracleParameter(name, oracleDbType, value, direction);
}

oracleParameters.Add(oracleParameter);
}

public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction)
{
var oracleParameter = new OracleParameter(name, oracleDbType, direction);
oracleParameters.Add(oracleParameter);
}

public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
((SqlMapper.IDynamicParameters)dynamicParameters).AddParameters(command, identity);

var oracleCommand = command as OracleCommand;

if (oracleCommand != null)
{
oracleCommand.Parameters.AddRange(oracleParameters.ToArray());
}
}
}
所以所有的代码加在一起是这样的:
    using Dapper;
using Oracle.ManagedDataAccess.Client;
using System.Data;

int selectedId = 1;
var sql = "BEGIN OPEN :rslt1 FOR SELECT * FROM customers WHERE customerid = :id; " +
"OPEN :rslt2 FOR SELECT * FROM orders WHERE customerid = :id; " +
"OPEN :rslt3 FOR SELECT * FROM returns Where customerid = :id; " +
"END;";

OracleDynamicParameters dynParams = new OracleDynamicParameters();
dynParams.Add(":rslt1", OracleDbType.RefCursor, ParameterDirection.Output);
dynParams.Add(":rslt2", OracleDbType.RefCursor, ParameterDirection.Output);
dynParams.Add(":rslt3", OracleDbType.RefCursor, ParameterDirection.Output);
dynParams.Add(":id", OracleDbType.Int32, ParameterDirection.Input, selectedId);

using (IDbConnection dbConn = new OracleConnection("<conn string here>"))
{
dbConn.Open();
var multi = dbConn.QueryMultiple(sql, param: dynParams);

var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
var returns = multi.Read<Return>().ToList();
...
dbConn.Close();
}

关于oracle - 在 Oracle 中使用 Dapper QueryMultiple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18772781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com