mysqli fatal error: No index used in query/prepared statement - php

I want to execute a simple prepared Statement using mysqli, but it won't work.
I have this table:
CREATE TABLE IF NOT EXISTS `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) COLLATE latin1_german2_ci NOT NULL,
`password` varchar(100) COLLATE latin1_german2_ci NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci AUTO_INCREMENT=4 ;
And want to print the id of a specific email.
$mysqli = new mysqli($server,$user,$pass,$db);
if(mysqli_connect_errno()) {
echo "Connection Failed: " . mysqli_connect_errno();
exit();
}
$user = "test#dada.com";
$pass = "dada";
/* Create a prepared statement */
if($stmt = $mysqli -> prepare("SELECT * FROM account WHERE email=?
AND password=?")) {
/* Bind parameters
s - string, b - blob, i - int, etc */
$stmt -> bind_param("ss", $user, $pass);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $user . "id of user is " . $result;
/* Close statement */
$stmt -> close();
}
/* Close connection */
$mysqli -> close();
But i get following Error:
Fatal error: Uncaught exception 'mysqli_sql_exception' with message 'No index used in query/prepared statement SELECT * FROM account WHERE email=? AND password=?' mysqli_stmt->execute() #1 {main}

Your problem is that the query you are executing is going to be inefficient without using an INDEX.
SELECT * FROM account WHERE email=? AND password=?
There's no index on any of the two fields you have used in the WHERE clause. One solution would be to create an index on both fields which should make the error go away.
ALTER TABLE account ADD INDEX `index_on_email_and_password` (email, password);
In many situations, you know that the INDEX is not going to improve the performance, so you can safely ignore this error. To do so, replace the following line of code:
mysqli_report(MYSQLI_REPORT_ALL);
with one of these
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// or
mysqli_report(MYSQLI_REPORT_ALL & ~MYSQLI_REPORT_INDEX);
This will keep on reporting normal SQL errors, but it will ignore all warnings about bad indexes.

Well I think you have to do this:
CREATE TABLE IF NOT EXISTS `account` (
`id` PRIMARY KEY int(11) NOT NULL AUTO_INCREMENT,
// the rest
The above code makes the id field of your table as PRIMARY KEY so it never repeats itself and it remains the index of your table.

Related

Cannot create table with PHP

I want to create a table with variables passed into my php file. However, the SQL does not work when I pass in '12345' and works when I pass in 'a12345' instead.
This is my error that is given.
Error creating the table
query was
CREATE TABLE 123456 ( humidity VARCHAR(50) NOT NULL, temperature VARCHAR(50)
NOT NULL, gasquality VARCHAR(50) NOT NULL, timestamp DATETIME NOT NULL
DEFAULT CURRENT_TIMESTAMP)
mysqlerror:You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near
'123456 ( humidity VARCHAR(50) NOT NULL, temperature VARCHAR(50) NOT NULL,
gasq' at line 1
Creating database failed!
and my function that creates the table
function CreateTableNode(&$formvars)
{
$serialno = $formvars['serialno'];
$qry = "CREATE TABLE ".$serialno." (".
" humidity VARCHAR(50) NOT NULL, ".
" temperature VARCHAR(50) NOT NULL, ".
" gasquality VARCHAR(50) NOT NULL, ".
" timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP)";
if(!mysqli_query($this->connection,$qry))
{
$this->HandleDBError("Error creating the table \nquery was\n $qry");
return false;
}
return true;
}
I want to be able to create tables with numeric names like '12345' or '154124' for other purposes. Thanks alot!
My suggestion:
Provide a prefix to the table you created.
Moreover, I couldn't
see the primary key in your table. However, it is not necessary to
have it but if your table design doesn't have a primary key, you need
to rethink your design. It plays a vital role to join tables.
Your code can be rewritten as:
function CreateTableNode (&$formvars) {
$host = 'localhost';
$database = 'test';
$dbuser = 'root';
$dbpass = '';
try {
$pdo = new PDO('mysql:host=localhost; dbname=test', $dbuser, $dbpass);
} catch (PDOException $e) {
print "ERROR! : " . $e->getMessage() . "<br/>";
die();
}
$serialno = $formvars['serialno'];
$qry = "CREATE TABLE ".$serialno." ("."
`id` INT NOT NULL AUTO_INCREMENT ,
`humidity` VARCHAR(50) NOT NULL ,
`temperature` VARCHAR(50) NOT NULL ,
`gasquality` VARCHAR(50) NOT NULL ,
`timestamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY (`id`)
)";
$stmt = $pdo->prepare($qry);
$stmt->execute();
$pdo = null;
return true;
}
You just need to wrap some elements in the query with quotes as the duplicated thread mentioned by underscore_d says:
$qry = "CREATE TABLE '$serialno' (
'humidity' VARCHAR(50) NOT NULL,
'temperature' VARCHAR(50) NOT NULL,
'gasquality' VARCHAR(50) NOT NULL,
'timestamp' DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP)";
This will fix your syntax errror in the query.
Marking to close the question as duplicated
The name of the entity was expected. (near "123456" at position 13)
Try adding a prefix to the table name as such
"t_12345"
CREATE TABLE t_12345
MySql does not allow numeric values as table name.
MySQL doesn't allow the creation of tables with names made solely of digits unless the name is quotes. See here
Identifiers may begin with a digit but unless quoted may not consist solely of digits.
Try quoting the name with backticks (`) or prefix the table name.
The error says "Creating database failed!".
So I assume you haven't selected the database in the connection query. You should do that or select it with "use mydatabase;" first. Of course, you may need to create the database first.
With PDO it would look like:
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
Please see dbname=myDB which preselects the right db for you.
Reference: https://www.w3schools.com/php/php_mysql_connect.asp
Using mysql functions, you can use:
mysql_select_db($dbname)
Reference: http://php.net/manual/en/function.mysql-select-db.php

Error performing sql query in PHP

I am trying to learn using mysql in php. I started off trying to create a table in mysql, and using the mysqli extension.
My code:
<?php
$truemsg = "Table created successfully";
$falsemsg = "Error creating table: ";
$servername = "localhost";
$username = "myuser";
$password = "mypass";
$db = "mytable";
// Create database
$sql = "USE ".$db.";".
'CREATE TABLE IF NOT EXISTS Authentication (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
userid VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL,
role VARCHAR(20) NOT NULL,
email VARCHAR(50)
);';
print "Sql command is ".$sql;
// Create connection
$conn = new mysqli($servername, $username, $password);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
print "<p></p>";
if ($conn->query($sql) === TRUE) {
echo $truemsg;
} else {
echo $falsemsg . $conn->error;
}
$conn->close();
?>
The error is:
Sql command is USE mytable;CREATE TABLE IF NOT EXISTS Authentication ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, userid VARCHAR(30) NOT NULL, password VARCHAR(30) NOT NULL, role VARCHAR(20) NOT NULL, email VARCHAR(50) );
Error creating table: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TABLE IF NOT EXISTS Authentication ( id INT(6) UNSIGNED AUTO_INCREMENT PR' at line 1
I tried pasting the same command on the mysql command line, and it works fine. What's the problem using this in php?
You are supposed to run queries one by one
$sql = "query one";
$conn->query($sql);
$sql = 'query two';
$conn->query($sql);
instead of coupling them all in one statement.
DO NOT use mysqi_multi_query() either, this asynchronous function is not intended for the everyday use.
Also, in this particular case USE query is superfluous. Database should go into constructor:
$conn = new mysqli($servername, $username, $password, $db);
^^^ here
Also, tell mysqli to throw errors by itself, automatically, instead of checking result of every database command manually:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
This way you will get neat and clean code:
<?php
$servername = "localhost";
$username = "myuser";
$password = "mypass";
$db = "mytable";
// Create data table
$sql = 'CREATE TABLE IF NOT EXISTS Authentication (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
userid VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL,
role VARCHAR(20) NOT NULL,
email VARCHAR(50)
)';
// Create connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli($servername, $username, $password, $db);
// Run a query
$conn->query($sql);
echo "Table created successfully";
This code will either report that table has been created successfully, or emit an error, with a detailed explanation on what went wrong.
This seems to be like a mysql multiple query problem
$conn->select_db($db);
you can use this function before the query to use the database and remove the use database statement from your query string , then you query string becomes
$sql = 'CREATE TABLE IF NOT EXISTS Authentication (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
userid VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL,
role VARCHAR(20) NOT NULL,
email VARCHAR(50)
)';
that may work for you ..

How to Insert in MySQLi in prepared statement

Hi! My table structure looks like this:
CREATE TABLE IF NOT EXISTS `search` (
`key` varchar(255) NOT NULL,
`id` int(15) NOT NULL auto_increment,
UNIQUE KEY `key` (`key`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
And this is how I try to add data into my table:
$stmt = $mysqli->prepare("INSERT INTO search(key) VALUES (?)");
$stmt->bind_param('s',$keyword);
$stmt->execute();
$stmt->close();
This is what I got:
Call to a member function bind_param() on a non-object
But it works when I do this:
$stmt = $mysqli->prepare("INSERT INTO search VALUES (?,NULL)");
$stmt->bind_param('s',$keyword);
$stmt->execute();
$stmt->close();
Is there any other way besides putting NULL to the VALUES?
is there any necessity that i should put NULL to auto increments?
No.
And there is no necessity in finding an answer by means of wild guess either.
You have to get the error message instead.
For which purpose always have this line right before connecting to mysqli:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
speaking for the certain query, key is a mysql keyword and have to be quoted in backticks
INSERT INTO search(`key`) VALUES (?)

PHP PDO::lastInsertId() returns 0

Thanks in advance for reading this, I couldn't find an answer that solved my problem... I don't understand what I'm doing differently than the tutorials/suggestions I found:
SQL Table
CREATE TABLE IF NOT EXISTS `LastInsertID` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(150) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
PHP File
<?php
// Connect to database
$user = "foo";
$pswd = "bar";
$db = new PDO( 'mysql:host=localhost;dbname=test', $user, $pswd );
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Prepare request
$rq = $db->prepare('INSERT INTO `LastInsertID` VALUES(NULL,:name,:email)');
// Begin and commit request
$db->beginTransaction();
$values = array('name'=>'Foo','email'=>'bar#baz.com');
$rq->execute($values);
$db->commit();
// Echo last ID
echo $db->lastInsertId();
?>
This returns 0 when it should return 6. Where is the problem?
You must use $db->lastInsertId() before you commit if you are in a transaction. Even if you rollback a transaction, the id is "used" or skipped, which is why you should not depend on IDs to be sequential.
Use this
INSERT INTO `LastInsertID` (name, email) VALUES(:name,:email)
instead
INSERT INTO `LastInsertID` VALUES(NULL,:name,:email)
I have removed the NULL.

PHP: Getting insert confirmation on prepared statement

I am a newbie to prepared statements and trying to get something simple to work.
This is my DB table:
`unblocker_users` (
`uno` bigint(20) NOT NULL AUTO_INCREMENT,
`user_email` varchar(210) DEFAULT NULL,
`pw_hash` varchar(30) DEFAULT NULL,
`email_confirmed` tinyint(4) DEFAULT NULL,
`total_requests` bigint(20) DEFAULT NULL,
`today_date` date DEFAULT NULL,
`accessed_today` tinyint(4) DEFAULT NULL,)
and this is my function to insert some test data
function add_new_user($e_mail1)
{
require_once "db.php";
$stmt = $mysqli->prepare("INSERT INTO unblocker_users VALUES ('',?, ?,0,0,?,0)");
$stmt->bind_param('sss', $e_mail1, $this->genRandomString(1),$this->today_date());
$stmt->execute();
$stmt->close();
// ####### Below line is giving an error ########
$done = $stmt->affected_rows;
return $done;
}
As you can see above, i have marked the line that is giving me an error.
Warning: unblocker_class::add_new_user() [unblocker-class.add-new-user]: Property access is not allowed yet in...
Where did I go wrong?
How can i get some sort of confirmation that a row has been inserted successfully?
Thanks!
you close the prepared statement BEFORE you want to access its affected rows
$done = $stmt->affected_rows;
$stmt->close();
return $done;

Categories