MySQL REPLACE without all fields provided - mysql

I have mysql query to replace some records:
REPLACE INTO product_core
(id, title, description, category_id)
VALUES (2, 'new_title', 'new_description', 33)
Can I do the same, but not providing all needed values? Example:
REPLACE INTO product_core
(id, title, description, category_id)
VALUES (2, 'new_title', 'new_description') #no category_id
Got error wrong number of values here near
I want to bulk replace many records, but I do not want to query all fields before. In this example, I want to update category_id for some records, but not for all.
REPLACE INTO product_core
(id, title, description, category_id)
VALUES (2, 'new_title_2', 'new_description_2'), #no category_id
(3, 'new_title_3', 'new_description_3', 34) #with category_id
Is it real to do this? Replace some fields for one record and other fields for second record in one query.
Or if is it real to provide special variable meaning that some fields will be the same as before replace (category_id)?
VALUES (2, 'new_title_2', 'new_description_2', #category_id_same_as_before)

Can I do the same, but not providing all needed values? Example:
REPLACE INTO product_core (id, title, description, category_id) VALUES
(2, 'new_title', 'new_description') #no category_id
Yes, the correct query is:
REPLACE INTO product_core
(id, title, description)
VALUES (2, 'new_title', 'new_description') #no category_id
EDIT: As Tom commented below the above might be misleading as for the omitted columns default values will be used, not the ones set for the record which is being replaced.
Is it real to do this? Replace some fields for one record and other fields for second record in one query.
It's not possible in MySQL. The column list is common for all the values sets.
Or if is it real to provide special variable meaning that some fields
will be the same as before replace (category_id)?
It's perhaps possible, but not straightforward and not in all MySQL versions. In the docs they say: "You cannot refer to values from the current row and use them in the new row".
In MySQL > 8.0.19 perhaps VALUES(ROW) can help. Or you can perhaps write you own UDF which does it.

You can't omit these columns from a REPLACE command, unless it is the default value for the column.
According to the documentation:
Any missing columns are set to their default values. [...] You cannot refer to values from the current row and use them in the new row.
It may be better to use a standard UPDATE command instead, which can reference the current column value.

Related

MySQL INSERT INTO putting every field at null or 0?

Still learning sql, but I'm not understanding how all the data I'm putting in my tables are set to 0 or NULL ?
You need to split up the columns and VALUES into separate statements (also the id should get added automatically since you have it as an identity, so you don't need to explicitly use it).
Try this:
INSERT INTO users (email, name, forename, pwhash)
VALUES ('mail', 'name', 'blaa', 'befbf');
You can use this to insert multiple values at once if you need to
INSERT INTO users (email, name, forename, pwhash) VALUES
('mail', 'name', 'blaa', 'befbf'),
('mail2', 'another name', 'blaa2', 'befbf123'),
('mail3', '1 more name', 'blaa3', 'befbf456'),
('mail4', 'one final name', 'blaa4', 'befbf789');
(Etc.)
The correct command:
insert into users (email, name, forename, pwhash) values ('mail', name, 'blaa', 'befbf')
You are getting null as sql format is wrong. Id is 1 because that is auto incremented as defined by you. But other columns are null or 0.
Try
INSERT INTO users (email, name, forename, pwdssh)
VALUES ('email', 'name', 'blaa', 'befbf');
id should be autoincremented as a primary key so no need to specify it. If you want to do it inline as you have attempted, I don't think a hyphen is the right syntax, it would be an equals, as in email='email'
Explicitly listing the column names like this means you can specify the Column names followed by VALUES in any order. You could also miss out the column names and just say:
INSERT INTO users
VALUES ('email', 'name', 'blaa', 'befbf');
Where the values are listed in the order that the columns are defined. Doing it this way, the order becomes important.
You may find this quite useful
You don't need to specify "field={value}", just put in the values in the proper order.
INSERT INTO Table (Field1,..., FieldN)
VALUES ('Value1',....,'ValueN');
https://www.w3schools.com/mysql/mysql_insert.asp

mysql insert into query not working

The query is pasted below. Basically I have a users table, and I want to create 1 record for every entry in the users table in the controls table. I need the user_id from the users table when I'm inserting into the controls table. I get a syntax error when I try and run the query below. I've looked at a bunch of other MySQL examples that do something similar but get the same error. I'm running MySQL 5.6.21.
This will end up being a Rails migration, so I am also amenable to using ActiveRecord, but haven't really figure out how to do something like this with it.
INSERT into controls (default, whitelist, user_id, admin_status, system_status, created_at, updated_at) values (0, 0, (SELECT id FROM users), 'inactive', 'sleeping', DATE(NOW), DATE(NOW));
I believe your problem is that you're trying to mix a SELECT with VALUES (which is used for inputting literal values).
Try:
INSERT into controls
(`default`, whitelist, user_id, admin_status, system_status, created_at, updated_at)
SELECT 0, 0, id, 'inactive', 'sleeping', NOW(), NOW() FROM users;
DEFAULT is a MySQL reserved word. You may need to enclose that column name in backticks.
INSERT into controls (`default`, whitelist,
^ ^
Those are backtick characters (key to the left of the 1/! key), not single quotes.
The error message from MySQL should indicate where in the SQL text MySQL thinks the problem is.
If this is a new table, strongly consider using a column name that is not a MySQL reserved word.
Reference: https://dev.mysql.com/doc/refman/5.5/en/keywords.html
The SELECT in the context of the VALUES clause needs to return at most one row. You'd need to ensure that SELECT doesn't return more than one row, e.g. add a LIMIT 1 clause. But
Reading your question again... if you want to insert a row in the new controls table for every row that's in users table, don't use the VALUES keyword. Use the INSERT ... SELECT form of the INSERT statement.
Reference: http://dev.mysql.com/doc/refman/5.5/en/insert-select.html

mysql prepared statement set default value for insert

I've got a table with two columns that links a row id from one table to a row id of another, basically I need to be able to insert multiple rows on this table where one column is a fixed value for the insert and the other changes. The insert is done in php using prepared statements and there is an unknown number of rows to be inserted (I've solved this part using call_user_func_array).
Here is an example of what I need to do:
example_table (column_A, column_B)
The insert:
INSERT INTO example_table (column_A, column_B) VALUES(a, b), VALUES(a, c), VALUES(a, d);
Translated to prepared statement:
INSERT INTO example_table (column_A, column_B) VALUES(?, ?), VALUES(?, ?), VALUES(?, ?);
values on bind_param:
('ssssss', 'a', 'b', 'a', 'c', 'a', 'd')
As you can see the repetition of 'a'. is there a way to store 'a' and default it to column_A for the current insert only?
example of what i would like to do on bind_param:
('ssss', 'a', 'b', 'c', 'd')
Where 'a' above is used for column_A on all rows inserted (3 rows in the example). Any help would be appreciated
No, it's not possible to "alias" a value multiple times. Each placeholder is unique and must be bound to exactly one value. (It is not even possible to do this reliably with named parameters in PDO.)
If automatically building SQL dynamically (with placeholders) and associated data array, then there is no issue with such "duplication" as it's already handled by the generator.
If transactions are correctly used - which they should be anyway! - then simply calling INSERT in a loop, once for each pair, will likely have similar performance. This avoids needing to build the dynamic SQL (with placeholders) itself, but can increase latency as each command needs to round-trip to the SQL server.
If finding a bunch of such repetition, it might be time to use a Data Access Layer to hind such details; write it, test it, move onto something interesting.
In response to the comment about using SQL variables:
While the following will not improve performance, excepting possibly for ridiculously large values of #v, and makes the code more difficult to understand - it ought to be possible to use user-defined variables in a single insert statement. For instance, consider:
INSERT INTO t VALUES (#v := ?, ?), (#v, ?), (#v, ?)
This is "valid" in MySQL (and is also MySQL-specific), where the placeholders are valid expressions; if it works will depend on how/if such a binding is allowed in a prepared statement.
You may try making a temporary table:
$query='CREATE TEMPORARY TABLE tempTable(column_B VARCHAR(50));';
$mysqli->query($query);
then insert unique values of column_B into this table
and finally
$query="INSERT INTO example_table (column_A, column_B) select $a , column_B from tempTable";
$mysqli->query($query);

Adding only one value to the table in sql

I have a table named student which consists of (rollno, name, sem, branch)
If I want to INSERT only one value (i.e only name has to be entered) what is the query?
To insert values into specific columns, you first have to specify which columns you want to populate. The query would look like this:
INSERT INTO your_table_name (your_column_name)
VALUES (the_value);
To insert values into more than one column, separate the column names with a comma and insert the values in the same order you added the column names:
INSERT INTO your_table_name (your_column_name_01, your_column_name_02)
VALUES (the_value_01, the_value_02);
If you are unsure, have a look at W3Schools.com. They usually have explanations with examples.
insert into student(name) values("The name you wan to insert");
Be careful not to forget to insert the primary key.
First, if the table is all empty, just wanna make the column 'name' with values, it is easy to use INSERT INTO. https://www.w3schools.com/sql/sql_insert.asp.
`INSERT INTO TABLE_NAME (COLUMN_NAME) VALUES ("the values")`
Second, if the table is already with some values inside, and only wanna insert some values for one column, use UPDATE. https://www.w3schools.com/sql/sql_update.asp
UPDATE table_name SET column1 = value1 WHERE condition;
insert into student (name)
select 'some name'
or
insert into student (name)
values ('some name')
Following works if other columns accept null or do have default value:
INSERT INTO Student (name) VALUES('Jack');
Further details can be found from the Reference Manual:: 13.2.5 INSERT Syntax.
Execute this query, if you want the rest of columns as "#", do insert # inside the single quote which is left blank in query.
Also, there is no need of defining column name in the query.
insert into student values('','your name','','');
Thanks...

Is this a Efficient way to query relational tables on MySQL?

I'm dealing with a relational table and I've been wondering if there's a way to lower the number of queries I need to make when inserting data to the tables..
Here are the queries I currently use:
I insert the "main" values.
INSERT INTO products
(title, description, status, url)
VALUES
('some title', 'description of doom', 1, 'some-title');
We make it insert the value only if it doesn't exist already.
INSERT IGNORE INTO values
(value)
VALUES
('example value');
Since I'm not sure if the query was actually inserted, I get the id..
SELECT id
FROM
values
WHERE
value = 'example value';
Where "?" is the ID I got from the last query.
INSERT INTO link
( id_product, id_catalog, id_value )
VALUES
( 33, 1, ? );
This means that each extra value I need to add will cost 3 queries. So my question is: Is there a more efficient way to do this?
You can do this to at least drop one of the queries:
INSERT INTO link
( id_product, id_catalog, id_value )
VALUES
( 33, 1, (SELECT id
FROM values
WHERE value = 'example value') );
I basically am replacing the '?' with a sub select of the second query to get the id.
"Is there a more efficient way to do this?"
No. Not really. Creating three things takes three inserts.
You should be able to tell whether the insert succeeded with the ROW___COUNT() function from inside MySQL. If calling from another language (e.g. PHP), the mysql_query or equivalent function will return the row count.
You could use an INSERT INTO ... ON DUPLICATE KEY UPDATE statement.
This does, however, require that the primary key be one of the values for the insert, so it doesn't work on tables with an auto-increment.