执行ODCIIndexStart()例程时出错

时间:2017-08-04 10:45:16

标签: plsql

我有一个包含多个函数的SEARCH包,每个包都返回一个pipelined表。

我收到以下错误:

ORA-29902: error in executing ODCIIndexStart() routine
ORA-06512: at "<SCHEMA_NAME>.SEARCH", line 955
ORA-06512: at "<SCHEMA_NAME>.SEARCH", line 216
ORA-06512: at line 1
ORA-06512: at "<SCHEMA_NAME>.SEARCH", line 1143
ORA-06512: at line 1
29902. 00000 -  "error in executing ODCIIndexStart() routine"
*Cause:    The execution of ODCIIndexStart routine caused an error.
*Action:   Examine the error messages produced by the indextype code and
           take appropriate action.

我用来获取此错误的命令是:

 select * from table(search.user_search(10000003, '', 1, 20, 5, '', '', ''));

以下是SEARCH正文的第1143行的代码:

FUNCTION USER_SEARCH(p_user_id number, p_search varchar2, p_page number, p_num_results number, p_concept_type_id number := null, p_standard_org varchar2 := null, p_standard_title varchar2 := null, p_standard_number varchar2 := null) RETURN SEARCH_RESULTS_TABLE AS

v_sub char(1);

v_rtn search_results_table := search_results_table();

v_user_id number;

v_page number;
v_num_results number;

v_query varchar2(4000);

cursor c_concept is
  select * from table(search.concept_new(v_user_id, v_query, v_page, v_num_results, p_concept_type_id, p_standard_org, p_standard_title, p_standard_number));

BEGIN
  v_page := p_page;
  v_num_results := p_num_results;

  v_query := p_search;

  if (v_query = '') then

    v_query := null;

  end if;

  -- ONLY DURING DEVELOPMENT
  v_user_id := p_user_id;

  if v_user_id = 0 then
    v_user_id := 2;
  end if;


  if v_page = null then
    v_page := 1;
  end if;

  if v_num_results = null then
    v_num_results := -1;
  end if;

  select security.has_permission(p_user_id, 'UNLIMITED_RESULTS') into v_sub from dual;

  case v_sub
    when 'N' then
      v_rtn := search.term(v_user_id, p_search, 1, 20, P_concept_type_id, p_standard_org, p_standard_title, p_standard_number);
    when 'Y' then
      for r_concept in c_concept loop -- line 1143
        v_rtn.extend;

        v_rtn(v_rtn.last) := search_results_row(r_concept.SCORE, r_concept.FROM_TABLE, r_concept.ID, r_concept.IN_DICTIONARY);
      end loop;
  end case;

  return v_rtn;

END USER_SEARCH;

第216行的代码:

FUNCTION CONCEPT_NEW(p_user_id number, p_search varchar2, p_page number := 1, p_num_results number := -1, p_concept_type_id number := null, p_standard_org varchar2 := null, p_standard_title varchar2 := null, p_standard_number varchar2 := null) RETURN SEARCH_RESULTS_TABLE PIPELINED AS

  out_rec search_results_row := search_results_row(null,null,null,null);

  v_num_pages number;
  v_num_results number;

  cursor c_count is
    select count(*) cnt, ceil(count(*) / p_num_results) num_pages from (
    select * from (
    select rownum rn, bb.* from (
      select * from (
        select sum(score) score, concept_id from
        (
          (
            select 
              sum(score) score,
              concept_id
            from
            (
              select
                s.score + (case
                when c.eotd = 'N' then
                  200
                else 
                  0
                end) score,
                ct.concept_id
              from
                table(search.synonym_search(p_search)) s,
                term_synonym ts,
                concept_term ct,
                concept c
              where
                c.eotd = 'N' and
                s.table_id = ts.synonym_id and
                ts.term_id = ct.term_id and
                c.concept_id = ct.concept_id
            )
            group by
              concept_id
          )
          union all
          (
          select 
            sum(score) score,
            concept_id
          from
          (
            select
              s.score + (case
              when c.eotd = 'N' then
                200
              else 
                0
              end) score,
              cd.concept_id
            from
              table(search.definition_search(p_search)) s,
              concept_definition cd,
              concept c
            where
                c.eotd = 'N' and
              s.table_id = cd.definition_id and
              c.concept_id = cd.concept_id
          )
          group by
            concept_id
          )
        )
        group by concept_id
      ) order by score desc
    ) bb) where score > 100) where rn < 1000;

    -- another cursor here called c_search (removed for cleanliness)

    v_added boolean;

    v_in_dict varchar(1);

    v_concept_id number;

    cursor c_in_dict is
      select * from dictionary_concept where concept_id = v_concept_id and dictionary_id in (select dictionary_id from company_dictionary where client_company_id in (select client_company_id from users where users_id = p_user_id));

    v_in_dict_result c_in_dict%rowtype;  

BEGIN

  open c_count;

  fetch c_count into v_num_results, v_num_pages; -- line 216

  close c_count;

  out_rec.SCORE := v_num_results;
  out_rec.FROM_TABLE := 'HEADER';
  out_rec.ID := v_num_pages;
  out_rec.IN_DICTIONARY := 'N';

  pipe row(out_rec);

  -- more code here but been removed

  RETURN;

END CONCEPT_NEW;

第995行的代码:

FUNCTION STANDARD_SEARCH(p_search varchar2) RETURN RESULT_TABLE 
PIPELINED
AS

  out_rec result_type := result_type(null, null);

  cursor c_search is
    select 
      45 score,
      source_id
    from
      source
    where
      source_title = p_search or
      standard_number = p_search
    union all
    select
      40,
      source_id
    from
      source
    where
      lower(source_title) = lower(p_search) or
      lower(standard_number) = lower(p_search)
    union all
    select
      35,
      source_id
    from
      source
    where
      lower(source_title) like lower(p_search) || '%' or
      lower(standard_number) like lower(p_search) || '%'
    union all
    select
      30,
      source_id
    from
      source
    where
      lower(source_title) like '%' || lower(p_search) || '%' or
      lower(standard_number) like '%' || lower(p_search) || '%'
    union all
    select
      10 * contains(source_title, lower(p_search)),
      source_id
    from
      source
    where 
      contains(source_title, lower(p_search)) > 1
    union all
    select
      10 * contains(standard_number, lower(p_search)),
      source_id
    from
      source
    where 
      contains(standard_number, lower(p_search)) > 1;

BEGIN

  for r_search in c_search loop -- line 995

    out_rec.SCORE := r_search.SCORE;
    out_rec.TABLE_ID := r_search.SOURCE_ID;

    pipe row(out_rec);

  end loop;

  return;
END;

1 个答案:

答案 0 :(得分:0)

using System; using System.Collections.Generic; using System.Configuration; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class Order : System.Web.UI.Page { //Order obj = new Order(); static int i = 0; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ddl_select_item.DataSource = MenuServices.ShowMenu(); ddl_select_item.DataTextField = "itemName"; ddl_select_item.DataValueField = "itemId"; ddl_select_item.DataBind(); } } protected void btn_AddCart_Click(object sender, EventArgs e) { int tempindex = int.Parse(ddl_select_item.SelectedItem.Value); SqlConnection con; SqlCommand cmd; SqlDataReader dr; con = new SqlConnection(ConfigurationManager.ConnectionStrings["con"].ConnectionString); con.Open(); cmd = new SqlCommand(); cmd.CommandText = "select * from Menu where itemId = @id"; cmd.Connection = con; cmd.Parameters.Add("id", tempindex); dr = cmd.ExecuteReader(); //int tempflag = 0; if (dr.Read()) { OrderMenu.orderCart[i] = new Item { itemId = Convert.ToInt32(dr["itemId"]), itemName = dr["itemName"].ToString(), itemPrepTime = dr["itemPrepTime"].ToString(), itemPrice = Convert.ToInt32(dr["itemPrice"]) }; } showgrid(OrderMenu.orderCart); } public void showgrid(Item[] obj1) { GridViewCart.DataSource = obj1.ToList<Item>(); GridViewCart.DataBind(); } } 更改为= null。 is null也是错误的。

这些是一些明显的错误,但代码是如此复杂,我不确定它们是否与错误直接相关。您可能需要缩小代码,直到它可以放入一个小的,可重现的测试用例中。这有时可能需要数小时的工作。

另一个建议是重新考虑是否需要使用流水线功能。根据我的经验,流水线功能有缺陷和过度使用。有时它们可​​以被常规SQL语句替换。有时它们可​​以被更简单的函数替换,该函数返回完整的集合,而不是一次返回一行。除非集合是如此巨大以至于它无法合理地存储在内存中,或者您需要函数返回前N个结果以便可以立即处理它们,所以流水线功能无助于此。