OceanBaseForOracle中调用存储过程报错。 返回
OceanBaseForOracleTest中,调用存储过程报错:

测试代码如下:
Console.WriteLine("");
Console.WriteLine("#### MasterSlave Start ####");
//OceanBase Oracle 模式用这个 DbType.OceanBaseForOracle
//OceanBase MySql 模式用DbType.MySql不要用这个
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = Config.ConnectionString,//Master Connection
DbType = DbType.OceanBaseForOracle,//Oracle 模式用这个 ,如果是MySql 模式用DbType.MySql
InitKeyType = InitKeyType.Attribute,
IsAutoCloseConnection = true
});
db.Aop.OnLogExecuted = (s, p) =>
{
Console.WriteLine(db.Ado.Connection.ConnectionString);
};
Console.WriteLine("Master:");
//带返回值的存储过程
//create or replace PROCEDURE "Proc_Test_table_return"(
//p_col1 in VARCHAR2,
// p_xx1 out sys_refcursor,
// p_xx2 out sys_refcursor
//) IS
//BEGIN
// --Enter your procedure code
// open p_xx1 FOR
// select* from orders;
// open p_xx2 FOR
// select* from orders;
//END;
var p = new SugarParameter("@p_col1", "");
var p1 = new SugarParameter("@p_xx1", "");
p1.IsRefCursor = true;// 游标
var p2 = new SugarParameter("@p_xx2", "");
p2.IsRefCursor = true;// 游标
var dt1 = db.Ado.UseStoredProcedure().GetDataTable("Proc_Test_table_return", p, p1, p2);
var ret1 = p1.Value;
var ret2 = p2.Value;
热忱回答(23)
-
tcc VIP0
2023/11/7另外,在这边的参数替换时好像没有起到作用,sql本身就只有一个存储过程名称。
0 回复 -
fate sta VIP0
2023/11/7你可以试试SQL方式,ODBC应该不能用 UseStoredProcedure
0 回复 -
tcc VIP0
2023/11/7@fate sta:SQL方式,具体怎么写?
0 回复 -
fate sta VIP0
2023/11/7数据库工具里面怎么调用存储过程就怎么写
0 回复 -
tcc VIP0
2023/11/8@fate sta:试了,简单的存储过程是可以调用的,但是现在如果用游标返回结果集是做不到的,ODBC.dll里报错了,你这边有什么好的建议么?
0 回复 -
fate sta VIP0
2023/11/8@tcc: odbc 驱动好像没游标参数,你可以用ODBC原生ADO.NET试着写一个例子看看
0 回复 -
tcc VIP0
2023/11/8此贴仅做记录,还是希望SqlSugar能支持OceanBaseForOracle调用存储过程返回结果集。
存储过程如下:
create or replace PROCEDURE "PROC_TEST_TABLE"( P_COL1 in VARCHAR2, P_COL2 out VARCHAR2 ) IS BEGIN select ORDER_NAME into P_COL2 from ORDERS where ORDERS.ORDER_ID=P_COL1; END;
原生ODBC需要这样才能调用基础存储过程(不带返回结果集)。
using (OdbcConnection connection = new OdbcConnection(connectionString)) { connection.Open(); using (OdbcCommand command = new OdbcCommand("CALL PROC_TEST_TABLE(?,?)", connection)) { command.CommandType = CommandType.StoredProcedure; // 添加存储过程的输入参数 command.Parameters.Add("P_COL1", OdbcType.NVarChar).Value = "3"; // 添加存储过程的输出参数 OdbcParameter outputParam = new OdbcParameter("P_XX1", OdbcType.NVarChar, 50); outputParam.Direction = ParameterDirection.Output; command.Parameters.Add(outputParam); command.ExecuteNonQuery(); // 获取输出参数的值 string outputValue = (string)outputParam.Value; Console.WriteLine("Output parameter value: " + outputValue); } }SqlSugar里直接调用不行。
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString,//Master Connection DbType = SqlSugar.DbType.OceanBaseForOracle,//Oracle 模式用这个 ,如果是MySql 模式用DbType.MySql InitKeyType = InitKeyType.Attribute, IsAutoCloseConnection = true }); var p = new SugarParameter("@P_COL1", "3"); var p1 = new SugarParameter("@P_XX1", "1"); p1.Direction = ParameterDirection.Output; p1.Size = 100; var dt1 = db.Ado.GetDataTable("CALL PROC_TEST_TABLE(@P_COL1,@P_COL2)", p, p1 ); var ret1 = p1.Value;0 回复 -
fate sta VIP0
2023/11/8db.Ado.UseStoredProcedure().GetDataTable("CALL Proc_Test_table_return", p, p1, p2);这样和你ADO.NET应该一样
0 回复 -
fate sta VIP0
2023/11/8少了UseStoredProcedure
0 回复 -
fate sta VIP0
2023/11/8command.CommandType = CommandType.StoredProcedure; 等同于这个
0 回复 -
紫竹林 VIP0
4天前这个问题还没解决
0 回复 -
fate sta VIP0
4天前@紫竹林:提供ADO.NET能跑的代码,我给你转成sqlsugar代码
0 回复 -
紫竹林 VIP0
4天前string sql = "CALL PROC_TEST_TABLE(@nameP,@ageP)";
var nameP = new SugarParameter("@P_COL1", "1");
var ageP = new SugarParameter("@P_XX1", null, true);//设置为output
var dt = db.Ado.UseStoredProcedure().GetDataSetAll("PROC_TEST_TABLE", nameP, ageP);//返回dt
if (dt != null)
{
Console.WriteLine(dt.Tables[0].toString());
}
按照官网文档,测试报错:
PROC_TEST_TABLE
@P_COL1:1,@P_XX1:
Program Exception:
System.Data.Odbc.OdbcException (0x80131937): ERROR [42000] [ob-2.0.9][5.6.25]OBE-00900: You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'PROC_TEST_TABLE' at line 1
at System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode)
at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, String method, Boolean needReader, Object[] methodArguments, SQL_API odbcApiMethod)
at System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, String method, Boolean needReader)
at System.Data.Odbc.OdbcCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Odbc.OdbcCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
at SqlSugar.OceanBaseForOracle.OceanBaseForOracleDataAdapter.Fill(DataSet ds)
at SqlSugar.AdoProvider.GetDataSetAll(String sql, SugarParameter[] parameters)
at GbaseTest.Program.Main(String[] args) in C:\Users\Administrator\source\repos\sqlsugar-oceanbase-odbc\Program.cs:line 96
Program End.
0 回复 -
紫竹林 VIP0
4天前using SqlSugar;
using System.Data;
using System.Data.Odbc;
namespace sqlsugar_oceanbase_odbc
{
public static class SqlSugarOdbcExtensions
{
/// <summary>
/// 执行一个不返回结果集的存储过程,并获取输出参数的值(适用于 ODBC 连接)。
/// 此方法绕过 SqlSugar 的内部处理,直接使用原生 OdbcCommand,避免因存储过程无结果集而引发的异常。
/// </summary>
/// <typeparam name="T">输出参数的类型</typeparam>
/// <param name="db">SqlSugarClient 实例</param>
/// <param name="procedureName">存储过程名称</param>
/// <param name="setParameters">用于设置输入参数的委托(注意:不要在这里设置输出参数)</param>
/// <param name="outputParameterName">输出参数名称(不含 @ 前缀)</param>
/// <param name="outputDbType">输出参数的 OdbcType(如 OdbcType.NVarChar)</param>
/// <param name="outputSize">输出参数的大小</param>
/// <returns>输出参数的值,已转换为 T 类型</returns>
public static T ExecuteStoredProcedureWithOutput<T>(
this ISqlSugarClient db,
string procedureName,
Action<OdbcParameterCollection> setParameters,
string outputParameterName,
OdbcType outputDbType,
int outputSize)
{
// 获取底层 ODBC 连接
var connection = db.Ado.Connection as OdbcConnection;
if (connection == null)
throw new InvalidOperationException("当前数据库连接不是 OdbcConnection,此扩展方法仅适用于 ODBC 数据源。");
// 确保连接已打开(SqlSugar 通常会自动管理,但为安全起见,检查并打开)
var needClose = connection.State != ConnectionState.Open;
if (needClose)
connection.Open();
try
{
using (var command = new OdbcCommand(procedureName, connection))
{
command.CommandType = CommandType.StoredProcedure;
// 如果 SqlSugar 当前在事务中,将命令事务设置为相同的事务对象
if (db.Ado.Transaction != null)
{
command.Transaction = db.Ado.Transaction as OdbcTransaction;
}
// 调用委托设置输入参数
setParameters(command.Parameters);
// 添加输出参数
var outputParam = new OdbcParameter(outputParameterName, outputDbType, outputSize)
{
Direction = ParameterDirection.Output
};
command.Parameters.Add(outputParam);
// 执行命令(不返回结果集)
command.ExecuteNonQuery();
// 获取输出参数值并转换
object value = outputParam.Value;
if (value == null || value == DBNull.Value)
return default(T);
return (T)Convert.ChangeType(value, typeof(T));
}
}
finally
{
// 如果之前由我们打开的连接,则关闭它(SqlSugar 会自动管理,但主动关闭也无妨)
if (needClose && connection.State == ConnectionState.Open)
connection.Close();
}
}
}
}
ADO.NET能跑的代码,调用上面的方法可以。
string output = db.ExecuteStoredProcedureWithOutput<string>(
"CALL PROC_TEST_TABLE(?,?)",
parameters =>
{
// 设置输入参数(注意:不要添加输出参数,扩展方法内部会添加)
parameters.Add("P_COL1", OdbcType.NVarChar).Value = "1";
},
outputParameterName: "P_XX1",
outputDbType: OdbcType.NVarChar,
outputSize: 50
);
Console.WriteLine("Output parameter value: " + output);
0 回复 -
fate sta VIP0
4天前@紫竹林:
var p1 = new SqlSugar.SugarParameter("@p1", "1"); var outPut = new SqlSugar.SugarParameter("@p2", null, true) ; db.Ado.ExecuteCommand("CALL PROC_TEST_TABLE(@p1,@p2)", new List<SugarParameter>() { p1, outPut }); Console.WriteLine(outPut.Value);差不多这样。
0 回复 -
fate sta VIP0
4天前@fate sta:如果还不行需要线上能跑的DEMO删掉OBJ和BIN打包上传。 DEMO要求ADO.NET执行成功。
0 回复 -
紫竹林 VIP0
4天前CALL PROC_TEST_TABLE(@p1,@p2)
@p1:1,@p2:
Program Exception:
System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at SqlSugar.AdoProvider.ExecuteCommand(String sql, SugarParameter[] parameters)
at SqlSugar.OceanBaseForOracle.OceanBaseForOracleProvider.ExecuteCommand(String sql, SugarParameter[] parameters)
at SqlSugar.AdoProvider.ExecuteCommand(String sql, List`1 parameters)
at GbaseTest.Program.Main(String[] args) in C:\Users\Administrator\source\repos\sqlsugar-oceanbase-odbc\Program.cs:line 112
Program End.
0 回复 -
紫竹林 VIP0
4天前var dt = db.Ado.UseStoredProcedure().GetDataSetAll("PROC_TEST_TABLE", nameP, ageP);//返回dt
这种方式不支持oboracle吗0 回复 -
紫竹林 VIP0
4天前0 回复 -
紫竹林 VIP0
1天前有结果了吗?亲
0 回复 -
fate sta VIP0
1天前@紫竹林:
varp1 =newSqlSugar.SugarParameter("@p1","1");varoutPut =newSqlSugar.SugarParameter("@p2",null,true) ;db.Ado.ExecuteCommand("CALL PROC_TEST_TABLE(@p1,@p2)",newList<SugarParameter>(){p1,outPut});Console.WriteLine(outPut.Value);你按我的DEMO写了吗。我写给你的和你ADO.NET一样的。
0 回复 -
紫竹林 VIP0
1天前复制粘贴你的
0 回复 -
紫竹林 VIP0
1天前我测试代码都给你上传了
0 回复