【问题标题】:SELECT INTO and multiple variables for UPDATESELECT INTO 和多个变量用于 UPDATE
【发布时间】:2012-11-30 08:19:05
【问题描述】:

我是 Oracle 和 PL/SQL 的新手;我在选择几个变量时遇到了一些问题。我要做的是在一个表(SA_SPECIFICATION_DETAILS)中搜索多个项目,并将它们连接到另一个表(SA_ASSET)中的一个字段中。 SA_SPECIFICATION_DETAILS 表为每个 SA_ASSET.ASSET_ID 保存多行属性。我已经为此工作了几天,并且不断遇到一些错误。这是我的示例代码:

DECLARE 
manuf VARCHAR(50);
mods VARCHAR(50);
mvs VARCHAR(50);
yeara VARCHAR(4);
assid VARCHAR(50):= &assid;

BEGIN
SELECT TRIM(ATTRIBUTE_VALUE) INTO manuf      
    FROM
      SA_SPECIFICATION_DETAILS d,
      SA_ASSET a
    WHERE
      d.SPECIFICATION_NO = a.SPECIFICATION_NO
    AND d.ATTRIBUTE_DESC = 'MANUFACTURER'
    AND ASSET_ID = assid;

SELECT TRIM(ATTRIBUTE_VALUE) INTO mods
    FROM
      SA_SPECIFICATION_DETAILS d,
      SA_ASSET a
    WHERE
      d.SPECIFICATION_NO = a.SPECIFICATION_NO
    AND d.ATTRIBUTE_DESC = 'MODEL'
    AND ASSET_ID = assid;

SELECT TRIM(ATTRIBUTE_VALUE) INTO mvs
    FROM
      SA_SPECIFICATION_DETAILS d,
      SA_ASSET a
   WHERE
      d.SPECIFICATION_NO = a.SPECIFICATION_NO
    AND d.ATTRIBUTE_DESC = 'MAIN VALVE SIZE'
    AND ASSET_ID = assid;

SELECT TRIM(ATTRIBUTE_VALUE) INTO yeara
    FROM
      SA_SPECIFICATION_DETAILS d,
      SA_ASSET a
    WHERE
      d.SPECIFICATION_NO = a.SPECIFICATION_NO
    AND d.ATTRIBUTE_DESC = 'YEAR MANUFACTURED'
    AND ASSET_ID = assid;

dbms_output.ENABLE(buffer_size => NULL);
DBMS_OUTPUT.PUT_LINE ('Variables:');
dbms_output.put_line (manuf);
dbms_output.put_line (mods);
dbms_output.put_line (mvs);
dbms_output.put_line (yeara);
dbms_output.put_line (assid);
END;

BEGIN
UPDATE
  SA_ASSET
SET
  ASSET_DESC = TRIM(ATTRIBUTE1)
  || ' - Service Type: PW, Manf: '
  || manuf
  || ', Model: '
  || mods
  || ', Main Valve Size: '
  || mvs
  || ', Year Manf: '
  || yearm
  || ', Location: '
  || TRIM(SA_ASSET.STREET_NUMBER_CHAR)
  || ' '
  || TRIM(SA_ASSET.STREET_NAME)
WHERE
  ASSET_TYPE     = 'HYDRANT'
AND ASSET_STATUS = 'ACTIVE'
AND UPPER(ASSET_DESC) NOT LIKE '%LOCATION:%'
AND UPPER(ASSET_DESC) NOT LIKE '%HYDRANT%'
AND SA_ASSET.ASSET_ID = assid
END;

我已经对此进行了测试,但它失败了: 错误报告: ORA-06550:第 73 行,第 1 列: PLS-00103:遇到符号“BEGIN” ORA-06550:第 96 行,第 1 列: PLS-00103:在预期以下情况之一时遇到符号“END”:

所以我注释掉了更新部分并尝试了这个:

    declare 
    manuf sa_specification_details.attribute_value%type;
    mods sa_specification_details.attribute_value%type;
    mvs sa_specification_details.attribute_value%type;
    yeara sa_specification_details.attribute_value%type;
    assid varchar2(15):= &assid;

    --dbms_output.ENABLE(buffer_size => NULL);

    BEGIN
    SELECT ATTRIBUTE_VALUE INTO manuf      
        FROM
          SA_SPECIFICATION_DETAILS d,
          SA_ASSET a
        WHERE
          d.SPECIFICATION_NO = a.SPECIFICATION_NO
        AND d.ATTRIBUTE_DESC = 'MANUFACTURER'
        AND ASSET_ID = assid;
    dbms_output.put_line (manuf);

   SELECT ATTRIBUTE_VALUE INTO mods
        FROM
          SA_SPECIFICATION_DETAILS d,
          SA_ASSET a
        WHERE
          d.SPECIFICATION_NO = a.SPECIFICATION_NO
        AND d.ATTRIBUTE_DESC = 'MODEL'
        AND ASSET_ID = assid;
    dbms_output.put_line (mods);

    SELECT ATTRIBUTE_VALUE INTO mvs
        FROM
          SA_SPECIFICATION_DETAILS d,
          SA_ASSET a
       WHERE
          d.SPECIFICATION_NO = a.SPECIFICATION_NO
        AND d.ATTRIBUTE_DESC = 'MAIN VALVE SIZE'
        AND ASSET_ID = assid;
    dbms_output.put_line (mvs);

    SELECT ATTRIBUTE_VALUE INTO yeara
        FROM
          SA_SPECIFICATION_DETAILS d,
          SA_ASSET a
        WHERE
          d.SPECIFICATION_NO = a.SPECIFICATION_NO
        AND d.ATTRIBUTE_DESC = 'YEAR MANUFACTURED'
        AND ASSET_ID = assid;
    dbms_output.put_line (yeara);  

    SYS.dbms_output.ENABLE;
    DBMS_OUTPUT.PUT_LINE ('Variables:');
    dbms_output.put_line (manuf);
    dbms_output.put_line (mods);
    dbms_output.put_line (mvs);
    dbms_output.put_line (yeara);
    dbms_output.put_line (assid); 
    END;

这让我得到了错误: 错误报告: ORA-01403: 未找到数据 ORA-06512: 在第 11 行 01403. 00000 - “未找到数据” *原因:
*行动:

所以我在没有选择的情况下运行查询:

SELECT
  ATTRIBUTE_VALUE
FROM
  SA_SPECIFICATION_DETAILS d,
  SA_ASSET a
WHERE
  d.SPECIFICATION_NO = a.SPECIFICATION_NO
AND d.attribute_desc = 'MANUFACTURER'
AND asset_id = '001722';

它返回单行/单列(又名它有效)。那么我做错了什么?我已经声明了变量,我已经让选择正确运行,但它没有传递变量(我可以告诉 - 没有 dbms_output.put_line (manuf); 工作)。我是接近了还是完全走错了路?

【问题讨论】:

  • :可能是您的一个查询没有返回数据,这就是为什么它给您No_DATA_FOUND 异常。请先进行异常处理。然后检查所有通过您的asset_id 的查询
  • 也检查MODEL,MAIN VALVE SIZE,YEAR MANUFACTURED

标签: oracle plsql oracle-sqldeveloper


【解决方案1】:

在您的代码中,您需要在此处添加单引号:

assid VARCHAR2(50):= '&assid';

这里也删除结束/开始:

dbms_output.put_line (assid);
END;

BEGIN

因为您希望将其作为一个块(因为您正在使用更新中第一个选择中的变量)。

最后我认为你的意思是一年而不是一年

  || ', Year Manf: '
  || yearm <-- yeara?

您也可以进行优化,将 4 个选择替换为一个:

select max(case d.attribute_desc
             when 'MANUFACTURER' then trim(attribute_value)
           end) manuf,
       max(case d.attribute_desc
             when 'MODEL' then trim(attribute_value)
           end) mods,
       max(case d.attribute_desc
             when 'MAIN VALVE SIZE' then trim(attribute_value)
           end) mvs,
       max(case d.attribute_desc
             when 'YEAR MANUFACTURED' then trim(attribute_value)
           end) yeara
  into manuf, mods, mvs, yeara
  from sa_specification_details d,
       sa_asset a
 where d.specification_no = a.specification_no
   and d.attribute_desc in ( 'MANUFACTURER', 'MODEL', 'MAIN VALVE SIZE',
                             'YEAR MANUFACTURED' )
   and asset_id = assid; 

【讨论】:

  • @robartle p.s.不要使用VARCHAR,使用VARCHAR2
  • 太棒了!完美运行!是的,“yearm”是一个错字,但我认为 &assid 周围的引号是拼图中缺失的部分。 BEGIN, END 可能是我测试的产物——我已经做过很多次了,我都忘记了。感谢您的帮助!
  • 是的,我在一次迭代中更改了它 - 忘记将其更改回来。谢谢
猜你喜欢
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2011-01-29
相关资源
最近更新 更多