我正在尝试执行以下程序,但一直收到错误(ORA-00900:无效的SQL语句)
CREATE OR REPLACE PROCEDURE RESETUSERSESSION (run IN VARCHAR2)
IS
cursor usersessiondetail_cur IS
SELECT usd.CLIENTID,usd.OPERID,usd.REGISTER,usd.MACHINE_ID,usd.SESSIONNUMBER
FROM cashiering_dev.CSH_USER usr, cashiering_dev.CSH_USERSESSIONDETAIL usd
WHERE usr.clientid = usd.clientid
AND usr.operid = usd.operid
AND usr.register = usd.register
AND usr.machine_id = usd.machine_id
AND usr.sessionnumber = usd.sessionnumber
AND usr.Machine_ID = 'basrytest'
AND usd.LOGOFFDATETIME IS NULL;
BEGIN
OPEN usersessiondetail_cur;
FOR vItems in usersessiondetail_cur
LOOP
EXECUTE IMMEDIATE 'UPDATE csh_UserSessionDetail
SET ClientID =vItems.CLIENTID
WHERE ClientID =vItems.CLIENTID
AND OperID =vItems.OPERID
AND Register =vItems.REGISTER
AND Machine_ID =vItems.MACHINE_ID
AND SessionNumber =vItems.SESSIONNUMBER';
END LOOP;
CLOSE usersessiondetail_cur;
END;
答案 0 :(得分:1)
您的SQL无效,因为在执行动态SQL字符串时,游标投影名称不在范围内。您需要使用这样的占位符:
FOR vItems in usersessiondetail_cur
LOOP
EXECUTE IMMEDIATE 'UPDATE csh_UserSessionDetail
SET ClientID = :p1
WHERE ClientID = :p2
AND OperID = :p3
AND Register = :p4
AND Machine_ID = :p5
AND SessionNumber = :p6'
using vItems.CLIENTID
, vItems.CLIENTID
, vItems.OPERID
, Items.REGISTER
, vItems.MACHINE_ID
, vItems.SESSIONNUMBER;
END LOOP;
您的动态代码不是匿名PL / SQL块或CALL语句,因此参数按位置而不是名称传递,因此您需要传递vItems.CLIENTID
两次。 Find out more
其他观察
run
参数... 除此之外,一切都很好。
我假设您将此作为测试来理解如何使用动态SQL而不是作为业务逻辑的实现。但即使它是一个测试,最好编写一段适当的代码来做某事。特别是当您在StackOverflow上与其他人共享代码时。发布包含如此多问题的代码会分散注意力,因为潜在的受访者不知道应该解决哪些问题。
答案 1 :(得分:0)
只有FOR循环的简单方法。在这种情况下,我们不需要打开关闭游标,因为这是由Oracle内部处理的。另外,我不明白是否需要再次更新客户端ID。如果我们在子句中选择客户端ID,则没有更新的重要性。无论如何享受:)
CREATE OR REPLACE
PROCEDURE RESETUSERSESSION(
run IN VARCHAR2)
AS
BEGIN
FOR vItems IN
(SELECT usd.CLIENTID,
usd.OPERID,
usd.REGISTER,
usd.MACHINE_ID,
usd.SESSIONNUMBER
FROM cashiering_dev.CSH_USER usr,
cashiering_dev.CSH_USERSESSIONDETAIL usd
WHERE usr.clientid = usd.clientid
AND usr.operid = usd.operid
AND usr.register = usd.register
AND usr.machine_id = usd.machine_id
AND usr.sessionnumber = usd.sessionnumber
AND usr.machine_id = 'basrytest'
AND usd.LOGOFFDATETIME IS NULL
)
LOOP
UPDATE csh_UserSessionDetail
SET ClientID =vItems.CLIENTID
WHERE ClientID =vItems.CLIENTID
AND OperID =vItems.OPERID
AND Register =vItems.REGISTER
AND Machine_ID =vItems.MACHINE_ID
AND SessionNumber =vItems.SESSIONNUMBER;
END LOOP;
END;
/