php database table creation fails - php

I use the following gist to make an OOP attempt to create a database connection:
https://gist.github.com/jonashansen229/4534794
It seems to work so far.
But the creation of the database table passed_exams fails.
Edit:
After recent comments and suggestions i updated my code:
require_once 'Database.php'; // the gist 4534794
class DatabaseSchema {
public function createStudents() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
$create_students = 'CREATE TABLE IF NOT EXISTS students (
id INT(6) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(40) NOT NULL,
lastname VARCHAR(40) NOT NULL,
university VARCHAR(50)
)';
$result = $mysqli->query($create_students);
}
public function createPassedExams() {
$db = Database::getInstance();
$mysqli = $db->getConnection();
$create_passed_exams = 'CREATE TABLE IF NOT EXISTS passed_exams (
id INT(6) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40) NOT NULL,
student_id INT(6),
FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE
)';
$result = $mysqli->query($create_passed_exams);
}
}
$db_student = new DatabaseSchema();
$db_student->createStudents();
$db_student->createPassedExams();
When i look in the mysql console, only table students is created.
Why is table passed_exams missing?

You create the string to check $query_students = 'SELECT ID FROM STUDENTS';
but you never actually run this. Then u check the string if it is Empty, it will never be empty in your code.
What you should do is use the CREATE ... IF NOT EXISTS syntax of mysql, and not what you do here.
First example show the syntax https://dev.mysql.com/doc/refman/5.5/en/create-table.html

The id column on your students table is INT(6) UNSIGNED but the student_id column on the passed_exams table is a signed INT(6). Therefore the FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE clause will fail with "Error Code: 1215. Cannot add foreign key constraint".
I advise you to implement some error handling so that you would see this error message rather than blindly continue executing code.

Related

Create TABLE using PHP, according to input [duplicate]

This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 3 years ago.
I am about to create a table, but I want to declare it based on the user's input. thankyou for any response, all answers are appreciated, more power!
I am receiving this error (Error creating table: 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 ''2020-2021' ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR' at line 1)
here's the sample code I am doing.
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "mias";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$table = $_POST['usersinput'];
// sql to create table
$sql = "CREATE TABLE $table (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)";
if ($conn->query($sql) === TRUE) {
echo "Table MyGuests created successfully";
} else {
echo "Error creating table: " . $conn->error;
}
$conn->close();
?>
Try this code by replacing your code. It will work. i have tried. Problem in your last line of your code.
CREATE TABLE $table(
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30),
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
As Nigel has said in the comment, it's definitely a bad idea to allow user input to create a table.
How I would think about doing this would be to use relationships between the Table Guests and the Table or Booking you want them to be added to.
You would just need to create two tables, one for the Booking and one for the Guests then in the Guests table, have a Booking_ID field which would contain the ID of the bookings the user should be added to.
This way, when you want to look for Guests for a specific table, you would be able to do SELECT * FROM MyGuests WHERE booking_id=[the booking id] and this would return the guests for that table.
Like other users stated there are several reasons (most importantly security) not to do that, but if you really want it you have to use concatenation for your string:
Option
$sql = "CREATE TABLE {$table}(id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30), email VARCHAR(50), reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";
Option
$sql = "CREATE TABLE" . $table . "(id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30), email VARCHAR(50), reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP)";

In a 1-1 relationship, why is my insert inserting two records in two tables?

I'm having trouble, as title says, when I INSERT a record in a table that has got a 1-1 relationship with another.
First things first, the SQL code that generates the tables:
DROP TABLE IF EXISTS Facebook_Info;
DROP TABLE IF EXISTS Conversations;
CREATE TABLE IF NOT EXISTS Conversations(
c_id INT AUTO_INCREMENT NOT NULL,
c_start TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
channel ENUM('desktop', 'facebook'),
u_name VARCHAR(20) DEFAULT NULL,
u_email VARCHAR(50) DEFAULT NULL,
PRIMARY KEY(c_id)
);
CREATE TABLE IF NOT EXISTS Facebook_Info (
c_id INT AUTO_INCREMENT NOT NULL,
f_id INT(12) NOT NULL,
PRIMARY KEY(c_id),
FOREIGN KEY(c_id) REFERENCES Conversations(c_id)
);
I assure you this code works: I tested it. I hope this is the best way to provide a 1-1 relationship between Conversations and Facebook_Info.
In any case, now I can introduce you my nightmare: I'm trying to insert a new record in Conversations via PHP (procedural style).
public function create_new_id_conv($channel = 1) {
$w_ch = '';
if ($channel == 2) {
$w_ch = 'facebook';
} else {
$w_ch = 'desktop';
}
$query = "INSERT INTO Conversations (c_id, c_start, channel) VALUES (NULL, CURRENT_TIMESTAMP,'$w_ch')";
$conn = mysqli_connect("localhost", Wrapper::DB_AGENT, Wrapper::DB_PSW, Wrapper::DB_NAME);
$res = mysqli_query($conn, $query);
$id_conv= mysqli_insert_id($conn);
mysqli_free_result($res);
return $id_conv;
}
The Wrapper:: * variables are all set well, in fact, an INSERT operation is done, but not only one! I'm having this situation after I call this function:
This is the content of Conversations table:
And here's the content of Facebook_Info:
What's happening?
I searched and searched...
Then I started to think about what I'm getting here: 2147483647. What represents this number? What's that? Seems like a big number!
And what if my script and my queries were correct but the mistake is the skeleton of my tables?
I must register a 14 digit integer, that is too large for the INT type.
So using BIGINT to store the f_id field made all correct and working!
Hope my mistake helps someone!

MySQL CREATE produces redundant index

When creating a new database table with the following code phpMyAdmin reports a redundant index like explained in this post. Is there a way to avoid this behavior and have only one index produced on table creation? I could remove the second index with ALTER TABLE mytest DROP INDEX id; but maybe there is a more elegant solution?
<?php
$sql = "CREATE TABLE IF NOT EXISTS `mytest` (
`id` SERIAL PRIMARY KEY,
`mytext` TEXT
) CHARSET=utf8";
mysqli_query($mysqli, $sql);
$sql = "SHOW INDEX FROM `mytest`";
if ($res = mysqli_query($mysqli, $sql)) {
while ($ds = mysqli_fetch_array($res)) {
echo "<pre>";
print_r($ds);
echo "</pre>";
}
} else echo mysqli_error($mysqli);
?>
According to the documentation:
SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
Hence, your declaration is:
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY
So, you are getting an index for UNIQUE and an index for PRIMARY KEY.
The simple solution is to not use "abbreviations" and be clear about what you want:
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY

MySQLi table creation via PHP Error calling prepare()

I am using PHP to put automatically generate a Database with its tables, but for some reason I am getting an error when calling the prepare statement for table3. I have tried combing it over and re-writing it a bunch of times, but I am just not seeing what I am missing. Can you help me out?
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DB);
$table1 = 'CREATE TABLE ArtecAdmins
(
id INT NOT NULL AUTO_INCREMENT,
Username VARCHAR(160) NOT NULL,
Password VARCHAR(160) NOT NULL,
PRIMARY KEY(id)
)';
$table2 = 'CREATE TABLE ArtecRacers
(
id INT NOT NULL AUTO_INCREMENT,
Firstname VARCHAR(50) NOT NULL,
Lastname VARCHAR(50) NOT NULL,
Banner VARCHAR(150),
Bio TEXT(1000),
PRIMARY KEY(id)
)';
$table3 = 'CREATE TABLE Parts
(
id INT NOT NULL AUTO_INCREMENT,
sku VARCHAR(20) NOT NULL,
PRIMARY KEY(id)
)';
$table4 = 'CREATE TABLE PartsUsed
(
id INT NOT NULL AUTO_INCREMENT,
ItemID INT NOT NULL,
RacerID INT NOT NULL,
Used INT NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY(ItemID) REFERENCES Parts(id),
FOREIGN KEY(RacerID) REFERENCES ArtecRacers(id)
)';
$makeTables = $mysqli
->prepare($table1)
->prepare($table2)
->prepare($table3) //Error happens here...
->prepare($table4)
->execute();
The Error I am receiving says that I am calling the prepare function on a non-object. I am sure it is something really simple, but I am stumped. Any help would be greatly appreciated!
you cannot use prepare like this. It is execute can be called multiple times, not prepare.
you don't need prepare here at all. just run $mysqli->query() four times

MySQLi CREATE Table query not working

$sql = "CREATE TABLE comments
(
ID INT NOT NULL AUTO_INCREMENT,
PosterName VARCHAR(32),
Title VARCHAR(32),
Content VARCHAR(500)
)";
$con->query($sql);
No errors, connection to database is successful. Does anyone know why it doesnt work?
You should have seen that error with that statement:
Incorrect table definition; there can be only one auto column and it must be defined as a key:
auto_increment column must have an UNIQUEindex on them, or more generally being the PRIMARY KEY:
$sql = "CREATE TABLE comments
(
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
PosterName VARCHAR(32),
Title VARCHAR(32),
Content VARCHAR(500)
)";

Categories