写了个最简单的存储过程,就是按照地区从学生表里取出学号和姓名,如下:
create or replace PROCEDURE SP_SelectStudentByDq (dq_id IN VARCHAR2, CUR OUT SELECT_PACKAGE.RET_CUR)
AS
BEGIN
OPEN CUR FOR
select code, name from students where dq = dq_id;
END;然后客户端C#调用
OracleCommand cmdToExecute = new OracleCommand();
cmdToExecute.CommandText = "SP_SelectStudentByDq";
cmdToExecute.CommandType = CommandType.StoredProcedure;
cmdToExecute.Connection = _mainConnection;
DataTable retTable = new DataTable();
OracleDataAdapter oAdapter = new OracleDataAdapter(cmdToExecute);cmdToExecute.Parameters.Add(new OracleParameter("dq_id", OracleType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Proposed, _dq));
cmdToExecute.Parameters.Add(new OracleParameter("CUR", OracleType.Cursor, 0, ParameterDirection.Output, false, 0, 0, "", DataRowVersion.Proposed, 0));_mainConnection.Open();
oAdapter.Fill(retTable);
return retTable;
_mainConnection.Close();传入地区参数,比如"11000000"(北京)、"21000000"(辽宁)怎么都取不出来值。
但是在存储过程里面写死:select code, name from students where dq = ‘21000000';马上就取出数据了。或者,将存储过程修改为:select code, name from students where dq like dq_id;
传入"21000000%"或"11000000%"等也能对。实在是气死了,浪费了一下午时间!谁能告诉我这是啥JB问题?

解决方案 »

  1.   

    在procedure中进行debug调试下  很可能就是参数输入有误吧
      

  2.   

    把C#调用参数打印出来 看,用它去测试sql看。
      

  3.   

    输入参数的问题。
       字段dq是什么类型? number类型还是字符型?
      

  4.   


    你用的是微软提供的ado.net库吧(.NET Framework Data Provider for Oracle (OracleConnection))
    为何不用Oracle提供的(Oracle Data Provider for .NET / ODP.NET), 建议用2.x库
    Oracle.DataAccess.Client.OracleConnection从ADO时代,这两者就是Oracle自身提供的库要健全些。你再试试吧,我用Oracle自身提供的ado.net 2.x,没什么问题。
      

  5.   


    谢谢阁下提供思路,一下子想到了是空格的问题,经过测试确是空格的问题。
    数据库里该字段是char(10),所以存的是‘21000000  ’,我传入的是'21000000',所以总取不到数据。造成这个问题一是因为该表是另一个程序员创建,他使用了char字段,我一般都是使用varchar2字段;另外,SQL Server会自动截去空格,ORACLE却没有,常年习惯了SQL Server开发。但奇怪的是如果写死select code, name from students where dq = '21000000';却是能取出数据来,谁能解释这时候为什么又自动截去了空格?让人抓狂的ORACLE!
      

  6.   

    我正是因为测试写死select code, name from students where dq = '21000000';能出来数据,所以一直在检查程序是不是编码名字写错了,数据是不是传错了等等问题,害死我啊!
      

  7.   


    这个确实让人费解你的这句还真是误导了我。不过,从个人角度来讲,我依然推荐使用oracle提供的odp.net驱动。
    仔细了解了一下,如果直接传值,oracle会自动填充空格进行比较,如果动态绑定,则不进行任何填充进行比较。
    目前只能这么解释了。 
      

  8.   


    cmdToExecute.Parameters.Add(new OracleParameter("dq_id", OracleType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Proposed, _dq));原数据库的字段类型是char(10),此处,你可以改为OracleType.Char, 10, ....
    相信应该可以生效。
      

  9.   

    正常,CHAR就是这个比较不好,所以我还是喜欢用VARCHAR
      

  10.   


    也只能这么解释了,事实就是如此了。谢谢阁下!
    ORACLE确实细节差微软太多。
    结贴了。