You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

打印1-1000质数并以&分隔报错:Data too long for column 'p'

问题分析与修复

你遇到的ERROR 1406本质是存储过程中拼接字符串的变量p长度不足,但核心诱因是质数判断逻辑错误,导致大量非质数被重复拼接到p中,让字符串长度迅速超出预设的varchar(2000)限制。

你的代码存在的具体问题:

  • 质数判断时机错误:在内层while n<=x的循环过程中,每次n递增后就判断y=2并执行拼接,但此时y还没统计完x的所有因数。比如x=4时,当n=2,y变为2,这时候错误地把4拼接到p里,但4的实际因数有1、2、4,最终y会是3,并非质数。这种错误会把大量非质数加入字符串,同时可能对同一个数多次拼接,导致p的长度急剧膨胀。
  • 变量p长度预留不足:即使逻辑正确,1000以内的质数有168个,用&分隔后总长度虽不到2000,但逻辑错误产生的冗余内容会轻易突破这个限制,建议改用更大的长度(比如varchar(10000))或text类型。
  • 循环效率低下:内层循环从1开始且遍历到x,做了大量无意义的判断(比如1是所有数的因数,无需单独统计)。

修复后的代码:

delimiter $$
create procedure a()
begin
    declare x int default 3;
    declare n int default 2; -- 从2开始判断,跳过无意义的1
    declare y int default 0;
    declare p varchar(10000) default '2'; -- 增大字符串长度
    
    while x<=1000 do
        set y = 0;
        set n = 2;
        -- 优化:只需循环到sqrt(x),减少判断次数
        while n <= sqrt(x) do
            if x % n = 0 then
                set y = 1; -- 找到因数,标记为非质数
                leave; -- 直接退出内层循环,无需继续判断
            end if;
            set n = n + 1;
        end while;
        
        -- 内层循环结束后确认是质数,再执行拼接
        if y = 0 then
            set p = concat(p, '&', x);
        end if;
        
        set x = x + 1;
    end while;
    
    select p;
end $$
call a();

关键修复说明:

  1. 调整拼接时机:将字符串拼接移到内层循环结束后,只有确认x是质数时才执行拼接,避免错误添加非质数。
  2. 优化循环逻辑:内层循环从2开始,且只遍历到sqrt(x),若x存在大于sqrt(x)的因数,必然对应一个小于sqrt(x)的因数,大幅减少循环次数。
  3. 扩大变量长度:将p的类型改为varchar(10000),确保能容纳所有拼接内容,也可直接用text类型彻底避免长度限制问题。
  4. 移除冗余代码:原代码中的case语句与外层while逻辑重复,直接保留while即可。

内容的提问来源于stack exchange,提问作者Ramya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:15:24