我有一个存储过程通过游标运行select查询并返回游标(原始Select查询更复杂,我已经缩短了它。)
CREATE OR REPLACE PROCEDURE GETASSIGNEDROLES(IN V_USER_ID INTEGER) SPECIFIC GETASSIGNEDROLES DYNAMIC RESULT SETS 1 LANGUAGE SQL NOT DETERMINISTIC EXTERNAL ACTION READS SQL DATA CALLED ON NULL INPUT INHERIT SPECIAL REGISTERS
BEGIN
DECLARE TEMP_CURSOR CURSOR WITH HOLD WITH RETURN TO CLIENT FOR
SELECT DISTINCT ROLE_ID, ROLE_NAME FROM ROLE ORDER BY ROLE_NAME FOR READ ONLY WITH UR;
IF V_USER_ID IS NOT NULL AND V_USER_ID > 0 THEN
OPEN TEMP_CURSOR;
END IF;
END;
现在,我找不到任何显示如何从返回游标的存储过程中获取值的示例。我相信它与包含select语句的每个其他存储过程是一样的吗?
另外,我的数据库是DB2,因此语法略有不同。到目前为止,我在看了几个关于SO的问题之后得到了以下代码。但我没有使用Datatable找到任何问题并在CMD中传递参数,这是正确的吗?
DataTable DT = new DataTable();
using (var connection = new DB2Connection(ConnectionString))
{
//connection.Open(); //open/close connection will be done implicitely by the DataAdapter.
using (DB2Command cmd = connection.CreateCommand())
{
cmd.CommandText = "GETASSIGNEDROLES";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new DB2Parameter(DataBaseObjects.ParamVUserID, DB2Type.Integer)).Value = userDo.User_ID;
//cmd.CommandTimeout = CommandTimeout; //wait time before terminating the attempt to execute a command and generating an error in secs
using (var da = new DB2DataAdapter(cmd))
{
da.Fill(DT);
}
DT.TableName = TableName;
return DT;
}
}
答案 0 :(得分:1)
有必要研究Db2知识中心的所有相关/链接页面,用于描述C#.net公共语言运行时程序的Db2版本。
启动here并研究每个链接的网页,让示例适用于您的环境。
如果您的Db2服务器在Microsoft-Windows上运行,或者您使用完整数据服务器客户端安装了Windows特定的Db2样本(默认位置为:
\ program files \ ibm \ sqllib \ samples \ dotnet \ cs
)然后你可以在那里看到C#的DataTable示例,也可以在知识中心 - " DbDatMap.cs"和相关文件和" SpClient.cs"及其依赖
请检查您填充DataTable DT
但return DTT
。
如果您调试代码,您应该能够在da.Fill(DT)之后迭代DT中的行;成功完成。
使用大多数语法的consoleApp对我来说很好,唯一的变化就是我使用了预先存在的连接,并为我的存储过程提供了varchar参数而不是整数(但这没有什么区别)。 / p>
答案 1 :(得分:1)
所以我终于开始工作了。关于开放游标,显然是在DB2中如何做到这一点。光标保持打开状态,供客户端应用程序读取。此链接有助于:https://bytes.com/topic/db2/answers/465403-how-do-well-anything-db2-sql
使用的存储过程(从问题修改):
CREATE OR REPLACE PROCEDURE GETASSIGNEDROLES(IN V_USER_ID INTEGER, IN V_BUSINESS_ENTITY_ID INTEGER) SPECIFIC GETASSIGNEDROLES DYNAMIC RESULT SETS 1 LANGUAGE SQL NOT DETERMINISTIC EXTERNAL ACTION READS SQL DATA CALLED ON NULL INPUT INHERIT SPECIAL REGISTERS
BEGIN
DECLARE TEMP_CURSOR CURSOR WITH HOLD WITH RETURN TO CLIENT FOR
SELECT DISTINCT ROLE_ID, ROLE_NAME FROM ROLE ORDER BY ROLE_NAME FOR READ ONLY WITH UR;
IF V_USER_ID IS NOT NULL AND V_USER_ID > 0 THEN
OPEN TEMP_CURSOR;
END IF;
END;
C#中的函数用于调用存储过程并将检索到的数据保存在数据表中:
public DataTable GetAssignedRolesForUser(string ConnectionString, string TableName, User userDo)
{
//LogManager.EventLog("Inside GetAssignedRolesForUser");
try
{
DataTable DTT = new DataTable();
//See if UserID exists check is required here
using (var connection = new DB2Connection(ConnectionString))
{
//connection.Open(); //open/close connection will be done implicitely by the DataAdapter.
using (DB2Command cmd = connection.CreateCommand())
{
cmd.CommandText = DataBaseObjects.spGetAssignedRoles;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new DB2Parameter(DataBaseObjects.ParamVUserID, DB2Type.Integer)).Value = userDo.User_ID;
cmd.Parameters.Add(new DB2Parameter(DataBaseObjects.ParamVBusinessEntityID, DB2Type.Integer)).Value = ConfigurationManager.AppSettings["BusinessEntity"];
//cmd.CommandTimeout = CommandTimeout; //wait time before terminating the attempt to execute a command and generating an error in secs
using (var da = new DB2DataAdapter(cmd))
{
da.Fill(DTT);
}
DTT.TableName = TableName;
return DTT;
}
}
}
catch (Exception)
{
//LogManager.EventLog("[Error] Inside GetAssignedRolesForUser: " + ex.Message);
throw;
}
}
调用C#函数的代码:
DataTable DtRoles = <Call function here>
foreach (DataRow row in DtRoles.Rows)
{
list.Add(Convert.ToInt32(row["ROLE_ID"].ToString()));
}