I recently started hosting my own site and mySQL db. Everything works fine, but whenever I do an insert or update to any of tables, it errors out if I do not call out each and every column. Is there a setting for the table or the DB that controls this? I never had to do this with my previous DB host.
Thanks.
There are several ways to write an INSERT query.
INSERT INTO tablename (col1, col2, ...) VALUES (val1, val2, ...)
INSERT INTO tablename (col1, col2, ...) SELECT ...
INSERT INTO tablename VALUES (val1, val2, ...)
INSERT INTO tablename SELECT ...
In the first two methods, you don't have to list all the columns, since you specify the columns to be filled in explicitly. The columns that aren't in the (col1, col2, ...) list will get their default values. The VALUES list or the SELECT query must return as many columns as you specified in the list.
In methods 3 and 4, MySQL requires the VALUES list or the SELECT query to return as many columns as the table contains, and they must be in the same order as the table definition. I can't find any setting that disables the column count check in these methods.
In methods 1 and 3, you can put the keyword DEFAULT in place of any of the column values to insert its default value.
If your server is in STRICT mode, you also have to explicitly set any columns that do not have a DEFAULT option in the schema. If it's not in strict mode, automatic defaults will be used.
It probably doesn't fail if you UPDATE the values of some, but not all, columns in particular rows.
When you create your table, you need to set a default value for each column which you may choose to omit in your INSERT statements.
Related
Part of my job requires that I insert hundreds of fields into a table each week, and I'm getting honestly tired of doing it by hand. SQL is not my forte, so I was wondering if there could be a way to do it semi-automatically?
The query I need to fulfill is:
insert into [table] ([c1][c2][c3][c4][c5][c6])
values([v1][v2][v3][v4][v5][v6]);
Only v1 and v2 need to change each loop, 3 to 6 are always the same value. Could I somehow make an array for the values of v1 and v2 and make it so the query repeats itself advancing through those arrays? Or something that would save me an hour of manually replacing hundreds of values?
Thanks!
MySQL supports a syntax for INSERT INTO ... SELECT ... queries, which may do everything you want in one query.
Example: assuming you have two columns which always get the same string value (col1 + col2) and two columns with values from somewhere else:
INSERT INTO target_table
(col1, col2, col3, col4)
SELECT 'foo', 'bar', id, price
FROM source_table WHERE created_at > '2022-01-01';
That would insert the two static values "foo" and "bar" for each row, plus the values from id and price in source_table.
I am working on redesigning of a legacy db and I have set new names to columns of old db. So, for instance, if olddb.oldtable under dbold has column descr, I have set it as description in new newdb.netable for column.
How can I mention individual columns in my query?
I am using MYSQL
Update: Both Databases are on different IP Addresses and I am using Navicat to transfer data.
You can try like this:
INSERT INTO newtable (col1, col2, ..., )
SELECT col1, col2, ..., FROM oldtable
By trying the above query you can insert the specific column. So for example if your newtable has a column as description and old table as descr then you can mention it like:
INSERT INTO newtable (col1, col2, `description`, ..., )
SELECT col1, col2, `descr` ,..., FROM oldtable
Also if the table column list is large and you want to copy all the columns and its data then you can simply use the wildcard charater * as:
INSERT INTO newtable
SELECT * FROM oldtable;
You can insert all columns at once without the need to mention the names using this:
INSERT INTO newtable (SELECT * FROM oldtable);
It will make an 1x1 match independently of column names.
If types don't match then will insert default values (not checked for all the type combination).
Note that column number must be the same on both tables otherwise an error like this will occur:
#1136 - Column count doesn't match value count at row 1
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);
I find that there are only after and instead of triggers in sql server. And it is illegal to modify the values in the inserted pesudo table. Then my problem occurs: If I want to check the data which is going to be inserted into my table, and when the data violates my constraints I should modify these values to default values, how to do it ? How about updateing the values after inserted ? However, if there's no primary key or colum which is unique in my table, how can I locate the row just inserted and then update it ?
Basically, with an INSTEAD OF INSERT trigger, you can achieve what you're looking for - just read out the data from the INSERTED pseudo table, modify it, and insert it into the table
So your trigger would look something like this:
CREATE TRIGGER YourTrigger ON dbo.YourTable
INSTEAD OF INSERT
AS
SET NOCOUNT ON
-- do the INSERT based on the INSERTED pseudo table, modify data as needed
INSERT INTO dbo.YourTable(Col1, Col2, ....., ColN)
SELECT
Col1, 2 * Col2, ....., N * ColN
FROM
INSERTED
Of course, you could also add e.g. checks in the form of WHERE clause to that SELECT .... FROM INSERTED statement to e.g. ignore certain rows - the possibilities are endless!
I normally found three ways of using MYSQL insert Command
INSERT INTO `table` (field1, field2, field3) VALUES ('value1', 'value2', 'value3');
or
INSERT INTO `table` VALUES ('value1', 'value2', 'value3');
or
INSERT INTO `table` SET `field1`='value1', `field2`='value2', `field3`='value3';
Is there any differences among these?
The first two are standard SQL; the third one is non-standard and specific to MySQL, derived from the standard syntax for UPDATE.
The difference between the first two is that one specifies the fields that you want to insert, which is more flexible because you can miss out fields if you're happy with them being set to NULL. Also specifying the fields means that the statement will still work if the table layout changes; if you don't specify the fields you're relying on the table never changing.
You are looking for differences in terms of what? In terms of usage, the first and third insert statements let you to set only those columns which you need whereas the second statement always tries to insert the values to all columns in order of table structure.
Only one difference, pretty obvious to me: the second one don't let you specify your own field set to insert.