I'm trying to set the Auto Increment of my tables st_id to = 201406001
query:
ALTER TABLE
support_ticket AUTO_INCREMENT=201406001
When doing this it worked and now my "st_id" (AI, Primary key) is set to 201406001 just as I wanted.
When I ran that query it said it affected 4 rows which is right, because there were 4 rows in the table when I ran that query.
But now when I try and update the status of a specific column in one of those 4 rows, it will not update.
Is my ALTER TABLE query wrong?
I tried running the following query to only target the st_id like this, but gave me an error.
ALTER TABLE
support_ticket.st_id AUTO_INCREMENT=201406001
FROM
support_ticket
ERROR
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 'FROM
support_ticket' at line 3
So my question is, should I stick with my original query, as it did work, or should I try to get the 2nd query working?
Also, could running that 1st query be that be the reason I cannot update my column now?
This is my first time using ALTER TABLE so any help would be of use.
Here is my update code:
Form
<form method="POST" action="close.php" enctype="multipart/form-data">
<input type="hidden" name="st_id" value="<?php echo escape ($t->st_id); ?>">
<h3>Close this ticket...</h3>
<select name="status">
<option value="<?php echo escape($t->status); ?>">Current Status: OPEN</option>
<option value="0">CLOSE</option>
</select>
<input type="submit" value="CLOSE"><input type="button" value="Cancel" onclick="window.location = '/admin/maintenance/'">
</form>
Action script:
include($_SERVER['DOCUMENT_ROOT'] . "/core/init.php");
$st_id = $_POST['st_id'];
$status = $_POST['status'];
$updatestatus = DB::getInstance()->UPDATE('support_ticket', $st_id, array(
'status' => $status,
));
echo "The ticket was successfully closed.<br />
Solution to my UPDATE problem:
Finally got it to update by this:
$st_id = $_POST['st_id'];
$status = $_POST['status'];
$updatestatus = DB::getInstance()->query("UPDATE `support_ticket` SET `status` = $status WHERE `st_id` = $st_id");
It seems to trial to auto-increment according to year or month. You can use MySQL Custom AUTO_INCREMENT values as follows:
(read the article first)
I changed the function getNextCustomSeq the line:
SET #ret = (SELECT concat(sSeqGroup,'-',lpad(nLast_val,6,'0')));
to
SET #ret = (SELECT concat(sSeqGroup,lpad(nLast_val,3,'0')));
Then I create table and triggeras follows:
CREATE TABLE ticket(
id int not null primary key auto_increment,
autonum int not null
);
DELIMITER $$
CREATE TRIGGER ticket_autonums_bi BEFORE INSERT ON ticket
FOR each ROW
BEGIN
SET NEW.autonum = getNextCustomSeq(date_format(now(),'%Y%m'),date_format(now(),'%Y%m'));
END$$
delimiter ;
Note: The function date_format(now(),'%Y%m') will return current year and mont like "201406"
Now insert some values:
insert into ticket(id)
values (null),(null),(null),(null),(null),
(null),(null),(null),(null),(null);
Select the inserted data:
mysql> select * from ticket;
+----+-----------+
| id | autonum |
+----+-----------+
| 1 | 201406001 |
| 2 | 201406002 |
| 3 | 201406003 |
| 4 | 201406004 |
| 5 | 201406005 |
| 6 | 201406006 |
| 7 | 201406007 |
| 8 | 201406008 |
| 9 | 201406009 |
| 10 | 201406010 |
+----+-----------+
10 rows in set (0.00 sec)
ALTER TABLE ... AUTO_INCREMENT=201406001 only means that the next AI value generated will be that value. It doesn't change the id value in any of the current rows of data in the table.
The "affected rows" message meant that it performed a table copy as part of the ALTER TABLE. Some older versions of MySQL would naively copy all the rows in the table, even though you wouldn't think it had to to perform the metadata change.
So if you try to UPDATE ... WHERE id=201406001 it will not apply to your existing rows.
With ALTER you update your tabledescription (ie columnnames, values for autoincrement).
If you want to update the values of a table you have to use UPDATE. ie:
UPDATE support_ticket SET status = 'closed' WHERE id = 1234;
If you're new to SQL have a look at w3schools.com. they have some tutorials (http://www.w3schools.com/sql/sql_update.asp)
Related
I use mysql and php with phpmyadmin. I have major problem with a partition based counter that I wan't to improve but my knowledge on sql prevents me from doing that. Im struggling very much with this.
I want the duplicated data in my table to have a counter that adds a number after a value if this value gets a duplicated value and then restarts from 1 until a new value is met and so on. Here is what the final result should look like
---------------------------
1 | Josh-1
---------------------------
2 | Josh-2
--------------------------
3 | Josh-3
--------------------------
4 | Josh-4
--------------------------
5 | Fred-1
--------------------------
6 | Fred-2
--------------------------
7 | Fred-3
-------------------------
I had gotten help with this counter here before but it's not working as I wan't it to. Also when I have pressed the insert button in my form the table looks like this in phpmyadmin after I reload it
---------------------------
1 | Josh-1-1-1
---------------------------
2 | Josh-2
--------------------------
3 | Josh-3
--------------------------
4 | Josh-4
--------------------------
5 | Fred-1
--------------------------
6 | Fred-2
--------------------------
7 | Fred
-------------------------
Whats going on here? The code that I seek help with rewriting is this
UPDATE usermeta u1,
(SELECT
u1.`id`, CONCAT(u1.`name`,'-',ROW_NUMBER() OVER(PARTITION BY u1.`name` ORDER BY u1.`id`)) newname
FROM
usermeta u1 JOIN (SELECT `name` , COUNT(*) FROM usermeta GROUP BY `name` HAVING COUNT(*) > 1) u2
ON u1.`name` = u2.`name` ) u3
SET u1.`name` = u3.`newname`
WHERE u1.`id` = u3.`id`
Could this code be rewritten so it creates a table of numbered names and duplicates that looks like the first table example and work like it should in phpmyadmin ? All help is very much appreciated. Keep in mind that I am a struggling moderate sql user.
Possible solution - BEFORE INSERT trigger and additional MyISAM table with secondary autoincrement:
Working table
CREATE TABLE user (id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(127));
Additional table
CREATE TABLE user_index (id INT AUTO_INCREMENT,
name VARCHAR(127),
PRIMARY KEY (name, id)) ENGINE=MyISAM;
Trigger
CREATE TRIGGER insert_user_index
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
DECLARE new_index INT;
INSERT INTO user_index (name) VALUES (NEW.name);
SET new_index = LAST_INSERT_ID();
DELETE FROM user_index WHERE name = NEW.name AND id < new_index;
SET NEW.name = CONCAT_WS('-', NEW.name, new_index);
END
Insert rows - the AI index is added to the name. Check the result.
INSERT INTO user (name) VALUES
('Josh'),
('Josh'),
('Fred'),
('Josh'),
('Fred'),
('Fred'),
('Josh');
SELECT * FROM user;
id | name
-: | :-----
1 | Josh-1
2 | Josh-2
3 | Fred-1
4 | Josh-3
5 | Fred-2
6 | Fred-3
7 | Josh-4
Look what is stored in additional table now.
SELECT * FROM user_index;
id | name
-: | :---
3 | Fred
4 | Josh
db<>fiddle here
If your working table user exists already, and it contains some data, then you'd create additional table and fill it with data using, for example,
CREATE TABLE user_index (id INT AUTO_INCREMENT,
name VARCHAR(127),
PRIMARY KEY (name, id)) ENGINE=MyISAM
SELECT MAX(SUBSTRING_INDEX(name, '-', -1) + 0) id,
SUBSTRING_INDEX(name, '-', 1) name
FROM user
GROUP BY 2;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=38f028cfe1c9e85188ab0454463dcd78
I have searched that there is already a way in inserting avoiding the duplicate error
ref: MySQL: Insert record if not exists in table
INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'Unknown' AS name, 'Unknown' AS address, '022' AS tele) AS tmp
WHERE NOT EXISTS (
SELECT name FROM table_listnames WHERE name = 'Unknown'
) LIMIT 1;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
SELECT * FROM `table_listnames`;
+----+---------+-----------+------+
| id | name | address | tele |
+----+---------+-----------+------+
| 1 | Rupert | Somewhere | 022 |
| 2 | John | Doe | 022 |
| 3 | Unknown | Unknown | 022 |
+----+---------+-----------+------+
is there a way for this to do in batch?
or how is the format in adding data as a batch
ref: insert multiple rows via a php array into mysql
Planning to integrate this one
$sql = array();
foreach( $data as $row ) {
$sql[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
}
mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $sql));
is there a way?
I would suggest using the ON DUPLICATE KEY syntax for this. This will simplify the query, and allow the use of the VALUES() statement, which is handy to pass parameters from your application.
For this to work, you need a unique (or primary key) constraint on colum name. Create it if it does not exist:
create unique index idx_table_listnames on table_listnames(name);
Then, you can do:
insert into table_listnames(name, address, tele)
values('Unknown', 'Unknown', '022')
on duplicate key update name = values(name)
The conflict clause traps violations on the unique index, and performs a no-op update.
Side note: use parameterized queries to pass data from your application to the query; escaping input is not enough to make your query safe.
Table_A
+--------+-----------+---------+
| id | name | views |
+--------+-----------++--------+
| num | text | int |
+--------+-----------+---------+
| 1 | Video 1 | 10 |
| NULL | NULL | 0 |
| NULL | NULL | 0 |
| NULL | NULL | 0 |
| NULL | NULL | 0 |
+--------+-----------+---------+
<a href="video.php?id=video1&idtitle=Hello%20Video1">
<a href="video.php?id=video2&idtitle=Hello%20Video2">
<a href="video.php?id=video3&idtitle=Hello%20Video3">
I'm trying to make the script do something like this.
1.User click on link
2.User is on video.php?id=video1
3.Mysql then add a +1 to my id column #1
4.then take the video title from $videoName
5.Mysql take the title inside of $videoname and store it on name column #2
6.Mysql then add +1 to Views everytime ID 1 is view
7.Mysql is now finish with Row 1
8.Now Mysql will repeat that same step if video.php?id=video2 and so on,
How can i make this happen?
$id = $_GET['id'];
$videoName = $_GET['idtitle'];
$pdo = new PDO('mysql:localhost;dbname=videocount', 'root', '');
$userip = $_SERVER["REMOTE_ADDR"];
if($userip){
$pdo->query("UPDATE Table_A SET (`id`, `name`, `views`)
VALUES (NULL,$videoName, views+1)");
}
I also try the code below but still no luck.
if($userip){
$pdo->query("INSERT INTO `videocount`.`Table_A` (`id`, `name`, `views`)
VALUES (NULL, '$videoname', 'views'+1)");
}
UPDATE instead of UPDATED, VALUES instead of VALUE. In addition you have to add a WHERE condition to your query to select record to update.
This is another correct syntax:
$pdo->query( "UPDATE `Table_A` SET `views`=`views`+1 WHERE `id`='$id'" );
Edit:
To update also the video name you can perform this query:
$pdo->query( "UPDATE `Table_A` SET `name`='{$videoName}', `views`=`views`+1 WHERE `id`='$id'" );
On the border, you should bind the variable values to avoid errors with titles special characters.
See more about binding and MySQL UPDATE syntax
I think there is a little confusion about data view logic.
First of all, you need to save all data into database, then list them for user.
When the use click the link to view this video, the column of views need to be updated.
I have this table called classes:
+------------+----------+------+-----+----------------+
| Field | Type | Null | Key | Extra |
+------------+----------+------+-----+----------------+
| class_id | int(3) | NO | PRI | auto_increment |
| class_level| int(1) | YES | | |
| class_name | char(1) | YES | | |
+------------+----------+------+-----+----------------+
With data inside like this:
+----------+-------------+------------+
| class_id | class_level | class_name |
+----------+-------------+------------+
| 1 | 0 | N |
| 2 | 1 | A |
| 3 | 1 | B |
| 4 | 2 | C |
| 5 | 2 | D |
| 6 | 3 | E |
| 7 | 3 | F |
+----------+-------------+------------+
With PHP I want to increment all values inside class_level except 0.
So I made this PHP/MySQL function:
mysql_query("UPDATE classes SET class_level = (class_level + 1) WHERE class_level != 0") or die(mysql_error());
This (what is weird) does not add 1 to each class_level except theese equal to 0, but adds 2 or 3 or 4! I haven't found a rule, that this script would add either 2 or 3 or 4. This is RANDOMLY picked. And there is no error outputted too.
All it does it adds randomly 2 or 3 or 4 to each row.
So, to debug it, I have done this PHP code to add to each one by one:
$query = mysql_query("SELECT * FROM `classes` WHERE `class_level` != 0");
while ($row = mysql_fetch_assoc($query)) {
$class_id = $row['class_id'];
$class_level = $row['class_level'];
$class_level = $class_level + 1;
var_dump($class_level);
mysql_query("UPDATE `classes` SET `class_level` = '$class_level' WHERE `class_id` = '$class_id'") or die(mysql_error());
}
The output from var_dump is:
int(2) int(2) int(3) int(3) int(4) int(4)
But in database in table I get following result:
+----------+-------------+------------+
| class_id | class_level | class_name |
+----------+-------------+------------+
| 1 | 0 | N |
| 2 | 4 | A |
| 3 | 4 | B |
| 3 | 5 | C |
| 4 | 5 | D |
| 5 | 6 | E |
| 6 | 6 | F |
+----------+-------------+------------+
This is an empty file with just MySQL connection and the code above, so there is no loop above it.
Here is my version information: PHP version: 5.2.12, MySQL Client API version 5.1.44. Note that I cannot install mysqli nor PDO.
EDIT:
Just after executing the MySQL query I have outputted data from table, and the result was, as it should be. But in table itself (or on refresh with code just for output) there was 3 added, not 1!
EDIT 2:
I tried executing this MySQL query from command line (aka Webmin tool for SQL commands) and the result was, as it should be: 1 was added.
EDIT
Added SQL Fiddle demonstration: http://sqlfiddle.com/#!9/efa05b/1
create table classes
( class_id int(3) not null auto_increment primary key comment 'pk'
, class_level int(1)
, class_name char(1)
)
;
insert into classes (class_id,class_level,class_name) values
('1','0','N')
,('2','1','A')
,('3','1','B')
,('4','2','C')
,('5','2','D')
,('6','3','E')
,('7','3','F')
;
update classes set class_level = (class_level + 1) where class_level != 0
;
A query verifies that expected result is returned. Each row (other than row with class_level=0) has been updated, with class_level incremented by exactly 1.
select * from classes order by class_id
class_id class_level class_name
-------- ----------- ----------
1 0 N
2 2 A
3 2 B
4 3 C
5 3 D
6 4 E
7 4 F
original answer
Assuming that there isn't a BEFORE/AFTER UPDATE trigger on the table, given the SQL statement being executed:
UPDATE classes SET class_level = (class_level + 1) WHERE class_level != 0
The most logical explanation for the behavior is that the SQL statement is being executed multiple times within the function, or, the function is being called multiple times.
To verify this, you could temporarily turn on the MySQL general log, run the test, disable the general log, and review... and you're going to find multiple executions of the statement. If you don't have access to the MySQL server, then the next best would be to echo out a line immediately before the statement is executed; you're going to see that line echoed out multiple times.
Highly unlikely that this is a bug in the MySQL database. (Verify there isn't a TRIGGER defined on the table.)
Also, test that statement using a different client, like mysql command like client, or phpmyadmin. And verify the statement is working correctly.
FOLLOWUP
Given that your test of the SQL statement from a different client gives the expected results, I think this demonstrates this isn't a problem with the MySQL database or the SQL statement.
For some reason, that SQL statement is being executed multiple times. As a next step in debugging, I would add some more code. I'd temporarily create a "log" table, using MyISAM engine, containing an auto_increment id, a datetime column, and an informational string:
CREATE TABLE debug_log
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, dt DATETIME
, info VARCHAR(40)
) Engine=MyISAM
Then add another SQL statement in your function to insert a row to that table, immediately before and/or after the execution of the UPDATE statement
INSERT INTO debug_log (dt, info) VALUES (SYSDATE(), 'my function before update')
Then, run the test, and see how many rows get inserted into the debug_log table.
To get an error thrown if this statement is executed more than one time, supply a fixed value for the id column, e.g.
INSERT INTO debug_log (id, dt, info)
VALUES (123, SYSDATE(), 'my function before update')
With the fixed value for id, if that statement gets called a second time, then MySQL will throw a duplicate key exception.
As I mentioned previously, based on the information provided, I suspect that your function is being called multiple times. (I don't have sufficient information to actually make that determination; that's just a hunch.)
Here is the simple solution below
<?php
print("<h1>BEFORE</h1>");
$q =mysql_query("select *from classes ");
while($row=mysql_fetch_array($q)){
print("$row['class_id'] - $row['class_level'] - row[$class_name] <br/>");
}
mysql_query("UPDATE classes SET class_level = class_level+1 WHERE class_level>0") or die(mysql_error());
print("<h1>AFTER</h1>");
$q =mysql_query("select *from classes ");
while($row=mysql_fetch_array($q)){
print("$row['class_id'] - $row['class_level'] - row[$class_name] <br/>");
}
?>
You dnt need to write any single php line to do what you are actually want to do.
Ok i have updated the code try this way. First it will get data & show . Secondly ,it will update the data .finally,display the data. Try this way hope you can find your problem.
I solved this by simply doing something like this:
mysql_query("UPDATE classes SET class_level = 2 WHERE class_level = 1");
mysql_query("UPDATE classes SET class_level = 3 WHERE class_level = 2");
mysql_query("UPDATE classes SET class_level = 4 WHERE class_level = 3");
I have just those three classes so it gets the job done.
It isn't the way I wanted to go with, but it works. The bug was really odd and I'd rather not go back to it. I hope this helps someone though.
P.S. How could I possibly not think about that in the first place XD
I am tring to re-index a table with a function inside php/joomla ...
it does nothing. I can not make the entire set of slq commands wihtin one string either.
function ReNumberID($TABLENAME ,$COLUMNNAME) {
$sql = "set #a=0; " ;
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$db->setQuery($sql);
$db->execute();
$sql2 = "UPDATE `".$TABLENAME."` SET `".$COLUMNNAME."`=(#a:=#a+1); " ;
$db->setQuery($sql2);
$db->execute();
$sql3 = "SELECT * FROM `".$TABLENAME."` WHERE 1" ;
$db->setQuery($sql3);
$db->execute();
$newindexnumber = $db->getNumRows();
$newindexnumber++ ;
$sql4 = "ALTER TABLE `".$TABLENAME."` auto_increment = ".$newindexnumber." ;";
$db->setQuery($sql4);
$db->execute();
}
First of all, I'd recommend that you check each of your queries to see whether they succeed, and how many rows are affected. You are currently calling execute() and trusting that something actually happened. Who knows if you spelled a column name wrong or got a privilege error or something.
Second, you should make sure you are applying the update in order from the current low id number ascending. Because you could easily cause an error. Here's an example:
mysql> create table bar (id int primary key, x int) engine=myisam;
mysql> insert into bar (id) values (1), (5), (7), (2);
mysql> select * from bar;
+----+------+
| id | x |
+----+------+
| 1 | NULL |
| 5 | NULL |
| 7 | NULL |
| 2 | NULL |
+----+------+
mysql> set #a := 0;
mysql> update bar set id = (#a:=#a+1);
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
The reason is that id 1 is set to 1, then id 5 is set to 2, which conflicts with the fourth row.
mysql> update bar set id = (#a:=#a+1) order by id;
Query OK, 3 rows affected (0.00 sec)
mysql> select * from bar;
+----+------+
| id | x |
+----+------+
| 1 | NULL |
| 3 | NULL |
| 4 | NULL |
| 2 | NULL |
+----+------+
That at least worked. I never would have known about the duplicate key error if I hadn't checked for errors.
By the way, you can just set ALTER TABLE ... AUTO_INCREMENT=0 and the table will automatically adjust it to the max(id)+1.
But here's my stronger recommendation:
You don't need to renumber the auto-increment key. The primary key must be unique, but it's not required to be consecutive.
It's normal to have gaps. This happens when an INSERT fails, or you DELETE a row, or if you INSERT but then roll back.
You can get problems if you renumber the primary key of rows throughout your table. For instance, if your application communicated outside the database, external systems may have a record of an entity by the old id.
Example: abusive user 1234 harasses other users and gets himself banned and his account shut down and deleted. Then you renumber all the id's and allocate 1234 to another new user. The next day, a lawyers shows up and serves you with a civil complaint against user 1234. The poor new user is blamed for something someone else did.
I wrote about this in my book, SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming. The chapter about this mistake is called "Pseudokey Neat-Freak."