Change auto increment value if a duplicate exist from another table - php

I am trying to generate a temporary ID for a student registration process, for applicants who do not have a specified identity document. However, there were instances when the some applicants used arbitrary ID numbers which are in the series we have selected for official temporary ID number generation.
When I create a temporary ID (via the c_nic table), I need to check whether that ID is already used by an applicant (in the a_student table) and if yes, skip that number to the next number in c_nic, so on and forth. I am using the auto_increment of the temporary ID table (c_nic)
e.g. When a student comes in for registration and he doesn't have an ID number, we will generate a temporary ID for him. This will be the auto_increment in the c_nic table. Say, 11001111. Before releasing this ID for the student's use, I need to check whether this has been used by another student by mistake. If 11001111 is used by another student for his registration, I need to give the current student the next available ID, which may be 11001112 or if that is also used 11001113 and so on. When the new student is given the new temporary ID, I need to adjust the auto_inc value in the c_nic table, so that the second new student gets the next available ID number.
I tried with the following code, but the auto_increment does not increase even if there is a records already exists in the a_students table
$refid = mysqli_query($conn, "SELECT `AUTO_INCREMENT` AS id FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '".DB_NAME."' AND TABLE_NAME = 'c_nic'");
$refnum = mysqli_fetch_assoc($refid);
$ref = $refnum["id"];
$refnew = $refnum["id"]+1;
$chkduplicate = mysqli_query($conn, "SELECT nic FROM a_students WHERE nic='$ref'");
do {
$chkduplicate = mysqli_query($conn, "ALTER TABLE c_nic AUTO_INCREMENT = '$refnew'");
$refnew = $refnum["id"]+1;
echo '<br/>Ref: '.$ref;
echo '<br/>Ref New: '.$refnew;
}
while (mysqli_affected_rows($conn) >0 );

I suggest you to use table as auto increment & primary key for unique student id
like below
ALTER TABLE a_students
ADD PRIMARY KEY (nic);
ALTER TABLE a_students AUTO_INCREMENT = 1;

Related

Is there a way to auto-increment in MYSQL after deleting a row from the database?

Is there a way to auto-increment in MYSQL after deleting a row from the database?
For example:
There is a table with 3 columns: StudentID, Student Name, and Contact details. Here StudentID will be the primary key which will keep incrementing after adding values in each column.
The PHP code will look as follows:
<?php
require_once "Delete_Form.php";
if ($_GET || id['id']) {
$id = mysqli_real_escape_string($db, $_GET['id']);
} else {
echo 'Value was not brought over';
}
echo $id;
$result = mysqli_query($db,"SELECT StudentID, StudentName, Contact FROM student WHERE
StudentID='$id'");
$row = mysqli_fetch_row($result);
$sql= "DELETE FROM `student` WHERE `student`.`studentID` = $id";
echo "<pre>\n$sql\n</pre>\n";
mysqli_query($db,$sql);
echo 'Success -Continue...';
return;
Once we delete an entry from the database the Auto-Incrementation of StudentID will mess up i.e if the last entry had a StudentID of 12 and then we delete the same then the next row we enter will have StudentID of 13.
We can always do ALTER TABLE `student` AUTO_INCREMENT = 1 which will reset it but that will solve the problem temporarily only.
Is there a way to add a PHP statement in the above code to reset auto increment whenever we delete a row?
Do it never.
Primary key in a table identifies the row uniquely during the whole table lifetime. Pay attention - TABLE lifetime, not ROW lifetime. The fact that the row was deleted changes nothing - the value identifies this deleted row nevertheless.
If you need rows enumeration without the gaps then create special column for this purposes or enumerate in a query.
PS. By the way, synthetic AI PK must be hidden for the user at all - this column destination is row identifying and foreign keys subsystem work. It must not have any additional meaning.

INSERT where doesn't exist in php script, comparing 2 tables

I currently have a script that runs every 5 minutes and selects the data from a table on server 1 and an identical table on server2. This is a workaround for replication, essentially, since we don't have that option currently.
The script is successful but I've realized that it misses records sometimes, for whatever reason. The current script selects all records from the destination table, stores the max primary key, selects all data from the source table and then inserts anything with a greater Primary key into the dest. table.
I'd like to modify the script slightly and instead of using max id, just say "if a row has an primary key that doesn't exist in the destination table, insert that row there."
Again these are cloned tables so the structure is the same and they both use AI Primary Keys.
Here's the current working script:
$latest_result = $conn2->query("SELECT MAX(`SESSIONID`) FROM
`ambition`.`session`");
$latest_row = $latest_result->fetch_row();
$latest_session_id = $latest_row[0];
//Select All rows from the source phone database
$source_data = mysqli_query($conn, "SELECT * FROM
`cdrdb`.`session` WHERE `SESSIONID` > $latest_session_id");
// Loop on the results
while($source = $source_data->fetch_assoc()) {
// Check if row exists in destination phone database
$row_exists = $conn2->query("SELECT SESSIONID FROM
ambition.session WHERE SESSIONID = '".$source['SESSIONID']."' ") or
die(mysqli_error($conn2));
//if query returns false, rows don't exist with that new ID.
if ($row_exists->num_rows == 0){
//Insert new rows into ambition.session
$stmt = $conn2->prepare("INSERT INTO ambition.session (SESSIONID,
SESSIONTYPE,CALLINGPARTYNO,FINALLYCALLEDPARTYNO,
DIALPLANNAME,TERMINATIONREASONCODE //etc. There are a lot of columns so I
ommitted the others
Is there a way I can slightly modify this to just insert what doesn't exist rather than relying on the MAX ID?
Or is there something here that would be a culprit as to why it's missing records?
You could use INSERT INTO SELECT and check if value is already in target:
INSERT INTO trg_table (cols)
SELECT cols
FROM src_table s
WHERE NOT EXISTS (SELECT 1 FROM trg_table t WHERE t.id = s.id);

putting values in between the ascending database column

Following is my database in mysql:
Id Username Password
1 admin admin
2 jay jay1
3 suman xyza
4 chintan abcde
This is my code in php:
$fetchid = mysql_query(" SELECT MAX(Id) As max From user;");
$row = mysql_fetch_array($fetchid);
$largest = $row['max'];
$largest++;
$user= $_POST['username'];
$pass= $_POST['password'];
$result = mysql_query(" INSERT INTO `proshell`.`user` (
`Id` ,
`Username` ,
`Password`
)"."
VALUES (
'".$largest."', '".$user."', '".$pass."'
);");
Problem:
Now if I delete row with Id=1 and then re-enter the data then it should use ID=1 then Again I reinsert the data it use ID=5
It works like this:
if I delete row with Id=1 and then re-enter the data the Id it gets is 5 but then 1 is free so,
What should I write to perform that task.
First, if you set your Id column to AUTO_INCREMENT you don't need the following part in your code at all:
$fetchid = mysql_query(" SELECT MAX(Id) As max From user;");
$row = mysql_fetch_array($fetchid);
$largest = $row['max'];
$largest++;
Because AUTO_INCREMENT will automatic add new value to your ID colume.
But if you don't set it to AUTO_INCREMENT, the above code will grab the MAXIMUM ID value (in this case, 4).
When you re-enter your data again after you delete the row 1, the MAXIMUM ID still 4, so your new ID value will be 5 (from $largest++;).
.....
If you really need to use consecutive ids as you PK, you need to re-write you code but I suggest you to use UUID for you ID column instead.
You can easily generate UUID by using uuid().
How about the UUID performance? Refer to Dancrumb's answer about this:
A UUID is a Universally Unique ID. It's the universally part that you should be considering here.
Do you really need the IDs to be universally unique? If so, then UUIDs
may be your only choice.
I would strongly suggest that if you do use UUIDs, you store them as a
number and not as a string. If you have 50M+ records, then the saving
in storage space will improve your performance (although I couldn't
say by how much).
If your IDs do not need to be universally unique, then I don't think
that you can do much better then just using auto_increment, which
guarantees that IDs will be unique within a table (since the value
will increment each time)
see. UUID performance in MySQL?
EDIT: I don't suggest you run query on the whole table just to find the MAX ID value before inserting new value everytime, because it will give you a performance penalty (Imagine that if you have million rows and must query on them everytime just to insert a new row, how much workload causes to your server).
It is better to do the INSERT just as INSERT, no more than that.
EDIT2:
If you really want to use consecutive ids, then how about this solution?
Create new TABLE just for store the ids for insert (new ids and the ids that you deleted).
For example:
CREATE TABLE cons_ids (
ids INT PRIMARY KEY,
is_marker TINYINT DEFAULT 0
);
then initial ids with values from 1-100 and set marker to be '1' on some position, e.g. 80th of whole table. This 'marker' uses to fill your ids when it's nearly to empty.
When you need to INSERT new Id to your first table, use:
$result = mysql_query("SELECT ids, marker FROM cons_ids ORDER BY ids ASC LIMIT 1;");
$row = mysql_fetch_row($result);
and use $row[0] for the following code:
INSERT INTO yourtable (Id, Username, Password)
VALUES ($row[0], $username, $password);
DELETE FROM cons_ids
WHERE ids = $row[0];
This code will automatically insert the lowest number in cons_ids as your Id and remove it from the cons_ids table. (so next time you do insert, it will be the next lowest number)
Then following with this code:
if ($row[1] == 1) {
//add new 100 ids start from the highest ids number in cons_ids table
//and set new marker to 80th position again
}
Now each time you delete a row from your first table, you just add the Id from the row that you deleted to cons_ids, and when you do INSERT again, it will use the Id number that you just deleted.
For example: your current ids in cons_ids is 46-150 and you delete row with Id = 14 from first table, this 14 will add to your cons_ids and the value will become 14, and 46-150. So next time you do INSERT to your first table, your Id will be 14!!.
Hope my little trick will help you solve your problem :)
P.S. This is just an example, you can modify it to improve its performance.
First of all, as I understand, you are selecting highest column ID which should be always the last one (since you set auto-increment on ID column).
But what are you trying to do is actually filling up holes after delete query, right?
If you are really looking for such approach, try to bypass delete operation by making new boolean column where you flag record if it is active or not (true/false).
SQL table change:
Id Username Password Active
1 admin admin false
2 jay jay1 true
3 suman xyza false
4 chintan abcde true
PHP request:
$fetchid = mysql_query(" SELECT MIN(Id) As min FROM user WHERE active = false;");
$result = mysql_query(" INSERT INTO `proshell`.`user` (
`Id` ,
`Username` ,
`Password`
`Active`
)"."
VALUES (
'".$largest."', '".$user."', '".$pass."', 'true'
);");

Add a new record to database after checking value

I am inserting data into a database fine with the user entering a reference number eg 1234. Can I change my insert to not require the user to input the value and for the last value entered to be checked and then the reference number being inserted be incremented by one and then inserted with the other data. Bit of a new bee. Here is my current code
$Reference_No = $_POST['Reference_No'];
$Property_Name = $_POST['Property_Name'];
$Property_Area = $_POST['Property_Area'];
mysql_query("INSERT INTO properties (Reference_No, Property_Name, Property_Area)
VALUES ('$Reference_No', '$Property_Name', '$Property_Area')");
You need to make the Reference_No an AUTO_INCREMENT.
Step 1:Create table
CREATE TABLE properties (
Reference_No int AUTO_INCREMENT ,
Property_Name varchar(255),
Property_Area varchar(255),
PRIMARY_KEY (Reference_No)
)
Step 2 : Set the start for auto increment of primary key if you like
ALTER TABLE properties AUTO_INCREMENT=1234;
Step 3: Insert the data into the table
INSERT INTO properties (Property_Name, Property_Area)
VALUES ('$Property_Name', '$Property_Area')");
interogate the database for the Reference NO (where property name matches if you need it)
$reference_no_query = mysql_query("SELECT Reference_No FROM properties WHERE Property_Name = $Property_Name");
pull the Reference No out of the database
$Reference_no = mysql_fetch_array($reference_no_query)
display the Reference no
echo $Reference_no('Reference_no');
you can (and should) tie the data to a variable then echo the var like this:
$Reference_no_display = $Reference_no('Reference_no');
then display it directly from the variable anywere and as many times as you want in the page below the query:
echo $Reference_no_display;
This seems to do the trick for the final bit
printf("Last inserted record has id %d\n", mysql_insert_id());

Adding 2000 autocomplete field records to an existing mysql table

I have a table named users
fields:
ID INT
First_name VARCHAR
Second_name VARCHAR
National_ID INT
The ID field is an AUTO_INCREMENT.
I need to AUTO_INCREMENT the first 2000 users with just the ID and the other fields remain blank,so that the new users will start at 2001.
Kindly assist.
It's called auto increment, your ID column must be set to auto increment.
ALTER TABLE users AUTO_INCREMENT=2001;
Update
If you wish to actually create those rows (not just set the auto increment value) you can use PHP for this:
for($i=1; $i<=2000; $i++)
{
$query = 'INSERT INTO users (id) VALUES ('.$i.')';
//execute this query using your desired PDO or sql extension
}

Categories