存储过程成功,但在mysql中无法正常运行
我有一个关于两个表的存储过程,如下所示:存储过程成功,但在mysql中无法正常运行,mysql,stored-procedures,sql-insert,Mysql,Stored Procedures,Sql Insert,我有一个关于两个表的存储过程,如下所示: CREATE DEFINER=`brambang`@`%` PROCEDURE `create_discount_campaign`( IN discount_campaign_discount_type_id CHAR(22), IN discount_campaign_product_id INT(10), IN discount_campaign_marketing_target_id
CREATE DEFINER=`brambang`@`%` PROCEDURE `create_discount_campaign`(
IN discount_campaign_discount_type_id CHAR(22),
IN discount_campaign_product_id INT(10),
IN discount_campaign_marketing_target_id INT(10),
IN discount_campaign_max_use_per_user int(11),
IN discount_campaign_discount_code varchar(100),
IN discout_campaign_discount_amount decimal(10,0),
IN discount_campaign_start_date datetime,
IN discount_campaign_end_date datetime,
IN discount_campaign_min_order_quantity INT(11),
IN discount_campaign_min_order_price decimal(10,0),
IN discount_campaign_discount_quota INT(11),
IN discount_campaign_min_product_varian INT(11),
IN discount_campaign_apply_all_product INT(10),
IN discount_campaign_product_product_id int(10) unsigned,
IN discount_campaign_product_active tinyint(1),
IN discount_campaign_product_createdby int(11),
IN discount_campaign_product_updatedby int(11),
IN discount_campaign_product_category_id VARCHAR(100),
IN discount_campaign_advanced_discount_advanced_rules_id int(50),
IN discount_campaign_advanced_value varchar(255),
IN discount_campaign_advanced_status tinyint(4)
)
proc:
BEGIN
DECLARE is_dc_discount_type_id INT(10);
DECLARE is_dc_product_id INT(10);
DECLARE is_dc_marketing_target_id INT(10);
DECLARE is_dc_max_use_per_user INT(11);
DECLARE is_dc_discount_code varchar(100);
DECLARE is_dc_discount_amount decimal(10,0);
DECLARE is_dc_start_date datetime;
DECLARE is_dc_end_date datetime;
DECLARE is_dc_min_order_quantity INT(11);
DECLARE is_dc_min_order_price decimal(10,0);
DECLARE is_dc_discount_quota INT(11);
DECLARE is_dc_min_product_variant INT(11);
DECLARE is_dc_apply_all_product INT(10);
DECLARE is_dcp_product_id INT(10);
DECLARE is_dcp_active tinyint(1);
DECLARE is_dcp_createdby int(11);
DECLARE is_dcp_updatedby int(11);
DECLARE is_dca_discount_advanced_rules_id int(50);
DECLARE is_dca_value varchar(255);
DECLARE is_dca_status tinyint(4);
DECLARE LAST_INSERT_ID int(11);
DECLARE discount_campaign_product_category_id varchar(100);
SET @querie = NULL;
SET @querie2 = NULL;
SET @querie3 = NULL;
SET lc_time_names = "id_ID";
SET @is_dc_discount_type_id = NULL;
SET @is_dc_product_id = NULL;
SET @is_dc_marketing_target_id = NULL;
SET @is_dc_max_use_per_user = NULL;
SET @is_dc_discount_code = NULL;
SET @is_dc_discount_amount = NULL;
SET @is_dc_start_date = NULL;
SET @is_dc_end_date = NULL;
SET @is_dc_min_order_quantity = NULL;
SET @is_dc_min_order_price = NULL;
SET @is_dc_discount_quota = NULL;
SET @is_dc_min_product_variant = NULL;
SET @is_dc_apply_all_product = NULL;
SET @is_dcp_product_id = NULL;
SET @is_dcp_active = NULL;
SET @is_dcp_createdby = NULL;
SET @is_dcp_updatedby = NULL;
SET @is_dca_discount_advanced_rules_id = NULL;
SET @is_dca_value = NULL;
SET @is_dca_status = NULL;
SET @LAST_INSERT_ID = NULL;
SET @discount_campaign_product_category_id = NULL;
SET @is_dc_discount_type_id = discount_campaign_discount_type_id;
SET @is_dc_product_id = discount_campaign_product_id;
SET @is_dc_marketing_target_id = discount_campaign_marketing_target_id;
SET @is_dc_max_use_per_user = discount_campaign_max_use_per_user;
SET @is_dc_discount_code = discount_campaign_discount_code;
SET @is_dc_discount_amount = discout_campaign_discount_amount;
SET @is_dc_start_date = discount_campaign_start_date;
SET @is_dc_end_date = discount_campaign_end_date;
SET @is_dc_min_order_quantity = discount_campaign_min_order_quantity;
SET @is_dc_min_order_price = discount_campaign_min_order_price;
SET @is_dc_discount_quota = discount_campaign_discount_quota;
SET @is_dc_min_product_variant = discount_campaign_min_product_varian;
SET @is_dc_apply_all_product = discount_campaign_apply_all_product;
SET @discount_campaign_product_category_id = discount_campaign_product_category_id;
SET @querie = CONCAT("
INSERT INTO discount_campaigns (
discount_type_id,
product_id,
marketing_target_id,
max_use_per_user,
discount_code,
discount_amount,
start_date,
end_date,
min_order_quantity,
min_order_price,
discount_quota,
min_product_variant,
apply_all_products,
createdAt,
updatedAt
) VALUES (
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
?,
NOW(),
NOW()
);
");
PREPARE stmt FROM @querie;
EXECUTE stmt
USING
@is_dc_discount_type_id,
@is_dc_product_id,
@is_dc_marketing_target_id,
@is_dc_max_use_per_user,
@is_dc_discount_code,
@is_dc_discount_amount,
@is_dc_start_date,
@is_dc_end_date,
@is_dc_min_order_quantity,
@is_dc_min_order_price,
@is_dc_discount_quota,
@is_dc_min_product_variant,
@is_dc_apply_all_product;
DEALLOCATE PREPARE stmt;
SET @is_dcp_product_id = discount_campaign_product_product_id;
SET @is_dcp_active = discount_campaign_product_active;
SET @is_dcp_createdby = discount_campaign_product_createdby;
SET @is_dcp_updatedby = discount_campaign_product_updatedby;
SET @LAST_INSERT_ID = LAST_INSERT_ID();
IF (discount_campaign_apply_all_product = 0) THEN
SET @querie2 = CONCAT("INSERT INTO discount_campaign_product (discount_campaign_id,
product_id,
active,
createdby,
updatedby,
createdAt,
updatedAt
) SELECT ?,product_id,?,?,NULL,NOW(),NULL
FROM product_categories WHERE category_id IN
(?) AND status=1");
PREPARE stmt_2 FROM @querie2;
EXECUTE stmt_2
USING
@LAST_INSERT_ID,
@is_dcp_active,
@is_dcp_createdby,
@discount_campaign_product_category_id;
DEALLOCATE PREPARE stmt_2;
END IF;
END
基本上我有两个表,折扣活动,别名为dc的任何变量都是这个表,折扣活动,别名为dcp的任何变量都是这个表。此存储过程具有将数据插入到带有已生成参数的表中的功能。在折扣活动表中有一列,即应用所有产品。如果参数中填写了0的apply_all_product,则别名为dcp的另一个参数将在折扣_campaign_product表中插入一些数据。但当我应用apply_all_product=0时,此存储过程仅在折扣活动表中插入数据,而不是在折扣活动产品表中插入数据
此存储过程中的错误在哪里?我猜您没有看到任何行插入到折扣活动产品中,因为产品类别中没有匹配的行。您使用了INSERT…SELECT FROM product_categories,但您搜索的是类别id所在的行 我想您的意思是在1,2,3,4,5中将其转换为category_id,但这不是SQL中查询参数的工作方式。一个参数只能用于一个标量值。因此,在您的代码中,它将像在“1,2,3,4,5”中搜索单个字符串的category_id一样进行搜索。当它将字符串强制转换为数字时,它可能会匹配字符串中的第一个数字,但是如果没有与第一个数字匹配的类别,那么它将找不到匹配项 解决方法是在设置类别id“1,2,3,4,5”中使用FIND_。这实际上不是函数应该如何使用的,但它可以在逗号分隔的整数列表中查找整数。注意不要在列表元素之间加空格,因为它不适用于FIND_in_SET 其他问题: 你声明了局部变量,然后就不用了。请理解,在MySQL中,变量myvar和@myvar是两个不同的变量。您需要将不带@sigil的类型声明为局部变量。而带有@sigil的类型是用户定义的会话变量,您不需要声明它——只需设置它的值,就可以隐式创建该变量 您正在使用PREPARE/EXECUTE,但在这种情况下不需要使用动态SQL。您唯一的动态部分是值,因此您可以将输入参数用作过程的查询参数。它们保证像单个标量一样工作,并且不会导致SQL注入。只有在查询中有动态表达式或动态标识符时,才需要使用PREPARE/EXECUTE,但实际上没有 在查询中直接使用过程参数的唯一风险是,应确保参数名称与查询中表的任何列名不同 小数10,0没有多大意义。为什么使用小数位数为0的刻度?这只是一个整数 INT11和INT50没有区别。INT类型的参数不会更改其大小或值的范围。事实上,在MySQL 8.0中不赞成将此参数用于INT类型,因此您应该养成删除它的习惯 这是我测试过的程序,它是有效的:
CREATE PROCEDURE create_discount_campaign(
IN discount_campaign_discount_type_id CHAR(22),
IN discount_campaign_product_id INT,
IN discount_campaign_marketing_target_id INT,
IN discount_campaign_max_use_per_user INT,
IN discount_campaign_discount_code varchar(100),
IN discout_campaign_discount_amount decimal(10,0),
IN discount_campaign_start_date datetime,
IN discount_campaign_end_date datetime,
IN discount_campaign_min_order_quantity INT,
IN discount_campaign_min_order_price decimal(10,0),
IN discount_campaign_discount_quota INT,
IN discount_campaign_min_product_varian INT,
IN discount_campaign_apply_all_product INT,
IN discount_campaign_product_product_id INT UNSIGNED, -- this is unused?
IN discount_campaign_product_active TINYINT,
IN discount_campaign_product_createdby INT,
IN discount_campaign_product_updatedby INT,
IN discount_campaign_product_category_id VARCHAR(100),
IN discount_campaign_advanced_discount_advanced_rules_id INT,
IN discount_campaign_advanced_value varchar(255),
IN discount_campaign_advanced_status TINYINT
)
MODIFIES SQL DATA
BEGIN
DECLARE last_id BIGINT;
INSERT INTO discount_campaigns
SET
discount_type_id = discount_campaign_discount_type_id,
product_id = discount_campaign_product_id,
marketing_target_id = discount_campaign_marketing_target_id,
max_use_per_user = discount_campaign_max_use_per_user,
discount_code = discount_campaign_discount_code,
discount_amount = discout_campaign_discount_amount,
start_date = discount_campaign_start_date,
end_date = discount_campaign_end_date,
min_order_quantity = discount_campaign_min_order_quantity,
min_order_price = discount_campaign_min_order_price,
discount_quota = discount_campaign_discount_quota,
min_product_variant = discount_campaign_min_product_varian,
apply_all_products = discount_campaign_apply_all_product,
createdAt = NOW(),
updatedAt = NOW();
IF (discount_campaign_apply_all_product = 0) THEN
SET last_id = LAST_INSERT_ID();
INSERT INTO discount_campaign_product (discount_campaign_id,
product_id, active, createdby, updatedby, createdAt, updatedAt)
SELECT last_id, c.product_id, discount_campaign_product_active,
discount_campaign_product_createdby, NULL, NOW(), NULL
FROM product_categories AS c
WHERE FIND_IN_SET(c.category_id, discount_campaign_product_category_id)
AND c.status=1;
END IF;
END
注意,我在第一次插入时使用了不同的语法。这是对标准SQL的MySQL扩展,仅适用于单行插入。但是它非常方便,因为它使它更容易。在带有列列表和VALUES子句的标准INSERT语法中,我发现很难确保已将列与正确的值匹配。插入。。。SET语法更具可读性。请添加表定义和call语句。谢谢您,先生,我在不到一年的时间里才有MySQL方面的经验,我很荣幸从您那里得到了高质量的答案,将不胜感激。让我一个接一个的学习,谢谢你的评论,因为这对我来说是新的,非常感谢