使用ODP.net将匿名参数传递到Oracle

时间:2011-07-31 19:31:31

标签: parameters odp.net

不知何故,我了解到我可以简单地将参数传递到Oracle存储过程中,并且它能够将参数转换为适当的类型。好吧,我遇到了与此有关的问题。我收到一个“ORA-00900:无效的SQL语句”给我回复......我猜这是因为我试图传入字符串...这就是我在某处读到的内容...... “http://www.dba-oracle.com/sf_ora_00900_invalid_sql_statement.htm”

将Oracle参数输入存储过程然后使用.net变量执行存储过程的技术是什么?我是否必须将.net字符串转换为ODP数据类型?我希望不是......

这是我的代码一般做的......

    XmlAttribute xAttribute;
        using (OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["ACODBConnectionString"].ConnectionString))
        {

            using (OracleCommand cmd = new OracleCommand(sProc, conn))
            {
                int i = 0;
                foreach (string path in paths)
                {
                    string OracleParam;
                    xAttribute = AcoXMLDoc.SelectSingleNode(string.Format("//dataTemplateSpecification/templates/template/elements/element[@name='{0}']", path)).Attributes["value"];
                    if ((xAttribute.Value == null))
                    {
                        OracleParam = "";
                        cmd.Parameters.Add(colName[i], OracleParam);
                    }
                    else
                    {
                        OracleParam = xAttribute.Value;
                        cmd.Parameters.Add(colName[i], OracleParam);
                    }
                    i++;
                }
                conn.Open();
                outcome = cmd.ExecuteNonQuery();
            }
        }

正如你所看到的,我正在从XML文档中提取值,所以自然值将成为字符串...如果我必须弄清楚如何更改将字符串转换为适当的数据类型......

1 个答案:

答案 0 :(得分:1)

cmd.Parameters.Add()期望一个对象是一个参数(不是参数的值)

所以这是可行的,有一些警告,但这是一个测试用例:


设置Oracle位:

create table testParam(aa number, bb varchar2(50) , cc date) 
/
create or replace procedure testProcParam(
                  p_aa IN TESTPARAM.AA%TYPE , --usage of tableName.ColumnName%Type has this "scoped" to the table.column AA (here it is number)
                  p_BB IN TESTPARAM.BB%TYPE , --The usage of TYPE here has it defined as VARCHAR2
                  p_CC IN TESTPARAM.CC%TYPE  --this is DATE
) is
BEGIN
    INSERT INTO testParam (AA, BB, CC) VALUES(P_AA, P_BB, P_CC);
END testProcParam ;
/

现在为.net位:

  OracleConnection con = Connect(constr);

  // Set the command
  OracleCommand cmd = new OracleCommand("testProcParam", con);
  cmd.CommandType   = CommandType.StoredProcedure;
  cmd.BindByName = false; /*mark this false to bind by position*/

  string AA = "123456" ;
  OracleParameter oparamAA  = new OracleParameter() ;
  oparamAA.Value = AA;
  cmd.Parameters.Add(oparamAA);

  string BB = "abcdefghijklmnopqrst" ;
  OracleParameter oparamBB  = new OracleParameter() ;
  oparamBB.Value = BB;      
  cmd.Parameters.Add(oparamBB);

  string CC = "01-AUG-11" ; /*we rely on the nls date parameter to 'cast' this*/
  OracleParameter oparamCC  = new OracleParameter() ;
  oparamCC.Value = CC;      
  cmd.Parameters.Add(oparamCC);      

  cmd.ExecuteNonQuery ();

  con.Close();
  con.Dispose();   

现在需要注意的事项:

  1. 请注意我是如何创建参数并为其指定“字符串”值的(http://download.oracle.com/docs/cd/B19306_01/win.102/b14307/OracleParameterClass.htm#i1011127您将看到构造函数要么没有dbtype,要么必须明确说明它,这可以解决这个问题。
  2. 如果参数未命名(即您依赖顺序位置),则必须“cmd.BindByName = false;”
  3. 对于日期,NLS格式在这里发挥作用(因此,如果您更改日期格式等,您将打开自己的最新问题)。

  4. 然后你会得到你的数据:

    SELECT * FROM testParam;
    
    AA                     BB                                                 CC                        
    ---------------------- -------------------------------------------------- ------------------------- 
    123456                 abcdefghijklmnopqrst                               01/08/11 00:00:00  
    
    /* --now to clean up
    DROP procedure testProcParam ;
    DROP table testParam ;
    */
    


    修改

    根据你的评论;在使用

    时PL / SQL中的参数
      

    tableName.ColumnName%类型

    实际上,您只是将该数据类型绑定到表中的列数据类型(这样可以更改列,并且不会破坏包)。

    我提供的例子:

                      p_aa IN TESTPARAM.AA%TYPE , 
                      p_BB IN TESTPARAM.BB%TYPE , 
                      p_CC IN TESTPARAM.CC%TYPE  
    

    相同
                      p_aa IN NUMBER, 
                      p_BB IN VARCHAR2  , 
                      p_CC IN DATE
    

    不确定您可以传递的“匿名/通用数据类型”