我现在已经编码了大约一年了,目前我正在做一个作品集(一个食谱网站),但我陷入了困境,不确定该如何继续。
我的问题是,我需要找到一种方法,将表A中的自动递增的ingredient id(无论是否插入)插入到表B中。
当提交一个食谱时,我已经设置了代码,它会使用以下MySQL查询来检查我的ingredients表中是否有提交的ingredient。
SELECT
i.ingredient
CASE
WHEN
LOWER(?) = LOWER(ingredient)
THEN INSERT IGNORE INTO
i (ingredient) VALUES ?
ELSE
LOWER(?) != LOWER(ingredient)
THEN INSERT INTO
i VALUES ?
END
FROM
ingredients i
我最初尝试使用一个插入后触发器,但意识到如果ingredient已经存在于数据库中并且不是新插入的,这种方法将不起作用。因此,我认为我的方法可能需要重构。
我的目标是,当提交食谱时,将ingredient编译成一个数组,使用以下代码:
let ingredients = req.body.ingredients;
let ingredientArray = Array();
ingredients.forEach(ingredient => {
ingredientArray.push([ingredient.ingredient]);
});
然后运行MySQL查询,如果ingredient尚未存在,则将其插入到表A中,如果已经存在,则忽略。在这两个选项之后,ingredient的自动递增id将插入到表B中。为了使问题更复杂,recipe_id将从表C中提取(包含其他各种食谱信息),amount将是用户在输入字段中键入的值(转换为数组),unit_id将是用户选择的与数据库中预定义的一组预定义的测量单位相对应的单位(也转换为数组)。这两个数组将使用上面的JavaScript代码使它们成为数组。
表A如下:
| id | 成分 |
|---|---|
| 1 | 糖 |
| 2 | 面粉 |
表B如下:
| id | recipe_id | 金额 | unit_id | ingredient_id |
|---|---|---|---|---|
| 1 | 45 | 1 | 5 | 1 |
| 2 | 76 | 4 | 4 | 2 |
更新的方法
希望这是一个更好的方法,但是,我在弄清楚如何使我的if语句的false结果执行@checkIngredientFalse,然后执行@checkIngredientTrue方面遇到了困难,因为这将会将ingredient的id添加到recipe_ingredients的ingredient_id表列中。
食谱.js
async function createRecipeIngredient(newRecipeId, ingredientName, unitId, amount) {
let ingredients = req.body.ingredients;
let ingredientArray = Array();
ingredients.forEach(ingredient => {
ingredientArray.push([ingredient.ingredient]);
});
const ingredientQuery = `
SET @checkIngredient =
(SELECT
i.id
FROM
ingredients i
WHERE
i.ingredient = LOWER(?)
);
SET @newRecipeId =
(SELECT
max(r.id)
FROM
recipes r
);
SET @checkIngredientTrue =
(INSERT INTO
recipeIngredients (recipe_id, ingredient_id)
VALUES
(@newRecipeId, @checkIngredient)
);
SET @checkIngredientFalse =
(INSERT INTO
ingredients (ingredient)
VALUES
(LOWER(?))
//MISSING CODE HERE//
);
IF(@checkIngredient, @checkIngredientTrue, @checkIngredientFalse);`
const [_queryRows, _queryFields] = await db.promise().query(ingredientQuery, [newRecipeId, _ingredientName, _unitId, _amount]);
module.exports = { getRecipe, getRecipeComments, getRecipePhotos, getUserRecipeCommentLikes, createRecipe, insertRecipePhoto, createRecipeIngredient };
routerRecipes.js
router.post('/recipes/new', cloudinary.upload.single('photo'), async (req, res, _next) => {
await recipeQueries.createRecipe();
await recipeQueries.insertRecipePhoto(newRecipeId, req.user, req.file.path);
await recipeQueries.createRecipeIngredient(newRecipeId);
res.redirect('/recipes');
}); Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
对于食谱中的每个成分:
SELECT id FROM ingredients WHERE ingredient = ?ingredient_id设置为返回的idINSERT INTO ingredients (ingredient) VALUES (?),并将ingredient_id设置为分配的自增IDingredient_id值进行INSERT INTO recipesingredients.forEach(async (ingredient) => { let ingredient_id; const [ing_ids] = await db.promise().query("SELECT id FROM ingredients WHERE ingredient = ?", [ingredient.toLowerCase()]); if (ing_ids.length > 0) { ingredient_id = ing_ids[0][0]; } else { const res = await db.promise().query("INSERT INTO ingredients (ingredient) VALUES (?)", [ingredient]); ingredient_id = res.insertId; } await db.promise().query("INSERT INTO recipeIngredients (recipe_id, ingredient_id) VALUES (?, ?)", [recipe_id, ingredient_id]); });