C#中PL/SQL匿名块返回游标到屏障。我正在尝试将匿名块作为动态SQL执行并返回结果集。但是,我尝试过的任何事情似乎都没有返回任何值。存储过程是由于设计限制而完成的。我的查询定义为:DECLAREtypeid_arrayISTABLEOFnumber;t_Idsid_array;BEGINUPDATECSM_RECORDSSETMIGRATION_STATE=1,LAST_UPDATE=CURRENT_DATEWHEREOBJECT_UIDIN(SELECTOBJECT_UIDFROMCSM_RECORDSobjWHEREMIGRATION_STATE=:BatchNameISNULLORobj.BATCH_NAME=:BatchName)返回OBJECT_UIDBULKCOLLECTINTO;tOPENrcursorFORSELECT*FROMCSM_RECORDS;--WHEREOBJECT_UIDIN(t_Ids);结尾;您可以看到我已经注释掉游标子句上的WHERE,试图使任何内容都可返回。在C#方面,我得到:OracleCommandgetNextNodesC=newOracleCommand(SQL_AS_SHOWN_ABOVE,conn);getNextNodesC.BindByName=true;OracleParameterbatchSizeP=newOracleParameter("BatchSize",OracleDbType.Int32);batchSizeP.Value=batchSize;getNextNodesC.Parameters.Add(batchSizeP);OracleParameterbatchNameP=newOracleParameter("BatchName",OracleDbType.Varchar2);batchNameP.Value=batchName;getNextNodesC.Parameters.Add(batchNameP);OracleParameterreturnCursor=newOracleParameter("rcursor",OracleDbType.RefCursor);returnCursor.Direction=ParameterDirection.Output;getNextNodesC.Parameters.Add(returnCursor);getNextNodesC.ExecuteNonQuery();返回((Oracle.ManagedDataAccess.Types.OracleRefCursor)returnCursor.Value).GetDataReader();最终目标是我可以使用DbDataReader,但在上面的代码中,returnCursor.Value似乎保持为空。我尝试了Output和ReturnValue参数以及ExecuteNonQuery()和ExecuteReader()的各种组合,但均无济于事。任何指针将不胜感激,但实际完成我正在寻找的代码示例将是壮观的。TLDR:您错过了游标绑定变量上的冒号:OPEN:rcursorFORSELECT*FROMCSM_RECORDS;--WHEREOBJECT_UIDIN(t_Ids);完整答案:您可能知道,在oracle中有pl/sql上下文(您的匿名块)和SQLplus上下文。这是一个带有SQLplus变量的块,一个带有关联绑定变量的块,最后是SQLplus打印:varrcursorrefcursorvarfromDatevarchar2(50)vartoDatevarchar2(50)exec:fromDate:='1-mar-2014';exec:toDate:='1-apr-2014';开始打开??:rcursorforSELECTtrunc(to_date(:fromDate,'dd-mon-yyyy'))+NUMTODSINTERVAL(n,'day')ASFull_DateFROM(select(level-1)nfromdualconnectbylevel-1block在.net中执行,ODP.net正在处理在SQLplus级别完成的准备工作。这是从.net执行的相同块(作为nunit测试):[Test]publicvoidRefCursorFromBatch(){OracleCommandcmd=newOracleCommand();cmd.CommandText=@"beginopen:rcursorforSELECTtrunc(to_date(:fromDate,'dd-mon-yyyy'))+NUMTODSINTERVAL(n,'day')ASFull_DateFROM(select(level-1)nfromdual通过1级连接您可以在这里阅读更多内容:http://www.brothersincode.com/post/executing-SQL-Plus-Batches-from-Net.aspx如果您还没有答案,这里有一些示例代码我已经确认您可以将其用作起点。使用系统;使用系统数据;使用Oracle.ManagedDataAccess.Client;使用Oracle.ManagedDataAccess.Types;namespaceConsoleApplication1{classClass1{[STAThread]staticvoidMain(string[]args){try{stringconString="UserId=scott;Password=tiger;DataSource=orcl;Pooling=false;";OracleConnectioncon=newOracleConnection();con.ConnectionString=conString;con.Open();stringcmdtxt="BEGIN"+"OPEN:1forselectename,deptnofromempwheredeptno=10;"+"OPEN:2forselectename,deptnofromempwheredeptno=20;"+"OPEN:3forselectename,deptnofromempwheredeptno=30;"+"END;";OracleCommandcmd=con.CreateCommand();cmd.CommandText=cmdtxt;OracleParameterp1=cmd.Parameters.Add("refcursor1",OracleDbType.RefCursor);p1.Direction=ParameterDirection.Output;OracleParameterp2=cmd.Parameters.Add("refcursor2",OracleDbType.RefCursor);p2.Direction=ParameterDirection.Output;OracleParameterp3=cmd.Parameters.Add("refcursor3",OracleDbType.RefCursor);p3.Direction=ParameterDirection.Output;cmd.ExecuteNonQuery();OracleDataReaderdr1=((OracleRefCursor)cmd.Parameters[2].Value).GetDataReader();OracleDataReaderdr2=((OracleRefCursor)cmd.Parameters[1].Value).GetDataReader();while(dr1.Read()&&dr2.Read()){Console.WriteLine("员工姓名:"+dr1.GetString(0)+","+"员工部门:"+dr1.GetDecimal(1));Console.WriteLine("员工姓名:"+dr2.GetString(0)+","+"员工部门:"+dr2.GetDecimal(1));控制台.WriteLine();}Console.WriteLine("Press'Enter'tocontinue");控制台.ReadLine();}catch(Exceptionex){Console.WriteLine(ex.Message);Console.WriteLine(ex.InnerException);Console.WriteLine(ex.Data);}}}}尝试这个动态sql……DECLAREtypeid_arrayISTABLEOFnumber;t_Idsid_array;BEGINUPDATECSM_RECORDSSETMIGRATION_STATE=1,LAST_UPDATE=CURRENT_DATEWHEREOBJECT_UIDIN(从CSM_RECO中选择OBJECT_UIDRDSobjWHEREMIGRATION_STATE=0ANDROWNUM感谢大家的反馈事实证明,在调试这个问题时,在某些时候我切换了定义我的查询的变量,所以当我运行应用程序时,我对查询所做的实际上并没有应用更改制成。因此,我不确定究竟是哪个修复程序得到了答案。但为了完整起见,这就是我最终使用它工作的方式。第一次运行:createtypeid_arrayastableofnumber;(从这个问题的答案)查询:DECLAREt_Idsid_array;BEGINUPDATECSM_RECORDSSETMIGRATION_STATE=1,LAST_UPDATE=CURRENT_DATEWHEREOBJECT_UIDIN(SELECTOBJECT_UIDFROMCSM_RECORDSobjWHEREMIGRATION_STATE=0ANDROWNUM而C#开始像:OracleCommandgetNextNodesC="BOJECT_UID.),conn);getNextNodesC.BindByName=true;OracleParameterbatchSizeP=newOracleParameter("BatchSize",OracleDbType.Int32);batchSizeP.Value=batchSize;getNextNodesC.Parameters.Add(batchSizeP);OracleParameterbatchNameP=newOracleParameter("BatchName",OracleDbType.Varchar2);batchNameP.Value=batchName;getNextNodesC.Parameters.Add(batchNameP);OracleParameterreturnCursor=newOracleParameter("rcursor",OracleDbType.RefCursor);returnCursor.Direction=ParameterDirection.ReturnValue;getNextNodesC.Parameters.Add(returnCursor);returngetNextNodesC.ExecuteReader();b_levitt关于光尽管我还需要将查询中的所有“rn”替换为“n”,但绑定变量上缺少冒号的建议已启用。我不清楚为什么我需要运行CREATETYPE...而不是仅仅使用DECLARETYPE...因为后者似乎适用于块的BULKCOLLECT部分,但它现在似乎运行良好。再次感谢你的帮助。以上就是C#学习教程:C#中PL/SQL匿名块返回游标全部内容分享。如果对大家有用,需要了解更多C#学习教程,希望大家多多关注---本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处:
