Вставка данных 1NF в таблицу через L oop in MySQL - PullRequest
1 голос
/ 11 апреля 2020

Как мне go вставить несколько строк в данные в таблицу для поддержания 1NF? Прямо сейчас у меня есть форма html, которая создает группу, в которую вы можете добавлять / приглашать членов группы. Вы можете добавить / пригласить несколько или один: вход членов группы может варьироваться от пользователя к пользователю. Я хочу взять пользовательский ввод и добавить его в таблицу, которая поддерживает 1NF. Я думал о создании хранимой процедуры в MySQL и вызывал ее, как только у меня появился список значений, и заставляю 'i' вставлять вызовы (я - число членов, которых приглашает пользователь).

Мое приложение. маршрут для создания команды: сейчас я вставляю данные в таблицу tb_team, затем я хочу заполнить таблицу team_members пользователями и связанным с ней team_id

@app.route('/create-team/', methods=['GET', 'POST'])
@login_required
def create_team():
    msg = ''

    if request.method == 'POST':

        # Create variables for easy access
        team_name = request.form['team_name']
        invite = request.form['invite']
        team_desc = request.form['content']

    if not team_name:
        msg='Please enter a group name'
        return render_template('create_team.html', msg=msg, team_name=team_name, invite=invite, content=team_desc)

    if not invite:
        msg = 'Please invite users to the team'
        return render_template('create_team.html', msg=msg, team_name=team_name, invite=invite, content=team_desc)

    if not invite and not team_name:
        msg = 'Please fill out the form'
        return render_template('create_team.html', msg=msg)


    cursor = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
    cursor.execute('SELECT user_id from tb_user WHERE user_name = %s', (invite,))
    invite_id = cursor.fetchone()
    invite_id_final = invite_id['user_id']

    # Check if team_name exists in tb_team table
    cursor.execute('SELECT * FROM tb_team WHERE team_name = %s', (team_name,))
    name = cursor.fetchone()

    # If team_name currently exists, show error that it is taken
    if name:
        msg = 'This Project Name is already taken!'
        return render_template('create_team.html', msg=msg, team_name=team_name, invite=invite, content=team_desc)
    else:
        msg = 'You have successfully created a team!'
        cursor.execute("INSERT INTO tb_team (team_name)"
                       " VALUES (%s)", (team_name))
        mysql.connection.commit()
        return redirect(url_for('team_page', group_name=team_name))

return render_template('create_team.html')

Вот дизайн моей базы данных и то, что я хочу чтобы в конечном итоге достичь: Relational design of my database

с фиктивными данными здесь: example populated table data here

Будет ли написание хранимой процедуры правильным способом для вставки этих членов группы?

Передача списка пользователей для добавления в строковую переменную, через некоторое время l oop, захват каждого пользователя, разделенного запятой, и добавление его в таблицу, пока в строке не останется больше пользователей переменная? (См. Код ниже для моей хранимой процедуры)

DELIMITER 
CREATE PROCEDURE basicInsert()
BEGIN
    SET @myArrayOfUsers = '100,102,105,'
WHILE(LOCATE(',', @myArrayOfUsers) > 0) DO
        SET @value = ELT(1, @myArrayOfUsers);
        SET @myArrayOfUsers= SUBSTRING(@myArrayOfUsers, LOCATE(',',@myArrayOfUsers) + 1);
        INSERT INTO `group_member` VALUES(1001, @value);
END WHILE;


END;
 DELIMITER ;


 CALL basicInsert();

СПАСИБО! Вся помощь действительно ценится!

1 Ответ

0 голосов
/ 11 апреля 2020

У вашей процедуры есть несколько серьезных проблем.

ELT не возвращает то, что вы хотели. он на самом деле возвращает полный @ myArrayOfUsers

Отладка L OOP сложно без временных таблиц, но когда вы не уверены, каков результат вашего кода, временно удалите l oop, добавьте еще @ пользовательских переменных и отладить строку для строки

DROP procedure IF EXISTS `basicInsert`;

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `basicInsert`()
BEGIN
    SET @myArrayOfUsers = '100,102,105';
    #SET @myArrayOfUsers = '106,107,108,';
    WHILE(LOCATE(',', @myArrayOfUsers) > 0) DO
            SET @value = SUBSTRING_INDEX(@myArrayOfUsers,',',1);
            IF (LENGTH(@myArrayOfUsers) > LENGTH(@value) +2)  THEN
                SET @myArrayOfUsers= SUBSTRING(@myArrayOfUsers, LENGTH(@value) + 2);
                INSERT INTO `group_member` VALUES(1001, @value);
            ELSE
                INSERT INTO `group_member` VALUES(1001, @value);
                -- to end while loop
                SET @myArrayOfUsers=  '';
            END IF;
            IF LENGTH(@myArrayOfUsers) > 0 AND LOCATE(',', @myArrayOfUsers) = 0 then
                -- Last entry was withóut comma
                INSERT INTO `group_member` VALUES(1001, @myArrayOfUsers);
            END IF;
    END WHILE;
END$$

DELIMITER ;

Я проверяю, как вы можете видеть в случае, когда в конце нет запятой.

Как вы только хотите сделать! NF, я не проверить уже существующие записи

...