将 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 作为参数传递给存储过程?