I'm trying to figure out how I can insert a NULL value into a column of newly inserted row.
I'm working on "post icons" which will display a small icon for the thread on the thread list. The icons use RADIO buttons in the form. By default it is set to No Icon. I was wondering what to do for the value of that radio button to make it null? I tried setting value as NULL but it just inserts the word "NULL" into the database.
$thread_sql = "
INSERT INTO forum_threads (
user_id,
forum_id,
thread_postdate,
thread_lastpost,
thread_title,
thread_description,
thread_icon
) VALUES (
'$_SESSION[user_id]',
'$_GET[f]',
'$date',
'$date',
'$_POST[topictitle]',
'$_POST[topicdescription]',
'$_POST[posticon]'
)
";
$thread_query = #mysqli_query ($db_connect, $thread_sql);
With MySQL:
insert into your_table (nulled_column) values (null);
If you are getting a 'NULL' literal instead of a null value, it's probably because you are not issuing the right command from your client (PHP, C#, Java program). You will need to share the code you are using for your insertion in order to get more help.
UPDATE:
According to your recently edited question, just get rid of the '' when you are inserting NULL values. If you use '', then you'll get 'NULL' literals inserted as you mentioned.
I would also suggest you use PreparedStatements in MySQL in order to avoid SQL injection attacks.
Just do something like this (PDO):
$stmt = $db->prepare('INSERT INTO foo(bar) values (?);');
$stmt->execute(array($value=='NULL'? NULL,$value));
Or with mysql:
mysql_query('INSERT INTO foo(bar)
values ('.($value=='NULL'? 'NULL',"'".mysql_real_escape_string($value)."'").')';
This works. Had to use an IF
if (isset($_POST['submit'])) {
$thread_sql = "
INSERT INTO forum_threads (
user_id,
forum_id,
thread_postdate,
thread_lastpost,
thread_title,
thread_description,
thread_icon
) VALUES (
'$_SESSION[user_id]',
'$_GET[f]',
'$date',
'$date',
'$_POST[topictitle]',
'$_POST[topicdescription]',
IF('$_POST[posticon]'='NULL',NULL,'$_POST[posticon]')
)
";
$thread_query = #mysqli_query ($db_connect, $thread_sql);
Related
I have a problem regarding SQL Query. I have 3 Insert queries in my code.
the first query is with auto-increment ID.
INSERT INTO master_tbl
The second Insert will get the ID from 1st query using LAST_INSERT_ID()function.
INSERT INTO process (id_ref, process_id, hot_cold, temp)
VALUES (LAST_INSERT_ID(), '4', '-', '12')
My problem is, I have third query which needed to use the ID generated in the 1st query as its id_ref also.
When I use the LAST_INSERT_ID(), the ID it gets was the ID of the second query.
Any suggestions on how can I still get the ID in the 1st query to use on 3rd?
You can declare the variable and store the first queries id in that variable and then use it wherever you want.
After first query as you mentioned you are using the separate queries you can try using select to set the `Last insert id` into the variable and then use that variable as below,
select #valuetoUse := LAST_INSERT_ID()
Or Other way is use select the to get the value in your code and then pass that value to insert as all other values. For getting value you can directly fire select
SELECT LAST_INSERT_ID()
then in second query
INSERT INTO process (id_ref, process_id, hot_cold, temp)
VALUES (valuetoUse , '4', '-', '12')
then again in the third query
INSERT INTO thirdtable (id_ref, process_id, hot_cold, temp)
VALUES (valuetoUse , '4', '-', '12')
For more info on how to use user defined variables see here.
Functionality is same as told by #Coder of Code But with PHP
Try This
Create Connection
$conn = new mysqli($servername, $username, $password, $dbname);
First Insert into Table 1
INSERT INTO master_tbl
Then do
$sql = "SELECT MAX(id) as id from master_tbl";
$result = $conn->query($sql);
$row = $result->fetch_array(MYSQLI_NUM);
$latest_id=$row[0];
$sql = "INSERT INTO process (id_ref, process_id, hot_cold, temp)
VALUES ($latest_id,'4','-','12')";
if ($conn->query($sql) === TRUE)
{
echo "New record created successfully";
}
$sql = "INSERT INTO table3 (id_ref , columns list)
VALUES ($latest_id,other fields)";
if ($conn->query($sql) === TRUE)
{
echo "New record created successfully";
}
I have a query which is behaving strange...
Firstly, here is a query to get all PMs whether or not they've been read or deleted for the user ID 1:
SELECT * FROM `pms` WHERE `toid` = '1'
This returns 3 rows as expected. Next, let's see if I can get only unread messages for this user:
SELECT * FROM `pms` WHERE `toid` = '1' AND `read` = '0'
This returns 2 rows as expected. Let's see if I can get any read and unread messages which have been binned:
SELECT * FROM `pms` WHERE `toid` = '1' AND `binned` = '0'
This returns 2 rows as expected.
The query which I need to run is getting all unread and not binned messages for a specified user id. To do this, I am doing this:
SELECT * FROM `pms` WHERE `toid` = '1' AND `read` = '0' AND `binned` = '0'
However, it should be returning 1 row as I know in the database there is a message with toid as 1, read as 0 and binned as 0 but for some reason this query above is returning 0 rows...
Why is this?
UPDATE
Here is a screenshot of my table structure as seen in Sequel Pro:
Here is a screenshot of the data inside the table as seen in Sequel Pro:
As you can see there is definitely 1 record with toid as 1, read as 0 and binned as 0.
UPDATE 2
The reason these are ENUM is because I'm wishing to store a boolean value in MySQL. I do this by enforcing the column to be either a '1' or a '0' and making it default to '0' as well. If anyone has a better way of storing boolean values in MySQL then I'd love to learn.
Secondly, here is my PHP function inside of my User.class.php file which is getting the unread count using this SQL. This function is returning 0 when it should be returning 1. The $this->getUserId() is returning 1 as that is the current user I am using:
public function getUnreadCount()
{
global $database;
$sql = "SELECT * FROM `pms` WHERE `toid` = '".$this->getUserID()."' AND `read` = '0' AND 'binned' = '0'";
$query = $database->query($sql);
$count = $database->count($query);
return $count;
}
Thanks for the help so far but I still cannot work out why this isn't working. I'm using the read in the query adding backticks to prevent MySQL from using it as a keyword.
I bet its something really obvious I'm missing...
James, I think the problem might have to do with how the table was populated.
Since the "read" and "binned" columns' datatypes are ENUMs, you probably have to either set the correct default value ('0' or '1') or always provide a valid value when inserting a row into this table. In other words, you can't omit a value for either the "read" or "binned" columns when inserting a "pms"-row.
In other words, if your "pms" table is set up as follows, without defaults:
create table pms (
toid int,
`read` ENUM('0','1') ,
binned ENUM('0','1')
);
then you have to insert fully specified row-values like so:
insert into pms (toid, `read`, binned) values
(1, '0', '0'),
(1, '0', '1'),
(1, '1', '0'),
(1, '1', '1')
;
and avoid inserting sparse data like this:
insert into pms (toid) values (1);
insert into pms (toid, binned) values (1, '1');
insert into pms (toid, `read`) values (1, '1');
insert into pms (toid, `read`, binned) values (1, '1', '1');
Providing the correct default enum-value for those columns would also solve this issue:
create table pms (
toid int,
`read` ENUM('0','1') default '0',
binned ENUM('0','1') default '0'
);
I've set up a sqlfiddle to illustrate.
if your columns are integers try doing this
SELECT * FROM `pms` WHERE `toid` = 1 AND `read` = 0 AND `binned` = 0
EDIT:
it should be your columns to be integers like that in this demo.
SQLFIDDLE DEMO
or to be enum with values as strings like here
SELECT * FROM `pms`
WHERE `toid` = 1 AND `read` = '0' AND `binned` = '0'
sqllfiddle demo
Try to test if you have set your variables correctly. I suggest by testing if you get the right results when querying for just one variable.:
SELECT * FROM `pms` WHERE `toid` = '1'; -- 3;
SELECT * FROM `pms` WHERE `read` = '0'; -- 4;
SELECT * FROM `pms` WHERE `binned` = '0'; -- 4;
Classic mistakes would be that you have used integer values instead of string (ENUM) values or have substituted the zero for an null.
SQL FIDDLE DEMO
Wow haha I've just found why its not been returning the rows.
I'd mistakenly used single quotes instead of backticks in my PHP implementation of the SQL query...
So my query was actually:
$sql = "SELECT * FROM `pms` WHERE `toid` = '".$this->getUserID()."' AND `read` = '0' AND 'binned' = '0'";
When it should've been:
$sql = "SELECT * FROM `pms` WHERE `toid` = '".$this->getUserID()."' AND `read` = '0' AND `binned` = '0'";`
As you can see, near the end of the query for binned I had mistakenly used single quotes.
Can you believe it was that simple?
Just out of interest, how do you think I should be storing boolean values in MySQL?
I'm using $this->db->update(); to create an update query that adds the value stored in a variable, $amount, to the value in a column, count. My function call currently looks like this:
$data = array('count' => 'count + '.$amount);
$this->db->where('id', $item_id);
$this->db->update('items', $data);
However, this generates the following broken SQL:
UPDATE `items` SET `count` = 'count + 2' WHERE `id` = '2'
Is there a way to generate the SET clause without the quotes around count + 2?
Thanks, Maxime Morin, for putting me on the right track. According to the CodeIgniter Documentation, you can create a "set" clause without quotes by setting the optional $escape parameter to FALSE. Thus, the solution to my problem was:
$this->db->set("count", "count + $amount", FALSE);
$this->db->where("id", $item_id);
$this->db->update("items", $data);
Here's the work-around I used until I found my accepted solution
$query = $this->db->query("UPDATE `items` SET `count` = `count` + $amount WHERE `id` = $item_id");
In my table I have an userID that is auto-incremented. In the same row I have an idHash. Is it possible to generate the idHash (simply an MD5 sum) from it directly with the same INSERT statement so that I don't have to SELECT the id, and then UPDATE the idHash again?
Problem is: I do not know the userID before it is being generated (auto-incremented) by MySQL.
Thanks
Frank
PS: I'm using PHP.
PPS: This question is all about a SINGLE INSERT. I know that I can use PHP or other languages to manually select the data and then update it.
I don't believe you can do it within a single INSERT statement.
What you probably could do is use an INSERT trigger, that both determines the new ID, hashes it, and then updates the record.
One solution I can recommend is using the last insert ID instead of re-querying the table. Here is a simplified example:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "INSERT INTO users VALUES (....)";
$mysqli->query($query);
$newUserID = $mysqli->insert_id;
$query = "UPDATE users SET idHash = MD5(userID) WHERE userID = $newUserID";
$mysqli->query($query);
/* close connection */
$mysqli->close();
?>
AFAIK there's no "secure" way for doing this in the same query if you're using auto_increment.
However, if rows are never deleted in your table, you can use this little trick :
insert into mytable (col1, col2, col3, idhash)
values ('', '', '', md5(select max(id) from mytable))
I don't understand why you need to hash the id though, why not use the id directly ?
This seems to work for me:
CREATE TABLE tbl (id INT PRIMARY KEY AUTO_INCREMENT, idHash TEXT);
INSERT INTO tbl (idHash) VALUES (MD5(LAST_INSERT_ID() + 1));
SELECT *, MD5(id) FROM tbl;
Note this will only work on single-row inserts as LAST_INSERT_ID returns the insert ID of the first row inserted.
Performing MD5(column_name) on an auto_increment value does not work as the value has not been generated yet, so it is essentially calling MD5(0).
PHP snippet
<?
$tablename = "tablename";
$next_increment = 0;
$qShowStatus = "SHOW TABLE STATUS LIKE '$tablename'";
$qShowStatusResult = mysql_query($qShowStatus) or die ( "Query failed: " . mysql_error() . "<br/>" . $qShowStatus );
$row = mysql_fetch_assoc($qShowStatusResult);
$next_increment = $row['Auto_increment'];
echo "next increment number: [$next_increment]";
?>
This will get you the next auto-increment and then you can use this in your insert.
Note: This is not perfect (Your method is imperfect as you will effectively have 2 primary keys)
From: http://blog.jamiedoris.com/geek/560/
I have two tables with identical structure except for one column... Table 2 has an additional column in which I would insert the CURRENT_DATE()
I would like to copy all the values from table1 to table2.
If I use
INSERT INTO dues_storage SELECT * FROM dues WHERE id=5;
it throws an error pointing to the difference in the number of columns.
I have two questions:
How do I get around this?
How do I add the value for the additional date column (CURRENT_DATE()) in table2 within this same statement?
To refine the answer from Zed, and to answer your comment:
INSERT INTO dues_storage
SELECT d.*, CURRENT_DATE()
FROM dues d
WHERE id = 5;
See T.J. Crowder's comment
The safest way to do it is to fully specify the columns both for insertion and extraction. There's no guarantee (to the application) that either of these will be the order you think they may be.
insert into dues_storage (f1, f2, f3, cd)
select f1, f2, f3, current_date() from dues where id = 5;
If you're worried about having to change many multiple PHP pages that do this (as you seem to indicate in the comment to another answer), this is ripe for a stored procedure. That way, all your PHP pages simply call the stored procedure with (for example) just the ID to copy and it controls the actual copy process. That way, there's only one place where you need to maintain the code, and, in my opinion, the DBMS is the right place to do it.
INSERT INTO dues_storage
SELECT field1, field2, ..., fieldN, CURRENT_DATE()
FROM dues
WHERE id = 5;
Hope this will help someone... Here's a little PHP script I wrote in case you need to copy some columns but not others, and/or the columns are not in the same order on both tables. As long as the columns are named the same, this will work. So if table A has [userid, handle, something] and tableB has [userID, handle, timestamp], then you'd "SELECT userID, handle, NOW() as timestamp FROM tableA", then get the result of that, and pass the result as the first parameter to this function ($z). $toTable is a string name for the table you're copying to, and $link_identifier is the db you're copying to. This is relatively fast for small sets of data. Not suggested that you try to move more than a few thousand rows at a time this way in a production setting. I use this primarily to back up data collected during a session when a user logs out, and then immediately clear the data from the live db to keep it slim.
function mysql_multirow_copy($z,$toTable,$link_identifier) {
$fields = "";
for ($i=0;$i<mysql_num_fields($z);$i++) {
if ($i>0) {
$fields .= ",";
}
$fields .= mysql_field_name($z,$i);
}
$q = "INSERT INTO $toTable ($fields) VALUES";
$c = 0;
mysql_data_seek($z,0); //critical reset in case $z has been parsed beforehand. !
while ($a = mysql_fetch_assoc($z)) {
foreach ($a as $key=>$as) {
$a[$key] = addslashes($as);
next ($a);
}
if ($c>0) {
$q .= ",";
}
$q .= "('".implode(array_values($a),"','")."')";
$c++;
}
$q .= ";";
$z = mysql_query($q,$link_identifier);
return ($q);
}
Alternatively, you can use Inner Queries to do so.
SQL> INSERT INTO <NEW_TABLE> SELECT * FROM CUSTOMERS WHERE ID IN (SELECT ID FROM <OLD_TABLE>);
Hope this helps!
SET #sql =
CONCAT( 'INSERT INTO <table_name> (',
(
SELECT GROUP_CONCAT( CONCAT('`',COLUMN_NAME,'`') )
FROM information_schema.columns
WHERE table_schema = <database_name>
AND table_name = <table_name>
AND column_name NOT IN ('id')
), ') SELECT ',
(
SELECT GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`'))
FROM information_schema.columns
WHERE table_schema = <database_name>
AND table_name = <table_source_name>
AND column_name NOT IN ('id')
),' from <table_source_name> WHERE <testcolumn> = <testvalue>' );
PREPARE stmt1 FROM #sql;
execute stmt1;
Of course replace <> values with real values, and watch your quotes.
Just wanted to add this little snippet which works beautifully for me.
INSERT INTO your_target_table
SELECT *
FROM your_rescource_table
WHERE id = 18;
And while I'm at it give a big shout out to Sequel Pro, if you're not using it I highly recommend downloading it...makes life so much easier