create table MYTABLE
{
MY_DATE int NOT NULL AUTO_INCREMENT,
NAME varchar(255) NOT NULL UNIQUE
};
INSERT INTO MYTABLE(NAME)values(jessica);
Why do I get this error?
ERROR 1364 (HY000): Field 'MY_DATE' doesn't have a default value
From the docs:
There can be only one AUTO_INCREMENT column per table, it must be indexed, and it cannot have a DEFAULT value.
I think you'll find that, because you're not indexing MY_DATE, it may be silently ignoring the AUTO_INCREMENT option (I can't guarantee that, it's just supposition, but the note in the documentation is still relevant).
All the samples I can see on the AUTO_INCREMENT stuff have (the equivalent of):
PRIMARY KEY (MY_DATE)
Alternatively, you may be running in strict SQL mode. All the docs I've seen seem to indicate that, in the absence of a specific default, unlisted columns in an insert will get NULL if they're nullable, or the type default if the not nullable:
If you are not running in strict SQL mode, any column not explicitly given a value is set to its default (explicit or implicit) value. For example, if you specify a column list that does not name all the columns in the table, unnamed columns are set to their default values. Default value assignment is described in Section 10.1.4, “Data Type Default Values”.
For an integral type, that default is 0 (which should kick in the auto increment anyway).
However, in strict SQL mode (from here):
an error occurs for transactional tables and the statement is rolled back.
Which version of MySQL are you using?
I'm using 5.1.41 community and the create table SQL gives
SQL Error (1075): Incorrect table definition; there can be only one auto column and it must be defined as a key
Next correct it to the below
create table MYTABLE
(
MY_DATE int NOT NULL AUTO_INCREMENT primary key,
NAME varchar(255) NOT NULL UNIQUE
);
The insert statement
INSERT INTO MYTABLE(NAME)values(jessica);
Results in
SQL Error (1054): Unknown column 'jessica' in 'field list'
Because it has not been quoted. Once that is corrected to the below:
INSERT INTO MYTABLE(NAME)values('jessica');
It works. You don't have to supply any values for the auto_increment primary key, but you can.
Now, let's talk about MySQL quirks. You can optionally include the column, and set a value of NULL. You can also give it a SPECIFIC value and MySQL will happily use it, even if it is defined as auto_increment.
INSERT INTO MYTABLE(my_date,NAME)values(41,'jessica2');
INSERT INTO MYTABLE(my_date,NAME)values(null,'jessica3');
INSERT INTO MYTABLE(NAME)values('jessica4');
DELETE FROM MYTABLE where my_date=43;
INSERT INTO MYTABLE(my_date,NAME)values(3,'jessica5');
INSERT INTO MYTABLE(NAME)values('jessica?');
select * from mytable;
When you set the number specifically to 41, the next number becomes 42, then 43. It allows us to specifically use 3, even then though 43 was deleted before we used the specific number 3, the next value is still 44.
Output
MY_DATE NAME
41 jessica2
42 jessica3
3 jessica5
44 jessica?
You don't supply a value for MY_DATE in your INSERT statement, and there is no default value defined. (And as paxdiablo points out, there can't be a default value defined in this situation.) Unintuitively, you do need to give a value for MY_DATE, and if that value is zero or null then MySQL will assign the next autoincrement value. Like this:
insert into mytable values(null,'jessica');
Edit this file /etc/mysql/mysql.conf.d/mysqld.cnf
add the below statement under [mysqld]
sql_mode =
This is working perfectly for me.
Related
I am getting an insert error:
Cannot insert the value NULL into column 'id', table 'db.dbo.table';
column does not allow nulls. INSERT fails
.
I have checked the data and the column I am inserting into 'id' does not have any nulls.
Any suggestions?
The error
column does not allow nulls
is happening because you are trying to insert data which has NULL for the column id, for at least one record which you are trying to insert. It has nothing to do with the state of the column before you attempted the insert. Check the source of your insertion data and remove/replace the NULL values, or alter the id column to accept NULL.
When looking at your SQL table design, scroll through "Column Properties" to "Identity Specification". In that drop-down, change "(Is Identity)" to Yes. This setting tells the table to auto-increment the ID field.
Null is not a particular value, but rather, an indication that you don't know the value for this field. It means, "VALUE UNKNOWN". If the field is not NULLable (i.e., if "UNKNOWN" is not permissible), then the INSERT will not be allowed. This is particularly true for an ID column, which might be INDEXed — perhaps even the PRIMARY KEY of the table. Some databases do not allow NULL in INDEXes (particularly primary indexes) at all.
I am using postgreSQL. I have a column that:
NOT NULL
However when I want to insert a row with an empty string as like:
''
it doesn't give me an error and accepts. How can I check insert value should be not empty? (Neither empty nor null)
PS: My column defined as:
"ads" character varying(60) NOT NULL
Add a constraint to column definition. For example something like:
ads character varying(60) NOT NULL CHECK (ads <> '')
For more, see http://www.postgresql.org/docs/current/static/ddl-constraints.html
Found in the current documentation of postgreSQL you can do the following to achieve what you want:
CREATE TABLE distributors (
did integer PRIMARY KEY DEFAULT nextval('serial'),
name varchar(40) NOT NULL CHECK (name <> '')
);
From the documentation:
CHECK ( expression )
The CHECK clause specifies an expression producing a Boolean result
which new or updated rows must satisfy for an insert or update
operation to succeed. Expressions evaluating to TRUE or UNKNOWN
succeed. Should any row of an insert or update operation produce a
FALSE result an error exception is raised and the insert or update
does not alter the database. A check constraint specified as a column
constraint should reference that column's value only, while an
expression appearing in a table constraint may reference multiple
columns.
Currently, CHECK expressions cannot contain subqueries nor refer to variables other than columns of the current row.
Consider the following table:
create table language (
id integer generated always as identity (START WITH 1, INCREMENT BY 1),
name long varchar,
constraint language_pk primary key (id)
);
To which I'd insert an entry this way.
insert into language(name) values ('value');
How does one know what value for id was created? Just doing a SELECT using the name field is not valid, because there can be duplicate entries.
Through plain SQL:
insert into language(name) values ('value');
SELECT IDENTITY_VAL_LOCAL();
See the manual for details: http://db.apache.org/derby/docs/10.7/ref/rrefidentityvallocal.html
When doing this from a Java class (through JDBC) you can use getGeneratedKeys() after "requesting" them with the approriate executeUpdate() method.
You use the JDBC method
st.execute(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet keys = st.getGeneratedKeys();
as documented in the Derby manual.
See also Javadocs: DatabaseMetaData#supportsGetGeneratedKeys()
and Statement#getGeneratedKeys()
You could execute this statement (NB, not 100% sure this syntax is correct for Derby:
SELECT TOP 1 id FROM language ORDER BY id DESC
To find the last inserted ID.
Alternative for Derby:
SELECT MAX(id) from language
Obviously this will only be accurate if no other inserts (including inserts by other users) have happened between your insert and select.
See also this discussion:
I've declared the following table for use by audit triggers:
CREATE TABLE audit_transaction_ids (id IDENTITY PRIMARY KEY, uuid VARCHAR UNIQUE NOT NULL, `time` TIMESTAMP NOT NULL);
The trigger will get invoked multiple times in the same transaction.
The first time the trigger is invoked, I want it to insert a new
row with the current TRANSACTION_ID() and time.
The subsequent times the trigger is invoked, I want it to return
the existing "id" (I invoke Statement.getGeneratedKeys() to that end)
without altering "uuid" or "time".
The current schema seems to have two problems.
When I invoke MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES(TRANSACTION_ID(), NOW()) I get: org.h2.jdbc.JdbcSQLException: Column "ID" contains null values; SQL
statement: MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES
(TRANSACTION_ID(), NOW()) [90081-155]
I suspect that invoking MERGE on an existing row will alter "time".
How do I fix both these problems?
MERGE is analogous to java.util.Map.put(key, value): it will insert the row if it doesn't exist, and update the row if it does. That being said, you can still merge into a table containing AUTO_INCREMENT columns so long as you use another column as the key.
Given customer[id identity, email varchar(30), count int] you could merge into customer(id, email, count) key(email) values((select max(id) from customer c2 where c2.email='test#acme.com'), 'test#acme.com', 10). Meaning, re-use the id if a record exists, use null otherwise.
See also https://stackoverflow.com/a/18819879/14731 for a portable way to insert-or-update depending on whether a row already exists.
1. MERGE INTO audit_transaction_ids (uuid, time) KEY(id) VALUES(TRANSACTION_ID(), NOW())
If you just want to insert a new row, use:
INSERT INTO audit_transaction_ids (uuid, time) VALUES(TRANSACTION_ID(), NOW())
MERGE without setting the value for the column ID doesn't make sense if ID is used as the key, because that way it could never (even in theory) update an existing rows. What you could do is using another key column (in the case above there is no column that could be used). See the documentation for MERGE for details.
2. Invoking MERGE on an existing row will alter "time"
I'm not sure if you talk about the fact that the value of the column 'time' is altered. This is the expected behavior if you use MERGE ... VALUES(.., NOW()), because the MERGE statement is supposed to update that column.
Or maybe you mean that older versions of H2 returned different values within the same transaction (unlike most other databases, which return the same value within the same transaction). This is true, however with H2 version 1.3.155 (2011-05-27) and later, this incompatibility is fixed. See also the change log: "CURRENT_TIMESTAMP() and so on now return the same value within a transaction." It looks like this is not the problem in your case, because you do seem to use version 1.3.155 (the error message [90081-155] includes the build / version number).
Short Answer:
MERGE INTO AUDIT_TRANSACTION_IDS (uuid, time) KEY (uuid, time)
VALUES (TRANSACTION_ID(), NOW());
little performance tip: make sure uuid is indexed
Long Answer:
MERGE is basically an UPDATE which INSERTs when no record found to be updated.
Wikipedia gives a more concise, standardized syntax of
MERGE but you have to supply your own update and insert.
(Whether this will be supported in H2 or not is not mine to answer)
So how do you update a record using MERGE in H2? You define a key to be looked up for, if it is found you update the row (with column names you supply, and you can define DEFAULT here, to reset your columns to its defaults), otherwise you insert the row.
Now what is Null? Null means unknown, not found, undefined, anything which is not what you're looking for.
That is why Null works as key to be looked up for. Because it means the record is not found.
MERGE INTO table1 (id, col1, col2)
KEY(id) VALUES (Null, 1, 2)
Null has a value. it IS a value.
Now let's see your SQL.
MERGE INTO table1 (id, col1, col2)
KEY(id) VALUES (DEFAULT, 1, 2)
What is that implying? To me, it says
I have this [DEFAULT, 1, 2], find me a DEFAULT in column id,
then update col1 to 1, col2 to 2, if found.
otherwise, insert default to id, 1 to col1, 2 to col2.
See what I emphasized there? What does that even mean? What is DEFAULT? How do you compare DEFAULT to id?
DEFAULT is just a keyword.
You can do stuff like,
MERGE INTO table1 (id, col1,
timeStampCol) KEY(id) VALUES (Null, 1,
DEFAULT)
but don't put DEFAULT in the key column.
I have the following hsqldb table, in which I map UUIDs to auto incremented IDs:
SHORT_ID (BIG INT, PK, auto incremented) | UUID (VARCHAR, unique)
Create command:
CREATE TABLE mytable (SHORT_ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, UUID VARCHAR(36) UNIQUE)
In order to add new pairs concurrently, I want to use the atomic MERGE INTO statement. So my (prepared) statement looks like this:
MERGE INTO mytable USING (VALUES(CAST(? AS VARCHAR(36)))) AS v(x) ON mytable.UUID = v.x WHEN NOT MATCHED THEN INSERT VALUES v.x
When I execute the statement (setting the placeholder correctly), I always get a
Caused by: org.hsqldb.HsqlException: row column count mismatch
Could you please give me a hint, what is going wrong here?
Thanks in advance.
Epilogue
I reported this behavior as a bug, and it is today (2010-05-25) fixed in the hsqldb SVN repository, per hsqldb-Bugs-2989597. (Thanks, hsqldb!)
Updated Answer
Neat one! Here's what I got to work under HSQLDB 2.0.0rc9, which supports the syntax and the error message you posted:
MERGE INTO mytable
USING (SELECT 'a uuid' FROM dual) AS v(x) -- my own "DUAL" table
ON (mytable.UUID = v.x)
WHEN NOT MATCHED THEN INSERT
VALUES (NULL, x) -- explicit NULL for "SHORT_ID" :(
Note, I could not convince 2.0.0rc9 to accept ... THEN INSERT (UUID) VALUES (x), which is IIUC a perfectly acceptable and clearer specification than the above. (My SQL knowledge is hardly compendious, but this looks like a bug to me.)
Original Answer
You appear to be INSERTing a single value (a 1-tuple) into a table with more than one column. Perhaps you can modify the end of your statement to read:
... WHEN NOT MATCHED INSERT ("UUID") VALUES (v.x)
I got same problems but solve in few minutes.
Its occur when datavalues and table structure are not same.Add explicit (NULL) in your empty column value.
Like i created table
TestCase table:
ID TESTCASEID DESCRIPTION
but your insertion statement you donot want to add any description for any testcase description then you have to explicite in insertion statement you have to set null value for description