(zt)int()字段类型长度 问题

本文详细解释了数据库中INT类型的使用方式及字段长度的意义。探讨了不同INT类型(如int(11))的具体含义,以及这些长度设置如何影响数据的显示而非实际存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://hi.baidu.com/%BC%D6%D3%F0%CE%F5/blog/item/a73c6d014ad951011c95831a.html/cmtid/642c5a510807092a43a75b03

int()字段类型长度 问题

一直以来我定义int数据类型时填写的长度都是为11,只知道int类型的数据可表达的范围:
有符号值:-2147683648 到 2147683647
无符号值:0 到 4294967295
小弟想问下,定义了int数据类型后,后面填写的长度具体有什么用?
如果长度为4,请问最大的数是多少?如果是自增的可以是多少条?
答:最大为11位,最少为4位,不够在前面补空格 
这个可选的宽度规格说明是用于在数值显示时,对某些值的宽度短于该列宽度的值进行左填补显示的,而不是为了限制在该列中存储值的宽度,也 不是为了限制那些超过该列指定宽度的值的可被显示的数字位数。注意,如果在一个整型列中存储一个超过显示宽度的更大值时,当 mysql 为某些复杂的联结(join)生成临时表时,你可能会遇到问题,因为在这种情况下,mysql 信任地认为所有的值均适合原始的列宽度。

而int本身就是4个字节 bigint是8个字节 所以说int(X)的含义就是 int决定数据存储的字节 X表示期望数据的列宽度

在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度。

这个代表显示宽度
整数列的显示宽度与mysql需要用多少个字符来显示该列数值,与该整数需要的存储空间的大小都没有关系,比如,不管设定了显示宽度是多少个字符,bigint都要占用8个字节。

<think>我们之前构建的存储过程使用了REPEAT函数来重复生成多个值,但是REPEAT函数返回的是字符串重复多次的结果,然而在构建INSERT语句时,我们需要的是多个值列表,每个值列表之间用逗号分隔。但是REPEAT函数只是简单地将字符串重复,并没有在重复的字符串之间添加逗号,因此会导致生成的SQL语句中,多个值列表之间没有逗号分隔,从而造成语法错误。 例如,我们想要生成: ('val1',...), ('val1',...), ... 但是使用REPEAT后,会变成: ('val1',...)('val1',...)... 所以我们需要在每次重复之间添加逗号,但是注意最后一个值后面不能有逗号。 因此,我们需要调整策略,不能直接用REPEAT,而是通过循环构建一个长字符串,在每次循环中添加一个值,并在每个值之间添加逗号(除了最后一个)。 但是,在存储过程中,我们可以使用WHILE循环来构建一个包含多个值的字符串,每个值之间用逗号分隔。然而,在存储过程中直接构建一个包含1000个值的字符串可能会超出SQL语句的最大长度(尤其是当每个值字符串很长时)。因此,我们需要权衡。 另一种方法是使用临时表或者内存表,但这里我们继续使用动态SQL,但改进构建多个值的方式。 修改后的思路: 1. 在每一批(batch)中,我们构建一个包含多个记录值的字符串,每个记录值用括号括起来,记录之间用逗号分隔。 2. 我们可以使用一个循环(从1到当前批次要插入的数量)来拼接每个值字符串,并在每个值字符串后添加逗号(除了最后一个)。 3. 但为了避免在循环中拼接长字符串(可能会慢),我们可以使用REPEAT来生成不带逗号的多个值,然后使用字符串替换的方式在中间插入逗号?但是这样并不直观。 更直接的方法:使用一个循环来拼接当前批次的所有值字符串,并在每次循环时添加逗号(除了最后一次)。但是,在存储过程中,使用循环拼接字符串可能会比较慢,特别是当批次大小很大时(比如1000条)。不过,由于我们每批只循环1000次,这个开销是可以接受的。 因此,我们修改存储过程如下: 我们将为每一批构建一个字符串,该字符串由多个值组成,每个值之间用逗号分隔。具体步骤如下: - 初始化一个空字符串`batch_values`。 - 循环从1到当前批次的数量(即`LEAST(remaining, batch_size)`),在每次循环中,我们添加一个值字符串,然后如果不是最后一个,就添加一个逗号。 - 然后把这个`batch_values`字符串拼接到INSERT语句中。 但是,由于我们使用的是动态SQL,并且批次大小可能达到1000,所以我们需要在存储过程中使用一个内层循环。 然而,在存储过程中使用循环拼接字符串可能会遇到性能问题(因为字符串拼接在循环中可能较慢),但考虑到1000次循环,这个开销是可以接受的。 修改后的存储过程(关键部分): ``` DECLARE j INT DEFAULT 1; DECLARE batch_values TEXT DEFAULT ''; SET @batch_count = LEAST(remaining, batch_size); -- 构建当前批次的值列表 WHILE j <= @batch_count DO SET batch_values = CONCAT(batch_values, "('2025-12-10 14:30:00', 'ZT20250710001', '荆州中通云仓', '湖北省', 'TEST-AUX-001', ", "'荆州市', '沙市区', '荆州-中通云仓唯品自营专用顺丰', 20, 3000.000, ", "1.200, NULL, NULL, 5.000, NULL, '淘宝海外新加坡补发1', 'JY20250501011664', ", "'唯品自营旗舰店', 3, 0.000, 25.500, 50.800, '9号', 2, NULL, NULL, NULL, ", "NULL, NULL, 5.200, NULL, NULL, '3<x<=5', NULL, NULL, 30.000, 8.000, 20.800, 1)"); IF j < @batch_count THEN SET batch_values = CONCAT(batch_values, ','); END IF; SET j = j + 1; END WHILE; ``` 然后,将`batch_values`拼接到INSERT语句中。 但是,注意:在存储过程中,如果使用WHILE循环嵌套,我们需要重新声明变量。另外,由于我们已经在外部有一个WHILE循环,所以内层循环需要小心作用域问题(在存储过程中,内部声明的变量只在当前BEGIN...END块中有效)。 然而,我们也可以不使用内层循环,而是通过一个技巧:使用数字辅助表,但这里我们选择内层循环。 由于存储过程不允许在同一个块中重复声明变量,我们需要在内部使用一个新的BEGIN...END块,或者使用不同的变量名。 我们重新设计存储过程,使用两个循环(外层循环控制批次,内层循环控制当前批次内的记录拼接)。 但是,考虑到性能,拼接1000条记录的内层循环不会太慢,所以可以接受。 修改后的完整存储过程如下:</think>您遇到的错误是由于存储过程中动态构建 SQL 语句时值列表之间缺少逗号分隔符导致的。我将提供一个修复后的存储过程,并解释问题原因: ### 问题分析 原存储过程使用 `REPEAT()` 函数生成多个值,但没有在值之间添加必要的逗号分隔符,导致生成的 SQL 语句如: ```sql INSERT ... VALUES ('val1')('val2')('val3') -- 缺少逗号分隔符 ``` 正确格式应为: ```sql INSERT ... VALUES ('val1'), -- 注意这里的逗号 ('val2'), ('val3') ``` ### 修复后的存储过程 ```sql DELIMITER // CREATE PROCEDURE InsertMassData(IN total_rows INT) BEGIN DECLARE i INT DEFAULT 1; DECLARE batch_size INT DEFAULT 1000; DECLARE batch_count INT; DECLARE remaining INT DEFAULT total_rows; DECLARE values_list TEXT; -- 单条记录的固定值模板 SET @single_value = CONCAT( "('2025-12-10 14:30:00', 'ZT20250710001', '荆州中通云仓', '湖北省', 'TEST-AUX-001', ", "'荆州市', '沙市区', '荆州-中通云仓唯品自营专用顺丰', 20, 3000.000, ", "1.200, NULL, NULL, 5.000, NULL, '淘宝海外新加坡补发1', 'JY20250501011664', ", "'唯品自营旗舰店', 3, 0.000, 25.500, 50.800, '9号', 2, NULL, NULL, NULL, ", "NULL, NULL, 5.200, NULL, NULL, '3<x<=5', NULL, NULL, 30.000, 8.000, 20.800, 1)" ); SET autocommit = 0; WHILE remaining > 0 DO START TRANSACTION; -- 计算本次插入的数量 SET @current_batch = LEAST(remaining, batch_size); SET values_list = ''; -- 构建逗号分隔的值列表 SET @counter = 1; WHILE @counter <= @current_batch DO SET values_list = CONCAT(values_list, @single_value); IF @counter < @current_batch THEN SET values_list = CONCAT(values_list, ','); END IF; SET @counter = @counter + 1; END WHILE; -- 构建完整SQL SET @insert_sql = CONCAT( 'INSERT INTO `kerespets_admin`.`la_zhongtong_details` (', 'shipping_time, logistics_no, warehouse, province, auxiliary_column, ', 'city, region, logistics_company, total_goods_count, weight, ', 'theoretical_material_weight, theoretical_weight, material_weight, ', 'billing_weight, goods_weight_diff, goods_summary, sales_channel, ', 'shop_name, additional_pieces, beijing_shanghai_surcharge, express_fee, ', 'total_amount, model, card_quantity, goods_quantity, additional_quantity, ', 'operation_fee, theoretical_material, material_consistent, material_fee, ', 'theoretical_material_fee, billing_weight_calc, weight_range, ', 'theoretical_express_fee, beijing_shanghai_theoretical_surcharge, ', 'theoretical_total_freight, shunfeng_service_fee, difference, status', ') VALUES ', values_list ); -- 执行插入 PREPARE stmt FROM @insert_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 更新计数器 SET remaining = remaining - @current_batch; COMMIT; END WHILE; SET autocommit = 1; END // DELIMITER ; ``` ### 关键修复点: 1. **逗号分隔符处理**: - 使用嵌套循环构建值列表 - 在每条记录后添加逗号(除了最后一条) - 通过 `IF @counter < @current_batch` 判断是否添加逗号 2. **性能优化**: - 预先定义单条记录模板 `@single_value` - 使用内存变量拼接,减少重复计算 - 保持事务分批提交机制 3. **SQL构建改进**: - 明确分隔字段列表和值列表 - 使用 `TEXT` 类型存储长字符串 - 更清晰的变量命名 ### 调用示例: ```sql -- 测试插入10条 CALL InsertMassData(10); -- 插入100万条 CALL InsertMassData(1000000); ``` ### 注意事项: 1. 执行百万级插入前,建议先备份数据 2. 确保 `id` 字段设置为自增主键 3. 根据服务器性能调整 `batch_size`(500-5000之间) 4. 监控服务器内存使用情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值