将 xml 数据作为存储过程的参数传递给 s-s-rs

Posted

技术标签:

【中文标题】将 xml 数据作为存储过程的参数传递给 s-s-rs【英文标题】:Passing xml data as parameter for stored procedure to s-s-rs 【发布时间】:2015-08-02 11:48:25 【问题描述】:

我在 asp.net 和报告服务中使用 Oracle 数据库。我创建了以 xml 文件作为参数的 oracle 存储过程,如下所示:

create or replace
PROCEDURE SAL_REP_DETAILS_XML   (

    P_CRITERIA_XML XMLTYPE ,
    P_EMPLOYEES OUT SYS_REFCURSOR,
    P_ALLOWNCES OUT SYS_REFCURSOR,
    P_DEDUCTIONS OUT SYS_REFCURSOR ,
    p_criteria OUT sys_refcursor) 
AS
  V_SARF_AR_CONCACT VARCHAR2(500) ;
  V_SARF_en_CONCACT VARCHAR2(500) ;
  v_from_month      NUMBER ;
  v_from_year       NUMBER ;
  v_to_year         NUMBER ;
  v_to_month        NUMBER ;
BEGIN
  FOR I IN
  (SELECT xmltype.extract (value (TAB),'/CRITERIA/P_FROM_DATE/text()').GETSTRINGVAL()   AS P_FROM_DATE ,
    XMLTYPE.EXTRACT (VALUE (TAB),'/CRITERIA/P_TO_DATE/text()').GETSTRINGVAL()           AS P_TO_DATE ,
    XMLTYPE.EXTRACT (VALUE (TAB),'/CRITERIA/P_EMPID/text()').GETSTRINGVAL()             AS P_EMPID ,
    XMLTYPE.EXTRACT (VALUE (TAB),'/CRITERIA/P_PAYROLL_TYPES_ARR/text()').GETSTRINGVAL() AS P_PAYROLL_TYPES_ARR ,
    XMLTYPE.EXTRACT (VALUE (TAB),'/CRITERIA/P_DEPT/text()').GETSTRINGVAL()              AS P_DEPT ,
    XMLTYPE.EXTRACT (VALUE (TAB),'/CRITERIA/P_REPORTFLAG/text()').GETSTRINGVAL()        AS P_REPORTFLAG
  FROM TABLE (XMLSEQUENCE ( P_CRITERIA_XML.extract ('/Root/CRITERIA'))) TAB
  ) 
  LOOP
    SELECT wm_concat(SARFNAME) ,
      wm_concat(SARFENNAME)
    INTO V_SARF_AR_CONCACT ,
      V_SARF_en_CONCACT
    FROM HRSARFIAT
    WHERE SARFID IN
      (SELECT * FROM TABLE (system_HELPER.string_tokenizer(i.P_PAYROLL_TYPES_ARR))
      );
    SELECT to_number (TO_CHAR( to_date(i.P_FROM_DATE, 'dd/mm/YYYY HH24:Mi:ss') , 'MM') )
    INTO v_from_month
    FROM dual ;
    SELECT to_number (TO_CHAR( to_date(i.P_FROM_DATE, 'dd/mm/YYYY HH24:Mi:ss') , 'YYYY') )
    INTO v_from_year
    FROM dual ;
    SELECT to_number (TO_CHAR( to_date(i.P_TO_DATE , 'dd/mm/YYYY HH24:Mi:ss') , 'YYYY') )
    INTO v_to_year
    FROM dual ;
    SELECT to_number (TO_CHAR( to_date(i.P_TO_DATE , 'dd/mm/YYYY HH24:Mi:ss') , 'MM') )
    INTO v_to_month
    FROM dual ;
    OPEN P_CRITERIA FOR SELECT system_HELPER.GET_APP_CODES_DESC(11,v_from_month ,1)
  AS
    MONTH_FROM_NAME_AR ,
    system_HELPER.GET_APP_CODES_DESC(11,v_from_month ,2)
  AS
    MONTH_FROM_NAME_EN ,
    system_HELPER.GET_APP_CODES_DESC(11,v_to_month ,1)
  AS
    MONTH_TO_NAME_AR ,
    system_HELPER.GET_APP_CODES_DESC(11,v_to_month ,2)
  AS
    MONTH_TO_NAME_EN ,
    v_from_year
  AS
    FROM_YEARCODE ,
    v_to_year
  AS
    to_YEARCODE ,
    i.P_FROM_DATE
  AS
    date_from ,
    i.P_to_DATE
  AS
    DATE_TO ,
    V_SARF_AR_CONCACT
  AS
    PAYROLL_TYPES_AR ,
    V_SARF_en_CONCACT
  AS
    PAYROLL_TYPES_en FROM dual ;
    OPEN P_EMPLOYEES FOR SELECT result_data.* ,
    PRS_EMP.EMP_PIC FROM
    ( SELECT DISTINCT HR_EMP_SALARY.EMP_ID AS EMP_ID ,
      "PRS_EMP"."EMP_AR_DATA"              AS EMP_DATA_AR ,
      "PRS_EMP"."EMP_EN_DATA"              AS EMP_DATA_en ,
      "HREMPLOYMENTDATA"."JOBCODE" ,
      "PRS_JOBS"."JOBARNAME" AS JOBNAME_AR ,
      "PRS_JOBS"."JOBENNAME" AS JOBNAME_en ,
      HREMPLOYMENTDATA.CONTRACTSTDATE ,
      HREMPLOYMENTDATA.ATM_ACCOUNT ,
      PRS_EMP.EMP_GENDUR ,
      0                         AS SAL_COMP_CODE_A ,
      ' '                       AS COMP_DESC_A_AR ,
      ' '                       AS COMP_DESC_A_en ,
      0                         AS SAL_VALUE_A ,
      0                         AS SAL_COMP_CODE_D ,
      ' '                       AS COMP_DESC_D_AR ,
      ' '                       AS COMP_DESC_D_en ,
      0                         AS SAL_VALUE_D ,
      0                         AS SAL_VALUE_NET ,
      GLCURRANCY.CURRARSYMBOL   AS CURRSYMBOL_AR ,
      GLCURRANCY.CURRENSYMBOL   AS CURRSYMBOL_en ,
      GLCURRANCY.FRACTIONENNAME AS FRACTIONNAME_EN ,
      GLCURRANCY.FRACTIONNAME   AS FRACTIONNAME_ar
    FROM HR_EMP_SALARY ,
      HR_SALARY_COMPONENT ,
      PRS_EMP ,
      HREMPLOYMENTDATA ,
      PRS_JOBS ,
      GLCURRANCY
    WHERE HR_SALARY_COMPONENT.COMP_ID                     = HR_EMP_SALARY.SAL_COMP_CODE
    AND HR_EMP_SALARY.EMP_ID                              = "HREMPLOYMENTDATA"."EMP_ID"(+)
    AND "PRS_JOBS"."JOBCODE"(+)                           = "HREMPLOYMENTDATA"."JOBCODE"
    AND HR_EMP_SALARY.EMP_ID                              = "HREMPLOYMENTDATA"."EMP_ID"
    AND HR_EMP_SALARY.EMP_ID                              = PRS_EMP.EMP_ID
    AND GLLOCAL                                           = 1
    AND to_date(TO_CHAR( SAL_DATE ,'MM/YYYY'),'MM/YYYY') >= to_date(TO_CHAR(to_date(i.P_FROM_DATE, 'dd/mm/YYYY HH24:Mi:ss'),'MM/YYYY'),'MM/YYYY')
    AND to_date(TO_CHAR(SAL_DATE ,'MM/YYYY'),'MM/YYYY')  <= to_date(TO_CHAR(to_date(i.P_TO_DATE, 'dd/mm/YYYY HH24:Mi:ss'),'MM/YYYY'),'MM/YYYY')
    AND (HR_EMP_SALARY.EMP_ID                            IN
      (SELECT * FROM TABLE (SYSTEM_HELPER.STRING_TOKENIZER(i.P_EMPID))
      )
    OR i.P_EMPID              IS NULL)
    AND (HR_EMP_SALARY.SARFID IN
      (SELECT * FROM TABLE (SYSTEM_HELPER.STRING_TOKENIZER(i.P_PAYROLL_TYPES_ARR))
      )
    OR i.P_PAYROLL_TYPES_ARR IS NULL)
    ORDER BY EMP_ID
    ) result_data ,
    prs_emp WHERE prs_emp.EMP_ID = result_data.EMP_ID ;
    OPEN P_ALLOWNCES FOR SELECT HR_EMP_SALARY.EMP_ID
  AS
    EMP_ID ,
    HR_SALARY_COMPONENT.COMP_ID
  AS
    SAL_COMP_CODE ,
    HR_SALARY_COMPONENT.COMP_ARDESC
  AS
    COMP_DESC_AR ,
    HR_SALARY_COMPONENT.COMP_ENDESC
  AS
    COMP_DESC_en ,
    HR_EMP_SALARY.SAL_VALUE
  AS
    SAL_VALUE ,
    HR_SALARY_COMPONENT.COMP_TYPE
  AS
    SAL_COMP_TYPE FROM HR_EMP_SALARY ,
    HR_SALARY_COMPONENT WHERE HR_SALARY_COMPONENT.COMP_ID = HR_EMP_SALARY.SAL_COMP_CODE AND to_date(TO_CHAR( SAL_DATE ,'MM/YYYY'),'MM/YYYY') >= to_date(TO_CHAR(to_date(i.P_FROM_DATE, 'dd/mm/YYYY HH24:Mi:ss'),'MM/YYYY'),'MM/YYYY') AND to_date(TO_CHAR(SAL_DATE ,'MM/YYYY'),'MM/YYYY') <= to_date(TO_CHAR(to_date(i.P_TO_DATE, 'dd/mm/YYYY HH24:Mi:ss'),'MM/YYYY'),'MM/YYYY') AND HR_SALARY_COMPONENT.COMP_TYPE = 1 AND ( HR_EMP_SALARY.EMP_ID IN
      (SELECT * FROM TABLE (SYSTEM_HELPER.STRING_TOKENIZER(i.P_EMPID))
      ) OR i.P_EMPID IS NULL) AND (HR_EMP_SALARY.SARFID IN
      (SELECT * FROM TABLE (SYSTEM_HELPER.STRING_TOKENIZER(i.P_PAYROLL_TYPES_ARR))
      ) OR i.P_PAYROLL_TYPES_ARR IS NULL) ORDER BY EMP_ID ,
    SAL_COMP_TYPE ,
    HR_SALARY_COMPONENT.ITEM_SORT ,
    HR_SALARY_COMPONENT.COMP_ID;
    OPEN P_DEDUCTIONS FOR SELECT HR_EMP_SALARY.EMP_ID
  AS
    EMP_ID ,
    HR_EMP_SALARY.SAL_COMP_CODE
  AS
    SAL_COMP_CODE ,
    HR_SALARY_COMPONENT.COMP_ARDESC
  AS
    COMP_DESC_AR ,
    HR_SALARY_COMPONENT.COMP_ENDESC
  AS
    COMP_DESC_en ,
    HR_EMP_SALARY.SAL_VALUE
  AS
    SAL_VALUE ,
    HR_SALARY_COMPONENT.COMP_TYPE
  AS
    SAL_COMP_TYPE FROM HR_EMP_SALARY ,
    HR_SALARY_COMPONENT WHERE HR_SALARY_COMPONENT.COMP_ID = HR_EMP_SALARY.SAL_COMP_CODE AND to_date(TO_CHAR( SAL_DATE ,'MM/YYYY'),'MM/YYYY') >= to_date(TO_CHAR(to_date(i.P_FROM_DATE, 'dd/mm/YYYY HH24:Mi:ss'),'MM/YYYY'),'MM/YYYY') AND to_date(TO_CHAR(SAL_DATE ,'MM/YYYY'),'MM/YYYY') <= to_date(TO_CHAR(to_date(i.P_TO_DATE, 'dd/mm/YYYY HH24:Mi:ss'),'MM/YYYY'),'MM/YYYY') AND HR_SALARY_COMPONENT.COMP_TYPE = 2 AND ( HR_EMP_SALARY.EMP_ID IN
      (SELECT * FROM TABLE (SYSTEM_HELPER.STRING_TOKENIZER(i.P_EMPID))
      ) OR i.P_EMPID IS NULL) AND (HR_EMP_SALARY.SARFID IN
      (SELECT * FROM TABLE (SYSTEM_HELPER.STRING_TOKENIZER(i.P_PAYROLL_TYPES_ARR))
      ) OR i.P_PAYROLL_TYPES_ARR IS NULL) ORDER BY EMP_ID ,
    SAL_COMP_TYPE ,
    HR_SALARY_COMPONENT.ITEM_SORT ,
    HR_SALARY_COMPONENT.COMP_ID;
  END LOOP ;

END SAL_REP_DETAILS_XML;

当为这个存储过程的报表创建一个数据集时,一个窗口出现在我面前(定义查询参数)

输入xml数据时如下:

<Root><CRITERIA><P_REPORTFLAG>1</P_REPORTFLAG><COMPUTER_NAME>dev-101</COMPUTER_NAME><P_PROCESS_ID>10859</P_PROCESS_ID><REPORT_DESIGNER>0</REPORT_DESIGNER><REPORT_FILTER>1</REPORT_FILTER><REPORT_PORTRAIT>0</REPORT_PORTRAIT><REPORT_SIZE>0</REPORT_SIZE><REPORT_RELOAD>0</REPORT_RELOAD><P_EMPID>1</P_EMPID><P_FROM_DATE>01/05/2015</P_FROM_DATE><P_TO_DATE>01/05/2015</P_TO_DATE><REPORT_LANGUAGE>1</REPORT_LANGUAGE><BRANCH_ID>1</BRANCH_ID><USER_ID>KHABEER</USER_ID></CRITERIA></Root>

我有一个错误,它的描述是(ORA-06550:第 1 行,第 7 列: PLS-00306:调用“SAL_REP_DETAILS_XML”时参数的数量或类型错误 ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略)。

谁能帮我解决这个问题?

【问题讨论】:

【参考方案1】:

要使用 XMLType 输入和输出游标测试此类过程,我更喜欢编写一个显式 PL/SQL 块 - 这里是一个示例。

 declare
     v_EMPLOYEES   SYS_REFCURSOR;
     v_ALLOWNCES   SYS_REFCURSOR;
     v_DEDUCTIONS   SYS_REFCURSOR;
     v_criteria    sys_refcursor;
     -- your declaration for test
     l_employee_id     number;
     l_employee_name   varchar2(100);
 BEGIN
    SAL_REP_DETAILS_XML(
     xmltype('<Root/>'), /* your xml here */
     v_EMPLOYEES,
     v_ALLOWNCES,
     v_DEDUCTIONS,
     v_criteria);

     /* to read the output cursors use fetch in a loop */
     LOOP
        FETCH v_EMPLOYEES INTO l_employee_id, l_employee_name ;
        EXIT WHEN v_EMPLOYEES%NOTFOUND;
        dbms_output.put_line(l_employee_id || l_employee_name);
     END LOOP;
 END;
 / 

【讨论】:

我使用 XML 运行该过程并返回数据。程序没有问题我在报告服务中创建数据集的问题

以上是关于将 xml 数据作为存储过程的参数传递给 s-s-rs的主要内容,如果未能解决你的问题,请参考以下文章

将 xml 作为参数传递给 SQL Server 中的存储过程

将 xml 字符串参数传递给 SQL Server 存储过程

mysql 存储过程 数据库表名字段作为参数传递给存储过程的方法

如何通过不提交当前会话事务将 DataTable 作为参数传递给存储过程?

将 Access 表日期值作为参数传递给 SQL Server 存储过程

将Datetime作为参数传递给PyODBC的存储过程时出错