Reputation: 446
I am using prepared statements for my SQL insert query, and I am receiving the message that there is an error in the syntax.
I have tried using PHPMyAdmin and used the same query in that and substituted the placeholders for the real values and that query worked fine, therefore I am assuming it is something to do with my use of prepared statements.
def create_user(f_name, s_name, email, sex, dob, mobile=None):
try:
conn = mysql.connector.connect(host=host, user=user, passwd=password) # create a connection to the database
cursor = conn.cursor(prepared=True) # Creates a cursor that is expecting prepared
if mobile is not None: # if the mobile number is specified
sql_parameterized_query = ("""BEGIN;
INSERT INTO users (FirstName, Surname, Email, Dob, Gender, Mobile)
VALUES (%s, %s, %s, %s, %s, %s);
INSERT INTO passwords (UserID, hashedPass)
VALUES (LAST_INSERT_ID(),%s);
COMMIT;""")
query_array = (f_name, s_name, email, date_sql_format(dob), sex, mobile, hash_user_password)
else: # if the mobile number is not specified
sql_parameterized_query = ("""BEGIN;
INSERT INTO users (FirstName, Surname, Email, Dob, Gender)
VALUES(%s, %s, %s, %s, %s);
INSERT INTO passwords (UserID, hashedPass)
VALUES(LAST_INSERT_ID(),%s);
COMMIT;""")
query_array = (f_name, s_name, email, date_sql_format(dob), sex, hash_user_password) # Init array of values
cursor.execute(sql_parameterized_query, query_array) # Execute query
conn.commit()
I would like it to insert the details for a new user into the database all fields are required excluding the mobile phone number, that is why I have used the if statement to separate them, if this is poor practice then please guide me in the correct direction for that too as I could not find a more elegant way of solving that issue, anyway, when calling the function like so create_user("Ollie", "Pugh", "[email protected]", "M", "22-04-2001")
The variable query_array has the value of ('Ollie', 'Pugh', '[email protected]', '2001-04-22', 'M', '$2b$12$RU9FRcNjgHlC78kjZA5OIeqT1s1K2LHndC2iDK8mcqkadGc8d9XO2')
The message I receive is: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INSERT INTO users (FirstName, Surname, Email, Dob, Gender)' at line 2
The structure of the table Users is:
CREATE TABLE `users` (
`UserID` int(11) NOT NULL AUTO_INCREMENT,
`FirstName` varchar(255) NOT NULL,
`Surname` varchar(255) NOT NULL,
`Email` varchar(255) NOT NULL,
`Dob` date NOT NULL,
`Gender` char(1) NOT NULL,
`Mobile` varchar(11) DEFAULT NULL,
`timeOfCreation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`Authority` varchar(255) NOT NULL DEFAULT 'User',
PRIMARY KEY (`UserID`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1
Upvotes: 1
Views: 120
Reputation: 446
The solution to my problem was to create a procedure, I named it CreateUser
and consisted of:
BEGIN
START TRANSACTION;
IF mobile = "NULL" THEN
SET mobile = null;
END IF;
INSERT INTO `cl43-flexfit`.users (FirstName, Surname, Email, Dob, Gender,Mobile)
VALUES (f_name, s_name, email, dob, gender, mobile);
INSERT INTO `cl43-flexfit`.passwords (UserID, hashedPass)
VALUES (LAST_INSERT_ID(), passhash);
COMMIT;
END
And I have modified the python script to have two cursors as I could not use a USE statement within the procedure nor could I use one with a cursor that was configured for prepared statements.
try:
conn = mysql.connector.connect(host=host, user=user, passwd=password) # create a connection to the database
cursor = conn.cursor() # Have to have two as you can not select database with a prepared cursor
prep_cursor = conn.cursor(prepared=True) # Creates a cursor that is expecting prepared
if mobile is None: # if the mobile number is not specified
mobile = "NULL" # This is recognised as null in the procedure
sql_parameterized_query = "CALL CreateUser(%s, %s, %s, %s, %s, %s, %s)" # Calls the create user procedure
query_array = (f_name, s_name, email, date_sql_format(dob), sex, mobile, hash_user_password)
cursor.execute("USE `cl43-flexfit`;")
prep_cursor.execute(sql_parameterized_query, query_array) # Execute query
conn.commit()
I'm sure there are still better ways of doing this, but this does the job for now.
Upvotes: 1