如何在 SQL*Plus 中将参数(值)从函数传递/调用到“选择”stmt?
Posted
技术标签:
【中文标题】如何在 SQL*Plus 中将参数(值)从函数传递/调用到“选择”stmt?【英文标题】:How to pass/call parameters (values) from Function to 'Select' stmt in SQL*Plus? 【发布时间】:2012-05-08 17:12:39 【问题描述】:我在将参数从我创建的函数传递到“Where”子句中的 SQL*Plus“Select”语句时遇到问题。但是,在这种“Where”子句的情况下,我使用的任何语法似乎都不正确或根本不使用。
这是我创建的函数,它看起来可以编译并运行良好:
CREATE OR REPLACE FUNCTION SA_BILL_CNTRL_EXTRNL_FXN(p_client_code VARCHAR2
,p_bill_seq VARCHAR2
,p_bill_control_seq VARCHAR2)
RETURN VARCHAR2 IS
v_external_id VARCHAR2(30);
v_client_code VARCHAR2(4) := p_client_code;
v_bill_seq NUMBER := to_number(p_bill_seq);
v_bill_control_seq NUMBER := to_number(p_bill_control_seq);
v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM BillControl@SQL_SAREP bc
WHERE bc."ExternalID" IS NOT NULL
AND bc."ExternalID" != ''
AND bc."ClientCode" = p_client_code
AND bc."BillControlSeq" = v_bill_control_seq
AND bc."BillSeq" = v_bill_seq;
IF v_cnt = 1 THEN
SELECT bc."ExternalID"
INTO v_external_id
FROM BillControl@SQL_SAREP bc
WHERE bc."ExternalID" IS NOT NULL
AND bc."ExternalID" != ''
AND bc."ClientCode" = p_client_code
AND bc."BillControlSeq" = v_bill_control_seq
AND bc."BillSeq" = v_bill_seq;
ELSE
v_external_id := NULL;
END IF;
RETURN v_external_id;
END SA_BILL_CNTRL_EXTRNL_FNX;
/
另外,当我在函数中使用“IN OUT”参数时,它在运行后失败了。
现在,这是我在传递参数时遇到困难的“选择”语句:
SELECT NVL(TRIM(eb.CASE_NUM_REEVALUATED), TRIM(eb.CASE_NUM_DUPLICATED)) CaseNumReev
,gnc.BILL_CONTROL_SEQ
FROM EPE_Bill eb NETWORK_CROSSWALK gnc
WHERE substr(eb.MIC_BILL_ID, 5, 4) = SA_BILL_CNTRL_EXTRNL_FNX(p_client_code)
AND gnc.BILL_CONTROL_SEQ = SA_BILL_CNTRL_EXTRNL_FNX(p_bill_seq)
AND (to_number(substr(eb.MIC_BILL_ID, 10, 10), '9999999999') = SA_BILL_CNTRL_EXTRNL_FNX(p_bill_control_seq)
GROUP BY CaseNumReev, gnc.BILL_CONTROL_SEQ;
在过去的两天里,我完全被弄糊涂了。 有了这个,如果你能帮助我解决问题,我将不胜感激。
再次感谢...
【问题讨论】:
您的函数采用 3 个参数(无默认值),但您只使用 1 个参数调用它,这是无效的。 您遇到了什么具体错误?此外,您在发布的代码中的函数名称有错字。在您的创建中,它是 SA_BILL_CNTRL_EXTRNL_FXN,在您的 where 子句中,它是 SA_BILL_CNTRL_EXTRNL_FNX。 你也不能group by
列别名;您需要重复 who nvl
子句(或将其包装另一个选择)。正如您已经发现的那样,您不能从普通 SQL 中调用带有 in out
参数的函数。
【参考方案1】:
试试下面的函数,我也做了一个假设,因为你只传递了一个参数,其余的必须为 NULL
CREATE OR REPLACE FUNCTION SA_BILL_CNTRL_EXTRNL_FXN(p_client_code IN VARCHAR2 DEFAULT NULL
,p_bill_seq IN VARCHAR2 DEFAULT NULL
,p_bill_control_seq IN VARCHAR2 DEFAULT NULL)
RETURN VARCHAR2 IS
v_external_id VARCHAR2(4000);
v_client_code VARCHAR2(4) := p_client_code;
v_bill_seq NUMBER := to_number(p_bill_seq);
v_bill_control_seq NUMBER := to_number(p_bill_control_seq);
v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM BillControl@SQL_SAREP bc
WHERE bc."ExternalID" IS NOT NULL
AND bc."ExternalID" != ''
AND bc."ClientCode" = NVL(p_client_code,bc."ClientCode")
AND bc."BillControlSeq" = NVL(v_bill_control_seq,bc."BillControlSeq")
AND bc."BillSeq" = NVL(v_bill_seq,bc."BillSeq");
IF v_cnt = 1 THEN
SELECT bc."ExternalID"
INTO v_external_id
FROM BillControl@SQL_SAREP bc
WHERE bc."ExternalID" IS NOT NULL
AND bc."ExternalID" != ''
AND bc."ClientCode" = NVL(p_client_code,bc."ClientCode")
AND bc."BillControlSeq" = NVL(v_bill_control_seq,bc."BillControlSeq")
AND bc."BillSeq" = NVL(v_bill_seq,bc."BillSeq");
ELSE
v_external_id := NULL;
END IF;
RETURN v_external_id;
END SA_BILL_CNTRL_EXTRNL_FNX;
/
你的 SQL 应该是
SELECT REC.CaseNumReev,REC.BILL_CONTROL_SEQ FROM
(
SELECT NVL(TRIM(eb.CASE_NUM_REEVALUATED), TRIM(eb.CASE_NUM_DUPLICATED)) CaseNumReev
,gnc.BILL_CONTROL_SEQ AS BILL_CONTROL_SEQ
FROM EPE_Bill eb ,NETWORK_CROSSWALK gnc
WHERE substr(eb.MIC_BILL_ID, 5, 4) = SA_BILL_CNTRL_EXTRNL_FNX(p_client_code)
AND gnc.BILL_CONTROL_SEQ = SA_BILL_CNTRL_EXTRNL_FNX(p_bill_seq)
AND (to_number(substr(eb.MIC_BILL_ID, 10, 10), '9999999999') =SA_BILL_CNTRL_EXTRNL_FNX(p_bill_control_seq))rec
GROUP BY REC.CaseNumReev,REC.BILL_CONTROL_SEQ
【讨论】:
谢谢...我会尝试所有功能/sql 尝试重新编译修改函数成功。然后我运行了 sql,修改了一个错误:ORA-00904: "P_BILL_CONTROL_SEQ": invalid identifier。有什么想法吗? 我想办法在 where 子句中为“p_client_code”使用单引号。所以,忽略 ORA-00904 错误。现在,我有另一个错误: ORA-06502: PL/SQL: numeric or value error: string buffer too small ORA-06512: at "GNXSA.GNX_SA_BILL_CNTRL_EXTRNL_ID", line 28 关于函数的任何想法?非常感谢。 你可以在你的问题中发布函数 GNXSA.GNX_SA_BILL_CNTRL_EXTRNL_ID 这是一个错字,我正在寻找其他内容...错误中正确的 fxn 名称是 - ORA-06502: PL/SQL: numeric or value error: string buffer too small ORA -06512:在“SA_BILL_CNTRL_EXTRNL_FXN”。感谢您注意到...以上是关于如何在 SQL*Plus 中将参数(值)从函数传递/调用到“选择”stmt?的主要内容,如果未能解决你的问题,请参考以下文章