MySQL - Selecting only the default value from column - java

I am wondering is it possible to select only the default value of empty column?
I have absolutely empty table and I want just to select one of the columns default value - it is important for my JAVA app which is filling the table.
Thanks.

You can get the default from the INFORMATION_SCHEMA.COLUMNS
select COLUMN_DEFAULT
from INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA='your_db' and TABLE_NAME='your_table' and COLUMN_NAME='your_column'

You can define a default value for a column when you create a table, if you just want MySQL to insert it automatically:
create table my_table (i INT DEFAULT 1);
But if you mean you want the default value which is stored in the DB dictionary, you can get it by this query:
SELECT Column_Default
FROM Information_Schema.Columns
WHERE Table_Schema = 'yourSchema'
AND Table_Name = 'yourTableName'
AND Column_Name = 'yourColumnName'

I can only think of two ways:
Inserting a row
Insert a row without specifying a value for that column
Select the column from that row; it will have the default value of the column
Delete the row
...probably all in a transaction so nothing else sees it.
Using describe (explain)
The describe command (aka explain) describes objects in the system, including tables. So if you do explain YourTable, you'll get back information about the table, including its default values.
Here's an example from that linked documentation:
mysql> DESCRIBE City;
+−−−−−−−−−−−−+−−−−−−−−−−+−−−−−−+−−−−−+−−−−−−−−−+−−−−−−−−−−−−−−−−+
| Field | Type | Null | Key | Default | Extra |
+−−−−−−−−−−−−+−−−−−−−−−−+−−−−−−+−−−−−+−−−−−−−−−+−−−−−−−−−−−−−−−−+
| Id | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| Country | char(3) | NO | UNI | | |
| District | char(20) | YES | MUL | | |
| Population | int(11) | NO | | 0 | |
+−−−−−−−−−−−−+−−−−−−−−−−+−−−−−−+−−−−−+−−−−−−−−−+−−−−−−−−−−−−−−−−+
So you can extract the default from the Default column in the returned rows.
Ah, of course, there's a third way, see slaakso's answer for it.

Related

ERROR 1366 (HY000): Incorrect string value: '\x85\x8A\x8D\x95\x97' for column 'name' at row 1

this is the faulty statement:
insert into customer (id, uuid, name) values (1,uuid(), 'àèìòù');
I am using MySQL server 8.0.32 (just upgraded from 5.7) on Windows.
I am also executing this statement from MySQL client, on the same machine.
Same error using mysql-connector-j-8.0.32.
jdbc:mysql://localhost:3306/risk?allowPublicKeyRetrieval=true&useLocalSessionState=true&rewriteBatchedStatements=true
No error using mysql-connector-java-8.0.22 with the same environment and the same connection string.
This the table:
| customer | CREATE TABLE `customer` (
`id` bigint NOT NULL,
`uuid` char(36) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_q8w2f8xfdoax44qc8w0epholu` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
And these are the variables:
mysql> show variables like '%char%';
+--------------------------+------------------------------------------------------+
| Variable_name | Value |
+--------------------------+------------------------------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
| character_sets_dir | D:\shape\servers\mysql-8.0.32-winx64\share\charsets\ |
+--------------------------+------------------------------------------------------+
8 rows in set (0.00 sec)
mysql> show variables like '%collation%';
+-------------------------------+--------------------+
| Variable_name | Value |
+-------------------------------+--------------------+
| collation_connection | utf8mb4_0900_ai_ci |
| collation_database | utf8mb4_0900_ai_ci |
| collation_server | utf8mb4_0900_ai_ci |
| default_collation_for_utf8mb4 | utf8mb4_0900_ai_ci |
+-------------------------------+--------------------+
4 rows in set (0.00 sec)
Maybe a bug? Am I missing something?
update
this is working:
mysql> set character_set_client=cp850;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into customer (id, uuid, name) values (1,uuid(), 'àèìòù');
Query OK, 1 row affected (0.00 sec)
But why?
And how can I use UTF-8 also on client side?
update2
Also, commenting in my.ini:
character-set-server=utf8mb4
collation-server=utf8mb4_0900_ai_ci
#character-set-client-handshake = FALSE
#init_connect='SET NAMES utf8mb4'
makes JDBC working again...
What application are you using?
Apparently, your client is using "cp850" since that hex decodes to àèìòù.
You could either tell MySQL that you are using cp850 by establishing the connection that way, or (better) fix the encoding inside the client.
That is, the problem does not seem to be with MySQL.
More
If you are using Windows, did you do something like
chcp 850
Instead, you need
chcp 65001

Define timestamp in hibernate.hbm.xml

I have a dummy table I want to map with Hibernate can you please help me to define in dummy.hbm.xml
type=timestamp, Default=CURRENT_TIMESTAMP, extra=on update CURRENT_TIMESTAMP
And which type of variable should i need to define in java class?
desc dummy;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+--------------+------+-----+-------------------+-----------------------------+

Not able to insert CAFÉ in mysql, even after setting encoding correctly

I inserted the word CAFE in name field mySQL table.
Unexpectedly, I get a row containing CAFE when I execute below statement
SELECT * FROM myTable where name='CAFÉ';
, which is wrong. In my use-case CAFE shouldn't be equal to CAFÉ
I think I set all the encodings correctly on server and client side:
Server side:
By modifying /etc/mysql/my.cnf I get below
mysql> show variables like "%character%";show variables like "%collation%";
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_general_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)
Client Side:
connect = DriverManager
.getConnection("jdbc:mysql://"+serverName+"/" +
dataBaseName + "?characterEncoding=utf8&user=" + userName + "&password=" + password);
p.s. there are many duplicate questions similar to this, but none of them answering specific to what I am running into.
Collation utf8_general_ci (_ci stands for Case Insensitive) does not only make e equal to E, but also makes E equal to É. To make a select statement case sensitive, you can use the solution from this answer:
SELECT * FROM myTable where BINARY name='CAFÉ';
If you want to make data in column name always case sensitive, use a case sensitive _bin collation as shown in the answers for this question. E.g. when you create a table, use:
CREATE TABLE myTable (
...
) CHARACTER SET utf8 COLLATE utf8_bin ENGINE=MyISAM;
Credit to #vanOekel comments
adding CHARACTER SET utf8 COLLATE utf8_bin while creating the table solved my problem
CREATE TABLE myTable (
name CHAR(100) NOT NULL,
CONSTRAINT uc__name UNIQUE (name)
) CHARACTER SET utf8 COLLATE utf8_bin ENGINE=MyISAM;
Now in my table I can have both CAFE and CAFÉ without tripping the unique constraint on name field.

Many SQL select queries in java with possibility of not finding

I currently got a performance issue with an application that uses many sql select.
The programming language is java and I'm using a mysql database. It contains about 10 million records.
What it needs to do is to find records in a database with zipcode and house number as parameters. When it does not find a record, it needs to do a query with only the zipcode and get the record with the lowest house number. When the zipcode cannot be found in the database the application needs to deal with this.
Thus the code for doing single queries looks like this:
Statement select = "select * from zipcode_addresses where zipcode = ? and houseNo =?";
ResultSet rs = select.executeQuery();
if(rs.next()) {
dealWithResult(rs);
}
else {
Statement alternativeSelect = "select * from zipcode_addresses where zipcode = ? group by houseNo having min(houseNo)";
ResultSet rs = alternativeSelect.executeQuery();
if(rs.next()) {
dealWithResult(rs);
} else {
System.err.println("Could not find zipcode :" + zipcode);
}
}
Is there a proper way of doing batch select queries which deals with data not being found?
Thanks!
Update
The table structure is the following:
+-----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+-------+
| zipcode | varchar(6) | NO | PRI | NULL | |
| house_no | int(11) | NO | PRI | NULL | |
| sanddcode | varchar(45) | NO | | NULL | |
| depot | varchar(3) | NO | | NULL | |
| network_point | varchar(6) | NO | | NULL | |
| region | varchar(3) | NO | | NULL | |
| seq | int(11) | NO | | NULL | |
| cluster_id | varchar(1) | NO | | NULL | |
| strand_id | int(11) | NO | | NULL | |
| strand_props_id | int(11) | NO | | NULL | |
| version_id | int(11) | NO | PRI | NULL | |
+-----------------+-------------+------+-----+---------+-------+
Primary key on version id, zipcode and house_no
Index on zipcode and house_no and another index on zipcode, both using BTREE index.
The application might sometimes be used to do 1 million distinctive select queries at which point it just takes too long.
Your code snippet doesn't show how your statements are being prepared. If your statements are being called numerous times then you should take a look at the PreparedStatement object:
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Your statements can then be cached to reduce future overhead.
you could create a stored procedure with two parameters, and use the House Number as optional, or just let that the procedure finds if exists or don't.
A lot depends on the usage pattern. How many queries you run, how often there is a ZIP code miss, etc. First off, I would use PreparedStatements where posssible. I am not that familiar with MySQL, but they are usually cached and reused by the connection-database, that will help with performance. Next, If ZIP code misses were common, I would probably build an in memory cache of ZIP codes to short circuit doing 3 queries on a miss. After that, I might make a view that's ZIP + house number. Going further depends more on how your appliation works, but these things would help.
The 'group by' in your second SQL query is unnecessary and killing performance. For maximum performance, replace this select (the second one in your code) ...
select * from zipcode_addresses where zipcode = ?
group by houseNo having min(houseNo)
with this ...
select min(houseNo) from zipcode_addresses where zipcode = ?
Also, ensure you have an index on zipcode + houseNo (which it looks like you have - from the updated post).

How to Get DB Field name from ConstraintViolationException - Hibernamte

How to get the Name of the DB field causing ConstraintViolationException while inserting in to Database in hibernate.
I have the Table Like
mysql> desc Mytable;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | bigint(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | UNI | NULL | |
| city | varchar(20) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
And records inthe table are
mysql> select * from Mytable;
+----+--------+-------+
| id | name | city |
+----+--------+-------+
| 1 | SATISH | BLORE |
+----+--------+-------+
1 row in set (0.00 sec)
Now, im trying to insert
"RAMESH","BLORE" through hibernate.
It is throwing ConstraintViolationException due to "BLORE" (CITY) already Exist.
if im trying to insert.
"SATISH","MLORE" through hibernate
It is throwing ConstraintViolationException due to "SATISH" (NAME) already Exist.
My question is
how to get fieldName who is causing the exception ConstraintViolationException through Hibernate.
Since there might be other constraints that could be violated (e.g. combined keys), you only have the name of the constraint that is violated, which in your case might just be the column name (however, I'm not entirely sure about that). You can get the name of the violated constraint by calling getConstraintName() on the ConstraintViolationException.

Categories