【发布时间】:2020-11-04 00:10:09
【问题描述】:
我试图在 CLOB 变量中传递单个 INTEGER 列的值,以便执行 IN 操作(列的输出大小未知),但出现错误,现在卡住了。首先,我试图在 IN 之后使用 SELECT 语句,但我发现它在 PL/SQL 中不起作用。所以,简而言之,我希望能够检查表中的主键,如果它不存在,则用新值更新现有记录,但如果它已经存在,我不应该这样做。
DoGood Donor 应用程序包含一个页面,该页面允许 管理员在 DD_DONOR 中更改分配给捐赠者的 ID 桌子。创建一个 PL/SQL 块来处理这个任务。包括 异常处理代码,以解决通过尝试 输入重复的捐赠者 ID。如果发生此错误,请显示消息 “这个ID已经分配了。”通过更改捐助者 ID 305 来测试代码。
这是我使用的一张桌子。 DD_DONOR
Name Null? Type
--------- -------- ------------
IDDONOR NOT NULL NUMBER(4)
FIRSTNAME VARCHAR2(15)
LASTNAME VARCHAR2(30)
TYPECODE CHAR(1)
STREET VARCHAR2(40)
CITY VARCHAR2(20)
STATE CHAR(2)
ZIP VARCHAR2(9)
PHONE VARCHAR2(10)
FAX VARCHAR2(10)
EMAIL VARCHAR2(25)
NEWS CHAR(1)
DTENTERED DATE
这是我的代码:
DECLARE
all_ids clob;
newID DD_DONOR.IDDONOR%TYPE;
fname DD_DONOR.FIRSTNAME%TYPE;
lname DD_DONOR.LASTNAME%TYPE;
CURSOR id IS
SELECT IDDONOR FROM DD_DONOR;
BEGIN
newID := 305;
fname := 'Thomas';
lname := 'Sheer';
OPEN id;
FETCH id BULK COLLECT INTO all_ids;
IF id%NOTFOUND THEN
UPDATE DD_DONOR
SET IDDONOR = newID
WHERE FIRSTNAME = fname AND LASTNAME = lname;
DBMS_OUTPUT.PUT_LINE(fname || ' ' || lname || ' ' || 'New ID: ' || newID);
ELSIF id%FOUND THEN
DBMS_OUTPUT.PUT_LINE('This ID is already assigned.');
END IF;
CLOSE id;
END;
这是错误:
Error report -
ORA-06550: line 14, column 32:
PLS-00497: cannot mix between single row and multi-row (BULK) in INTO list
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
我一开始创建的这段代码可以编译,但对表没有任何作用,所以我放弃了它:
DECLARE
newID DD_DONOR.IDDONOR%TYPE;
fname DD_DONOR.FIRSTNAME%TYPE;
lname DD_DONOR.LASTNAME%TYPE;
BEGIN
newID := 305;
fname := 'Thomas';
lname := 'Sheer';
UPDATE DD_DONOR
SET IDDONOR = newID
WHERE NOT EXISTS (SELECT IDDONOR
FROM DD_DONOR
WHERE FIRSTNAME = fname AND LASTNAME = lname);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('This ID is already assigned.');
END;
输出:
PL/SQL procedure successfully completed.
另一个不起作用的版本:
DECLARE
newID DD_DONOR.IDDONOR%TYPE;
fname DD_DONOR.FIRSTNAME%TYPE;
lname DD_DONOR.LASTNAME%TYPE;
BEGIN
newID := 305;
fname := 'Thomas';
lname := 'Sheer';
IF (SELECT IDDONOR FROM DD_DONOR
WHERE FIRSTNAME = fname AND LASTNAME = lname) = newID
THEN
DBMS_OUTPUT.PUT_LINE('This ID is already assigned.');
ELSE
UPDATE DD_DONOR
SET IDDONOR = newID
WHERE FIRSTNAME = fname AND LASTNAME = lname;
END IF;
END;
这种方法有效,但同样不会输出 ID 被占用的错误消息:
SET SERVEROUTPUT ON SIZE 100000
DECLARE
newID DD_DONOR.IDDONOR%TYPE;
fname DD_DONOR.FIRSTNAME%TYPE;
lname DD_DONOR.LASTNAME%TYPE;
CURSOR id IS
SELECT IDDONOR FROM DD_DONOR
WHERE FIRSTNAME = fname AND LASTNAME = lname;
BEGIN
newID := 305;
fname := 'Thomas';
lname := 'Sheer';
OPEN id;
IF SQL%NOTFOUND THEN
UPDATE DD_DONOR
SET IDDONOR = newID
WHERE FIRSTNAME = fname AND LASTNAME = lname;
DBMS_OUTPUT.PUT_LINE(fname || ' ' || lname || ' ' || 'New ID: ' || newID);
ELSIF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('This ID is already assigned.');
END IF;
CLOSE id;
END;
这个不行,但我喜欢。看起来应该可以了。
SET SERVEROUTPUT ON SIZE 100000
DECLARE
newID DD_DONOR.IDDONOR%TYPE;
fname DD_DONOR.FIRSTNAME%TYPE;
lname DD_DONOR.LASTNAME%TYPE;
CURSOR id IS
SELECT IDDONOR FROM DD_DONOR
WHERE FIRSTNAME = fname AND LASTNAME = lname;
all_IDs DD_DONOR%rowtype;
BEGIN
newID := 305;
fname := 'Thomas';
lname := 'Sheer';
OPEN id;
LOOP
FETCH id into all_IDs;
UPDATE DD_DONOR
SET IDDONOR = newID
WHERE FIRSTNAME = fname AND LASTNAME = lname;
DBMS_OUTPUT.PUT_LINE(fname || ' ' || lname || ' ' || 'New ID: ' || newID);
EXIT WHEN id%FOUND;
DBMS_OUTPUT.PUT_LINE('This ID is already assigned.');
END LOOP;
CLOSE id;
END;
Error report -
ORA-06550: line 15, column 9:
PLS-00394: wrong number of values in the INTO list of a FETCH statement
ORA-06550: line 15, column 9:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
【问题讨论】:
-
这两段代码都存在不少问题。我正在努力理解您要解决的问题。发布一些示例数据和预期结果通常很有帮助。我假设您是学生,这是某种形式的作业。通常,目标是接受
idDonor、firstName和lastName作为输入,并更新指定idDonor的firstName和lastName列(如果该行已存在)。几乎永远不会更新表的主键。