【问题标题】:MySql - Inserting into the table in a while loopMySql - 在while循环中插入表
【发布时间】:2021-06-03 15:44:02
【问题描述】:

我有一个takes 表,我想将每个成绩记录转换为数值并将其存储在grade_point 表中。

我将grade_point 初始化为:

CREATE TABLE IF NOT EXISTS university.grade_point (
    id VARCHAR(5),
    grade VARCHAR(2),
    grade_value NUMERIC(2 , 1)
);

我可以通过以下方式解决问题:

  • takes 表中获取id

  • takes 表中获取grade

  • 如果gradeA 那么grade_value 是4.0

    如果 gradeA- 那么 grade_value 是 3.7 ...

我可以编写以下查询:

insert into grade_point(id, grade, grade_value) 
SELECT 
    id,
    grade,
    CASE
        WHEN grade LIKE 'A' THEN 4.0
        WHEN grade LIKE 'A-' THEN 3.7
        WHEN grade LIKE 'B+' THEN 3.3
        WHEN grade LIKE 'B' THEN 3.0
    END AS grade_value
FROM
    takes;

我想知道我是否可以使用 procedure 做到这一点?

灵感来自How can I loop through all rows of a table (MySQL) 的公认解决方案:

  • 对于takes 表中的每个grade 记录

    • 选择ith 行

    • 获取idgrade 并将grade 转换为grade_value

    • 将其插入grade_point

  • 结果是:

delimiter 
create procedure update_grade_point()
begin
declare n int default 0
declare i int default 0
select count(grade) from takes into n    
set i = 0
while i < n do
    insert into grade_point(id, grade, grade_value) 
    select id, grade, 
        case
            when grade like 'A' then 4.0
            when grade like 'A-' then 3.7
            when grade like 'B+' then 3.3
            when grade like 'B' then 3.0
        end as grade_value
    from
        takes
    limit i, 1;
    set i = i + 1
end while
end;
delimiter ;

但是,上面的查询响应为:

0 行受影响,1 个警告:1050 表 'grade_point' 已存在

当删除 grade_point 表并重新执行查询时,我得到以下响应

0 行受影响

没有任何东西被插入到grade_point 表中。

您能告诉我我的procedure 中缺少什么或错误吗?

问候。

【问题讨论】:

  • INSERT tablename (column1, column2, colmn3) VALUES (value1, value2, value3) 是正确的 INSERT 语法。你没有输入任何VALUES
  • 你为什么要用一个缓慢而讨厌的程序解决方案来替换完美、时尚、基于集合和高性能的INSERT ... SELECT ...
  • 再想一想:grade_point 应该建模的表是什么?成绩的数字和字母表示之间的关系?在这种情况下,您不想根据takes 的行来填充它,而只是一次,每个可能 等级(不一定当前存在于takes)中的一行。 (然后更改takes,使grade 是指向grade_point 中记录的外键。)
  • 是的,创建过程不会插入、更新或删除任何行。您需要执行该过程,以便其主体中的任何INSERT(或UPDATEDELETE)语句都有效。 (如果这就是您的问题。要破译您拥有和想要什么以及问题是什么有点困难。至少对我来说......)
  • @stickybit 我试图想象书籍问题先生。这个问题与现实世界的问题无关。我目前正在为一个麻烦的考试工作。感谢您与我分享您的想法。问候

标签: mysql


【解决方案1】:

我不知道,你为什么要这样做,当一个简单的插入就足够了

但是 ij 是一个存储过程,你会使用循环

CREATE TABLE IF NOT EXISTS  grade_point (
    id VARCHAR(5),
    grade VARCHAR(2),
    grade_value NUMERIC(2 , 1)
);
CREATE TABLE IF NOT EXISTS takes (
    id VARCHAR(5),
    grade VARCHAR(2)
);
INSERT INTO takes VALUES ("1","A"),("2","B"),("3","A"),("4","B")
CREATE PROCEDURE update_grade_point (

)
BEGIN
  DECLARE finished INTEGER DEFAULT 0;
  DECLARE _grade varchar(2) DEFAULT "";
  DECLARE _id varchar(5) DEFAULT "";

  -- declare cursor for employee email
  DEClARE curtakes 
      CURSOR FOR 
          SELECT id,grade FROM takes;

  -- declare NOT FOUND handler
  DECLARE CONTINUE HANDLER 
        FOR NOT FOUND SET finished = 1;

  OPEN curtakes;

  getidGrade: LOOP
      FETCH curtakes INTO _id,_grade;
      IF finished = 1 THEN 
          LEAVE getidGrade;
      END IF;
                insert into grade_point(id, grade, grade_value) VALUES (_id,_grade,        case
            when grade like 'A' then 4.0
            when grade like 'A-' then 3.7
            when grade like 'B+' then 3.3
            when grade like 'B' then 3.0
        end);
  END LOOP getidGrade;
  CLOSE curtakes;

END
CALL update_grade_point()
SELECT * FROM grade_point
编号 |等级 |等级值 :- | :---- | ----------: 1 |一个 | 4.0 2 |乙| 3.0 3 |一个 | 4.0 4 |乙| 3.0

db小提琴here

【讨论】:

  • “我不知道,你为什么要这样做,当一个简单的插入就足够了”,我正在学习资格考试。考试社区可以问任何问题。不管怎样,谢谢。虽然我不明白为什么“dbfiddle”会给我的语法带来错误。该查询在 MySql Workbench 上运行良好。
  • dbfiddle,有一些怪癖,必须考虑看到dbfiddle.uk/…,除了下次尝试DELIMITER $$ 并添加分号,它使ebtter rad 和MySQL 同时接受你的风格感到困惑在 dbfiddle
  • 我想知道“..在接受你的风格时会感到困惑..”是什么意思?
  • 你有一个没有实际字符的分隔符,这是通过 dbfiddle 在其配置中关闭的。 dbfiddle.uk 不喜欢 DELIMITER,因为它会自动添加它,正如您在小提琴中看到的那样。就像我说的,了解小提琴网站的规则需要一些时间
  • 好的,谢谢你的信息,下次我会小心的。问候
猜你喜欢
  • 2022-01-07
  • 2015-01-14
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-02-29
  • 2019-08-08
  • 2012-04-23
相关资源
最近更新 更多