【问题标题】:Count how many car/cars owner owns计算有多少汽车/车主拥有
【发布时间】:2020-11-09 00:36:24
【问题描述】:

我正在尝试学习 plsql,但在理解一些基本知识时遇到了困难。这是我试图解决的一个挑战。我有两张桌子。一个保存有关车主的信息,另一个保存有关汽车的信息。

我想编写一个匿名块来连接这两个表,并使用基于每个所有者注册的汽车数量的 for 循环打印每个人拥有的汽车数量。此外,我想要一个区分 1 Car(单数)和 2, 3 Cars(复数)的 if 语句。

表格如下:

CREATE TABLE owners(
    id_nr VARCHAR2(13) PRIMARY KEY,
    f_name VARCHAR2(20),
    s_name VARCHAR2(20)
);
    
CREATE TABLE cars(
    reg_nr VARCHAR2(6) PRIMARY KEY,
    id_nr REFERENCES owners(pnr),
    model VARCHAR2(20),
    year NUMBER(4),
    date DATE
);

结果可能如下所示:

19380321-7799, Hans, Anderson, Owns: 1 car
19490321-7899, Mike, Erikson, Owns: 2 cars

。 . .等等

我知道这个问题已经得到解答,但是当我尝试以下操作时:

declare
    v_suffix varchar2(1);
begin
    for o in (select bilägare_pnr, fnamn, enamn,
                (select count(1) from fordon where fordon_pnr = bilägare_pnr) as bilar_ägda
                from bilägare)
    loop
        if o.pnr_fordon = 1 
            then v_suffix = 'bil'
            else v_suffix = 'bilar'
        end if;
        dbms_output.put_line(o.pnr || ', ' || o.fnamn || ', ' || o.enamn
            || ' Äger: ' || o.pnr_fordon || ' bil' || v_suffix);
    end loop;
end;
/

我明白了:

ORA-06550: line 9, column 27:
PLS-00103: Encountered the symbol "=" when expecting one of the following:

   := . ( @ % ; 

有什么建议吗?我不确定如何声明 v_suffix

编辑(从以下答案的评论中复制):

更新我的代码:

declare
  cursor c_BILÄGARE is
    select fnamn,enamn,pnr
      from BILÄGARE;
begin
  for rec in c_BILÄGARE loop
    if (rec.antal>1) then
     dbms_output.put_line (rec.pnr||','|| rec.fnamn || ',' ||
                           rec.enamn || ',' || rec.antal || 'bilar');
    else
      dbms_output.put_line (rec.pnr||','|| rec.fnamn || ',' ||
                            rec.enamn || ',' || rec.antal || 'bil');
    end if;
  end loop;
end;

得到:

ORA-06550: line 9, column 9: PLS-00302: component 'ANTAL' must be declared (antal=Quantity)

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    如上所述,您需要使用:= 作为赋值运算符。您还需要在每个语句之后使用分号 - 因此,您应该使用

    then v_suffix := 'bil';
    

    而不是

    then v_suffix := 'bil'
    

    所以你的代码应该是这样的:

    declare
        v_suffix varchar2(1);
    begin
        for o in (select bilägare_pnr, fnamn, enamn,
                    (select count(1)
                       from fordon
                       where fordon_pnr = bilägare_pnr) as bilar_ägda
                    from bilägare)
        loop
            if o.pnr_fordon = 1 
                then v_suffix := 'bil';
                else v_suffix := 'bilar';
            end if;
    
            dbms_output.put_line(o.pnr || ', ' || o.fnamn || ', ' || o.enamn
                || ' Äger: ' || o.pnr_fordon || ' bil' || v_suffix);
        end loop;
    end;
    

    【讨论】:

    • 更新我的代码:声明游标 c_BILÄGARE 是 select fnamn,enamn,pnr from BILÄGARE; begin for rec in c_BILÄGARE 循环 if (rec.antal>1) then dbms_output.put_line (rec.pnr||','|| rec.fnamn||','||rec.enamn||','||rec .antal||'bilar');否则 dbms_output.put_line (rec.pnr||','|| rec.fnamn||','||rec.enamn||','||rec.antal||'bil');万一;结束循环;结尾;获取:ORA-06550:第 9 行,第 9 列:PLS-00302:必须声明组件“ANTAL”(antal=Quantity)
    • 请不要使用 cmets 来更新您的问题 - 而是使用 edit 按钮来编辑您的问题(就像我在本例中所做的那样),然后发表评论说明您'已经更新了你的问题。谢谢。现在-关于您现在遇到的错误-您似乎没有在光标c_BILÄGARE 中选择ANTAL。将antal 添加到光标,你应该没问题。此外 - 如果您更新问题以显示表格的真实布局而不是英文翻译,这将很有帮助。我们不在乎代码或表格是否是瑞典语 - 对我们来说这只是字符串。 :-)
    【解决方案2】:

    请试试这段代码:

    begin
    
    for rec in (select
        o.id_nr ||  ',' || o.f_name || ',' || o.s_name || ', Owns: ' || coalesce(car.cnt, 0) || ' ' || decode(car.cnt , 1, 'Car', 'Cars') as res
        from owners o
        left outer join (select id_nr, count(1) as cnt from cars group by id_nr) car on (car.id_nr = o.id_nr)) loop
       dbms_output.put_line(rec.res);
    end loop;
    end;
    

    谢谢。

    【讨论】:

      【解决方案3】:

      您的代码中有多个问题在以下代码中突出显示并修复:

      declare
          v_suffix varchar2(5); -- data length should be 5 or more
      begin
          for o in (select bilägare_pnr, fnamn, enamn,
                      (select count(1) from fordon where fordon_pnr = bilägare_pnr) as bilar_ägda
                      from bilägare)
          loop
              if o.bilar_ägda <= 1 -- replaced it from pnr_fordon and <= is used for 0 or 1 car
                  then v_suffix := 'bil'; -- := and ; is used here and in next statement
                  else v_suffix := 'bilar';
              end if;
              dbms_output.put_line(o.pnr || ', ' || o.fnamn || ', ' || o.enamn
                  || ' Äger: ' || o.pnr_fordon || ' bil' || v_suffix);
          end loop;
      end;
      /
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 2011-04-30
        相关资源
        最近更新 更多