我在Oracle中编写了这个存储过程:
sed -i -E 's/--cgroup-driver=systemd/--cgroup-driver=cgroupfs/' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
我正在使用参数'P_CANCELLATION_SEATS'执行此存储过程,其值为:'10,12' 但它会抛出异常:第一个查询中的Ora-01722(无效数字),问题很可能是IN子句将Number类型列值与我参数中的字符串类型值进行比较。 任何人都可以告诉我如何解决这个问题?
答案 0 :(得分:2)
在运行Proc之前,您必须记住几件事。首先是你是否需要DYNAMIC SQL
。在您的情况下,根本不需要动态SQL。您可以直接执行此操作,如下面的代码所示。其次,您已经确定表格列BOOKD_SEAT
是NUMBER
个库,并且您正在尝试与String
进行比较,因此很明显它会出错。您需要将这些值作为集合传递。见下文:
您修改了代码:
--Create a type of Number to hold your input values
CREATE OR REPLACE TYPE var IS TABLE OF NUMBER;
/
CREATE OR REPLACE PROCEDURE TMS.SP_BOOKING_CANCEL_SMPL (
P_BOOK_TERMINAL NUMBER,
P_BOOK_CODE NUMBER,
P_BOOK_NO VARCHAR2,
P_CANCELLATION_SEATS var, -- Declare the input as type of NUMBER
P_CANCEL_QTY NUMBER,
P_CANCEL_AMOUNT NUMBER,
P_CANCEL_SEAT_QTY NUMBER,
P_SEAT_QTY NUMBER,
P_UNCANCELLED_ID VARCHAR2,
P_UNCANCELLED_QTY NUMBER,
P_CANCEL_TERMINAL NUMBER,
P_CANCEL_SITE NUMBER,
P_CANCEL_SEQ NUMBER,
P_CANCEL_TYPE CHAR,
P_USER_ID VARCHAR2,
P_SYNC CHAR,
P_CREATE_IP VARCHAR2,
P_CREATE_PC VARCHAR2)
IS
V_CANCEL_CODE NUMBER;
BEGIN
UPDATE TMS_BOOKD
SET BOOKD_CANCEL_YN = 'Y',
BOOKD_CANCEL_DATE = SYSDATE,
BOOKD_CANCEL_USER = P_USER_ID,
BOOKD_GENDER = NULL
WHERE BOOKD_TERMINAL = P_BOOK_TERMINAL
AND BOOKD_CODE = P_BOOK_CODE
AND BOOKD_SEAT IN (select column_value from table(P_CANCELLATION_SEATS) );
-- Note you can also use MEMBER of operator and change query as
--BOOKD_SEAT MEMBER OF P_CANCELLATION_SEATS
IF P_CANCEL_SEAT_QTY = P_SEAT_QTY
THEN
UPDATE TMS_BOOKM
SET BOOKM_SET_SEATS = NULL,
BOOKM_SET_QTY = NULL,
BOOKM_SET_AMOUNT = NULL,
BOOKM_CANCEL = 1
WHERE BOOKM_TERMINAL = P_BOOK_TERMINAL
AND BOOKM_CODE = P_BOOK_CODE
AND BOOKM_BOOKNO = P_BOOK_NO;
ELSE
UPDATE TMS_BOOKM
SET BOOKM_SET_SEATS = P_UNCANCELLED_ID,
BOOKM_SET_QTY = P_UNCANCELLED_QTY,
BOOKM_CANCEL = 1
WHERE BOOKM_TERMINAL = P_BOOK_TERMINAL
AND BOOKM_CODE = P_BOOK_CODE
AND BOOKM_BOOKNO = P_BOOK_NO;
END IF;
END;
/
执行:
DECLARE
v_var var := var ();
BEGIN
v_var.EXTEND (2);
--Populate all the values which you want to evalued in IN calsue.
v_var (1) := 1;
v_var (2) := 2;
TMS.SP_BOOKING_CANCEL_SMPL (P_BOOK_TERMINAL => <give your value>
P_BOOK_CODE => <give your value>
P_BOOK_NO => <give your value>
--- pass all the value which you want to be evaluted in IN clause of your query
P_CANCELLATION_SEATS => v_var
P_CANCEL_QTY => <give your value>
P_CANCEL_AMOUNT => <give your value>
P_CANCEL_SEAT_QTY => <give your value>
P_SEAT_QTY => <give your value>
P_UNCANCELLED_ID => <give your value>
P_UNCANCELLED_QTY => <give your value>
P_CANCEL_TERMINAL => <give your value>
P_CANCEL_SITE => <give your value>
P_CANCEL_SEQ => <give your value>
P_CANCEL_TYPE => <give your value>
P_USER_ID => <give your value>
P_SYNC => <give your value>
P_CREATE_IP => <give your value>
P_CREATE_PC => <give your value> )
end;
答案 1 :(得分:1)
参数P_CANCELLATION_SEAT是您想要在IN子句中传递的逗号分隔值的列表,您尝试实现的方式在技术上是错误的,您必须在将逗号分隔后使用它时将其分隔为值列表IN条款。
d_sql := 'UPDATE TMS_BOOKD SET BOOKD_CANCEL_YN = ''Y'', BOOKD_CANCEL_DATE = SYSDATE, BOOKD_CANCEL_USER = :UserId, BOOKD_GENDER = NULL
WHERE BOOKD_TERMINAL = :BookDTerminal AND BOOKD_CODE = :BookDCode AND BOOKD_SEAT in (SELECT to_number(regexp_substr(vlist, ''[^,]+'', 1, LEVEL))
FROM (SELECT :cancellationIds AS vlist FROM dual)
CONNECT BY regexp_substr(vlist, ''[^,]+'', 1, LEVEL) IS NOT NULL)';
BTW,你为什么要使用动态SQL?您可以使用简单的SQL语句执行所有操作。