C# 从asp.net向Oracle发送带有逗号的字符串似乎会导致问题

C# 从asp.net向Oracle发送带有逗号的字符串似乎会导致问题,c#,asp.net,oracle,C#,Asp.net,Oracle,在我的前端,我发送VarChar变量以用于Oracle中的存储过程。我的前端代码如下所示: protected void Page_Load(object sender, EventArgs e) { OracleConnection conn = GetConnection(); try { { string vw_AuditID = Convert.ToString(Request.QueryString["AuditID"]

在我的前端,我发送VarChar变量以用于Oracle中的存储过程。我的前端代码如下所示:

protected void Page_Load(object sender, EventArgs e)
{
    OracleConnection conn = GetConnection();

    try
    {
        {
            string vw_AuditID = Convert.ToString(Request.QueryString["AuditID"]);
            string vw_PlanID = Convert.ToString(Request.QueryString["PlanID"]);

            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnCST"].ToString();
            OracleCommand cmd3 = new OracleCommand();
            cmd3.CommandType = CommandType.StoredProcedure;
            cmd3.CommandText = "CSTAPP_O.CST_ADMIN_REPORT";
            cmd3.Connection = conn;

            cmd3.Parameters.Add("RAudit", OracleType.VarChar).Value = vw_AuditID;
            cmd3.Parameters.Add("RPlan", OracleType.VarChar).Value = vw_PlanID;
            cmd3.Parameters.Add("cursor_", OracleType.Cursor).Direction = ParameterDirection.Output;

            var SearchAdapter = new OracleDataAdapter(cmd3);
            var ds = new DataSet();
            SearchAdapter.Fill(ds);

            // Perform the binding.
            GridView_AuditReport.DataSource = ds;
            GridView_AuditReport.DataBind();
        }
    }
    catch (Exception ex)
    {
        // Handle the error
        Console.WriteLine("Error making Call to " + ex + "");
    }
}
create or replace PROCEDURE "CST_ADMIN_REPORT" 
(
    RAudit VARCHAR2,
    RPlan VARCHAR2,
    cursor_ OUT SYS_REFCURSOR
) AS 
BEGIN
open cursor_ for

SELECT BLAH // Edited the lengthy SELECT section out, no need for it.
Where FAP.Audit_ID = RAudit
AND FAP.Plan_ID in (RPlan)
ORDER BY FAP.PLAN_DESC ASC;

END CST_ADMIN_REPORT;
请注意,auditd和PlanID来自上一页,并按如下方式传递 ?试听='10294'和计划ID='322323324'

在Oracle方面,我运行的存储过程如下:

protected void Page_Load(object sender, EventArgs e)
{
    OracleConnection conn = GetConnection();

    try
    {
        {
            string vw_AuditID = Convert.ToString(Request.QueryString["AuditID"]);
            string vw_PlanID = Convert.ToString(Request.QueryString["PlanID"]);

            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnCST"].ToString();
            OracleCommand cmd3 = new OracleCommand();
            cmd3.CommandType = CommandType.StoredProcedure;
            cmd3.CommandText = "CSTAPP_O.CST_ADMIN_REPORT";
            cmd3.Connection = conn;

            cmd3.Parameters.Add("RAudit", OracleType.VarChar).Value = vw_AuditID;
            cmd3.Parameters.Add("RPlan", OracleType.VarChar).Value = vw_PlanID;
            cmd3.Parameters.Add("cursor_", OracleType.Cursor).Direction = ParameterDirection.Output;

            var SearchAdapter = new OracleDataAdapter(cmd3);
            var ds = new DataSet();
            SearchAdapter.Fill(ds);

            // Perform the binding.
            GridView_AuditReport.DataSource = ds;
            GridView_AuditReport.DataBind();
        }
    }
    catch (Exception ex)
    {
        // Handle the error
        Console.WriteLine("Error making Call to " + ex + "");
    }
}
create or replace PROCEDURE "CST_ADMIN_REPORT" 
(
    RAudit VARCHAR2,
    RPlan VARCHAR2,
    cursor_ OUT SYS_REFCURSOR
) AS 
BEGIN
open cursor_ for

SELECT BLAH // Edited the lengthy SELECT section out, no need for it.
Where FAP.Audit_ID = RAudit
AND FAP.Plan_ID in (RPlan)
ORDER BY FAP.PLAN_DESC ASC;

END CST_ADMIN_REPORT;
所以,如果我通过一个计划ID,它运行得非常好。但是,如果我传递多个planid(例如“322323324”),Oracle过程会告诉我该数字无效


有谁能告诉我,我将信息传递给Oracle的方式可能有什么问题吗?

Oracle不接受
in(RPlan)
子句中的字符串。不确定这是否是最佳解决方案,但您可以这样解析参数字符串:

in (SELECT REGEXP_SUBSTR(RPlan,'[^,]+', 1, LEVEL) 
    FROM DUAL 
    CONNECT BY REGEXP_SUBSTR(RPlan, '[^,]+', 1, LEVEL) IS NOT NULL)
RPlan
是一个绑定变量,是一个单值-即使您输入逗号分隔的字符串,它仍然是一个单值,并且它试图将
Plan\u ID
列中的数值与包含数字和逗号的字符串相匹配,并有效地执行以下操作:

AND TO_CHAR( FAP.Plan_ID ) = '322,323,324'
这不会产生匹配

如果要传入数组,请使用集合:

CREATE OR REPLACE TYPE IntList IS TABLE OF INTEGER;
/
并将其传递到程序中:

create or replace PROCEDURE CST_ADMIN_REPORT
(
    RAudit  IN  FAP.Audit_ID%TYPE,
    RPlan   IN  IntList,
    cursor_ OUT SYS_REFCURSOR
) AS 
BEGIN
  open cursor_ for
    SELECT BLAH // Edited the lengthy SELECT section out, no need for it.
    Where FAP.Audit_ID = RAudit
    AND FAP.Plan_ID MEMBER OF RPlan
    ORDER BY FAP.PLAN_DESC ASC;
END CST_ADMIN_REPORT;
但是,您可能会发现C#驱动程序只支持传递(而不是集合),因此您可能需要传递关联数组(可以在PL/SQL中使用,但不能在SQL中使用),并将值复制到集合中,然后在SQL语句中使用:

CREATE OR REPLACE PACKAGE CST_ADMIN_PKG
IS
  TYPE IntAssocArrayType IS TABLE OF INTEGER INDEX BY PLS_INTEGER;

  PROCEDURE CST_ADMIN_REPORT
  (
    RAudit  IN  FAP.Audit_ID%TYPE,
    RPlan   IN  IntAssocArrayType,
    cursor_ OUT SYS_REFCURSOR
  );
END;
/

CREATE OR REPLACE PACKAGE BODY CST_ADMIN_PKG
IS
  PROCEDURE CST_ADMIN_REPORT
  (
    RAudit  IN  FAP.Audit_ID%TYPE,
    RPlan   IN  IntAssocArrayType, -- Pass assoc. array in.
    cursor_ OUT SYS_REFCURSOR
  )
  AS
    -- Create a collection
    p_rplan IntList := IntList(); 
    i       PLS_INTEGER;
  BEGIN
    -- Copy assoc. array into the collection
    i := RPlan.FIRST:
    WHILE i IS NOT NULL LOOP
      p_rplan.EXTEND;
      p_rplan(p_rplan.COUNT) := RPlan(i);
      i := RPlan.NEXT(i);
    END LOOP;

    open cursor_ for
      SELECT BLAH
      Where FAP.Audit_ID = RAudit
      AND FAP.Plan_ID MEMBER OF p_RPlan -- Use the collection in the select.
      ORDER BY FAP.PLAN_DESC ASC;
  END CST_ADMIN_REPORT;
END;
/

当你说“前端代码”,然后把数据库访问混为一谈时,我会退缩。数据库访问并不是直接在你的代码后面——它应该在一个单独的层中。您需要学习如何正确处理(您的OracleConnection)。正如我在中所解释的,请将您的问题分开。这个问题要么与查询字符串有关,要么与Oracle有关,而不是两者都有。查询字符串不了解Oracle,反之亦然。这都是关于字符串的,所以把你的问题精简到一个简单的问题。我还逐字解释了错误,而不是你的解释。“甲骨文程序告诉我数字无效”并不是一个逐字逐句的错误。我一直对一些人所拥有的知识感到惊讶和谦卑。如果我对甲骨文所知甚少,我永远也不会明白这一点。