Table Structure:
CREATE TABLE `cs_menuitem` (
`menuitemid` int(11) NOT NULL AUTO_INCREMENT,
`catid` int(11) DEFAULT NULL,
`itemname` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`menuitemid`),
KEY `fi0` (`catid`)
) ENGINE=InnoDB AUTO_INCREMENT=651879 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='InnoDB free: 9216 kB; (catid) REFER cruzstar_v01/cs_menucate';
Inserted UTF-8 chars using PHP
INSERT INTO `cs_menuitem` (`catid`, `itemname`)
VALUES
(97260, 'as “Sautéed Pastrami” , “Piña Colada Virgin” or “Piña Colada”');
Select query:
SELECT itemname FROM cs_menuitem where menuitemid = 651841;
with the command line, and PHP : (correct result)
as “Sautéed Pastrami” , “Piña Colada Virgin” or “Piña Colada”
But with others (MysqlWorkbench, SequelPro, PhpMyAdmin, PhpStorm, Java), getting: (incorrect result)
as “Sautéed Pastrami†, “Piña Colada Virgin†or “Piña Coladaâ€
Related
When I used "explain" on Mysql to view some information about the execution of the statement, the value of the field type made me very confused!
Table creation statement
DROP TABLE IF EXISTS `actor`;
CREATE TABLE `actor` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `actor` (`id`, `name`, `update_time`) VALUES (1,'a','2017-12-2 15:27:18'), (2,'b','2017-12-22 15:27:18'), (3,'c','2017-12-22 15:27:18');
DROP TABLE IF EXISTS `film`;
CREATE TABLE `film` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `film` (`id`, `name`) VALUES (3,'film0'),(1,'film1'),(2,'film2');
DROP TABLE IF EXISTS `film_actor`;
CREATE TABLE `film_actor` (
`id` int(11) NOT NULL,
`film_id` int(11) NOT NULL,
`actor_id` int(11) NOT NULL,
`remark` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_film_actor_id` (`film_id`,`actor_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `film_actor` (`id`, `film_id`, `actor_id`) VALUES (1,1,1),(2,1,2),(3,2,1);
When I execute
explain select * from film
left join film_actor on film.id = film_actor.film_id
left join actor on actor.id = film_actor.actor_id
where film.id = 1;
The type of each table is as follows
| table | type |
| ---------- | ----- |
| film | const |
| film_actor | ref |
| actor | ALL |
When I execute
explain select * from film
left join film_actor on film.id = film_actor.film_id
left join actor on actor.id = film_actor.actor_id
The type of each table is as follows
eq_ref is interpreted as One row is read from this table for each combination of rows from the previous tables.
ref is interpreted as All rows with matching index values are read from this table for each combination of rows from the previous tables.
But the difference between these two queries is only a where condition, and no related fields are modified. Why are the types of film_actor and actor tables completely different in the two queries? How to understand this phenomenon?
Thanks in advance.
I'm starting to create a database program for managing engineers, assigning calls to them and such and having this all linked together. However, I have ran into a problem where when I try to update/change a bit of information in the database through the use of my program it instead changed all the other items in the table to what it has just been changed to. For example, if I changed engineer 1's name to 'a', it would overwrite the other entities in the table so engineer 2 would have its name as 'a' now along with the properties of engineer 1.
I have attached the code I have written to update the table along with the SQL code for my database.
I'd appreaciate if someone could help me understand what is wrong here and I can provide other information when requested.
Thanks
private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {
try{
con = Connect.ConnectDB();
String sql = "update engineers set first_name ='" + textFirstName.getText()+ "',last_name='"+ textLastName.getText()+ "',middle_name='" + textMiddleName.getText()+ "',postcode='" + textPostcode.getText() + "',engineer_address='" + textAddress.getText() + "',engineer_dob='" + textDOB.getText() + "',comments='" + textComments.getText()+ "'";
pst = con.prepareStatement(sql);
pst.execute();
JOptionPane.showMessageDialog(this, "Updated","Engineer",JOptionPane.INFORMATION_MESSAGE);
btnUpdate.setEnabled(false);
}catch(HeadlessException | SQLException ex){
JOptionPane.showMessageDialog(this,ex);
}
-- MySQL Script generated by MySQL Workbench
-- Fri Sep 22 12:56:05 2017
-- Model: New Model Version: 1.0
-- MySQL Workbench Forward Engineering
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`customers`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`customers` (
`customer_id` INT NOT NULL AUTO_INCREMENT,
`customer_name` VARCHAR(45) NOT NULL,
`telephone` VARCHAR(45) NOT NULL,
`postcode` VARCHAR(45) NOT NULL,
`address` VARCHAR(45) NOT NULL,
`city` VARCHAR(45) NOT NULL,
PRIMARY KEY (`customer_id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`engineers`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`engineers` (
`engineer_id` INT NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(45) NOT NULL,
`last_name` VARCHAR(45) NOT NULL,
`postcode` VARCHAR(45) NOT NULL,
`active_job` VARCHAR(45) NOT NULL,
`on_holiday` VARCHAR(45) NOT NULL,
`engineer_address` VARCHAR(45) NOT NULL,
`engineer_postcode` VARCHAR(45) NOT NULL,
`comments` VARCHAR(45) NOT NULL,
`middle_name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`engineer_id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`machines`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`machines` (
`serial_number` VARCHAR(45) NOT NULL,
`customer_id` INT NOT NULL,
`meter_reading` VARCHAR(45) NOT NULL,
`install_date` VARCHAR(45) NOT NULL,
PRIMARY KEY (`serial_number`),
INDEX `fk_customer_id_idx` (`customer_id` ASC),
CONSTRAINT `fk_customer_id`
FOREIGN KEY (`customer_id`)
REFERENCES `mydb`.`customers` (`customer_id`)
ON DELETE RESTRICT
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`new_call`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`new_call` (
`call_id` INT NOT NULL AUTO_INCREMENT,
`serial_number` VARCHAR(45) NOT NULL,
`customer_id` INT NOT NULL,
`engineer_id` INT NOT NULL,
`call_fault` VARCHAR(45) NOT NULL,
`call_type` VARCHAR(45) NOT NULL,
`date_recieved` VARCHAR(45) NOT NULL,
`start_date` VARCHAR(45) NOT NULL,
`engineer_dob` VARCHAR(45) NOT NULL,
PRIMARY KEY (`call_id`),
INDEX `fk_serial_number_idx` (`serial_number` ASC),
INDEX `fk_engineer_id_idx` (`engineer_id` ASC),
INDEX `fk1_customer_id_idx` (`customer_id` ASC),
CONSTRAINT `fk_serial_number`
FOREIGN KEY (`serial_number`)
REFERENCES `mydb`.`machines` (`serial_number`)
ON DELETE RESTRICT
ON UPDATE CASCADE,
CONSTRAINT `fk_engineer_id`
FOREIGN KEY (`engineer_id`)
REFERENCES `mydb`.`engineers` (`engineer_id`)
ON DELETE RESTRICT
ON UPDATE CASCADE,
CONSTRAINT `fk1_customer_id`
FOREIGN KEY (`customer_id`)
REFERENCES `mydb`.`customers` (`customer_id`)
ON DELETE RESTRICT
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`users`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`users` (
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL)
ENGINE = InnoDB;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
first of all use PreparedStatement.
if you want to update a specific engineer you should identify the data with the sql where section.
in your case that could be:
PreparedStatement statement = con.prepareStatement("update engineers set first_name =? " +
",last_name=?, middle_name=?" +
",postcode=?,engineer_address=?" +
",engineer_dob=?" +
",comments=? " +
"where engineer_id=?"); // <--- WHERE SECTION
statement.setString(1, "Chuck");
statement.setString(2, "Norris");
// and so on and so on...
statement.setInteger(8, idOfEngineer);
statement.executeUpdate();
I am using Scriptella to copy data from one table to another table(different database) on Mysql. For source, I have used table film from Mysql sample database Sakila.
While copying the data I am getting this error message.
Exception in thread "main" scriptella.execution.EtlExecutorException: Location: /etl/query[1]/script[1]
JDBC provider exception: Unable to get parameter 4
Error codes: [S1009, 0]
Driver exception: java.sql.SQLException: Cannot convert value '2006' from column 4 to TIMESTAMP.
at scriptella.execution.EtlExecutor.execute(EtlExecutor.java:190)
at com.zensar.scrptellaTest.App.main(App.java:21)
Caused by: scriptella.core.ExceptionInterceptor$ExecutionException: /etl/query[1]/script[1] failed: Unable to get parameter 4
at scriptella.core.ExceptionInterceptor.execute(ExceptionInterceptor.java:44)
at scriptella.core.QueryExecutor$QueryCtxDecorator.processRow(QueryExecutor.java:114)
at scriptella.jdbc.StatementWrapper.query(StatementWrapper.java:92)
at scriptella.jdbc.SqlExecutor.statementParsed(SqlExecutor.java:128)
at scriptella.jdbc.SqlParserBase.handleStatement(SqlParserBase.java:129)
at scriptella.jdbc.SqlParserBase.parse(SqlParserBase.java:72)
at scriptella.jdbc.SqlExecutor.execute(SqlExecutor.java:85)
at scriptella.jdbc.JdbcConnection.executeQuery(JdbcConnection.java:222)
at scriptella.core.QueryExecutor.execute(QueryExecutor.java:71)
at scriptella.core.ContentExecutor.execute(ContentExecutor.java:73)
at scriptella.core.ElementInterceptor.executeNext(ElementInterceptor.java:56)
at scriptella.core.StatisticInterceptor.execute(StatisticInterceptor.java:41)
at scriptella.core.ElementInterceptor.executeNext(ElementInterceptor.java:56)
at scriptella.core.ConnectionInterceptor.execute(ConnectionInterceptor.java:36)
at scriptella.core.ElementInterceptor.executeNext(ElementInterceptor.java:56)
at scriptella.core.ExceptionInterceptor.execute(ExceptionInterceptor.java:39)
at scriptella.core.Session.execute(Session.java:103)
at scriptella.execution.EtlExecutor.execute(EtlExecutor.java:227)
at scriptella.execution.EtlExecutor.execute(EtlExecutor.java:183)
... 1 more
This is one row from the table.
'1', 'ACADEMY DINOSAUR', 'A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies', 2006, '1', NULL, '6', '0.99', '86', '20.99', 'PG', 'Deleted Scenes,Behind the Scenes', '2006-02-15 05:03:42'
Here it the DDL statement of both the tables.
sakila.film
CREATE TABLE `film` (
`film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`description` text,
`release_year` year(4) DEFAULT NULL,
`language_id` tinyint(3) unsigned NOT NULL,
`original_language_id` tinyint(3) unsigned DEFAULT NULL,
`rental_duration` tinyint(3) unsigned NOT NULL DEFAULT '3',
`rental_rate` decimal(4,2) NOT NULL DEFAULT '4.99',
`length` smallint(5) unsigned DEFAULT NULL,
`replacement_cost` decimal(5,2) NOT NULL DEFAULT '19.99',
`rating` enum('G','PG','PG-13','R','NC-17') DEFAULT 'G',
`special_features` set('Trailers','Commentaries','Deleted Scenes','Behind the Scenes') DEFAULT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`film_id`),
KEY `idx_title` (`title`),
KEY `idx_fk_language_id` (`language_id`),
KEY `idx_fk_original_language_id` (`original_language_id`),
CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE,
CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `language` (`language_id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8;
trg.film
CREATE TABLE `film` (
`film_id` smallint(5) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`description` text,
`release_year` year(4) DEFAULT NULL,
`language_id` tinyint(3) unsigned NOT NULL,
`original_language_id` tinyint(3) unsigned DEFAULT NULL,
`rental_duration` tinyint(3) unsigned NOT NULL DEFAULT '3',
`rental_rate` decimal(4,2) NOT NULL DEFAULT '4.99',
`length` smallint(5) unsigned DEFAULT NULL,
`replacement_cost` decimal(5,2) NOT NULL DEFAULT '19.99',
`rating` enum('G','PG','PG-13','R','NC-17') DEFAULT 'G',
`special_features` set('Trailers','Commentaries','Deleted Scenes','Behind the Scenes') DEFAULT NULL,
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Scriptella etl.xml
<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd">
<etl>
<description>Scriptella ETL File Template.</description>
<!-- Connection declarations -->
<connection id="source" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/sakila" user="root" password="12345" />
<connection id="target" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/trg" user="root" password="12345" />
<!-- Uncomment and modify to run a query-based transformation -->
<query connection-id="source">
SELECT * FROM film;
<script connection-id="target">
INSERT INTO film VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13);
</script>
</query>
</etl>
Java Code
public static void main(String[] args) throws EtlExecutorException {
ProgressIndicatorBase indicatorBase = new ProgressIndicatorBase() {
#Override
protected void show(String label, double progress) {
System.out.println(label + "--> " + progress);
}
};
EtlExecutor.newExecutor(new File("etl.xml")).execute(indicatorBase);
}
Please tell me where I am doing wrong or is there any workaround to solve it.
The exception you receive is
Driver exception: java.sql.SQLException: Cannot convert value '2006' from column 4 to TIMESTAMP.
It seems that the particular DB line contains value 2006 in a column where a TIMESTAMP type is expected, the format of which for MySQL seems to be
TIMESTAMP - format: YYYY-MM-DD HH:MI:SS
Ok I think I know.
Just put quotes around the parameter
?4 should look like "?4"
At the source the date is being casted as a string.
So when the insert is created with the string date without the quotes, the date parsing stops after year leaving you with just a number
I wrote MySQL StoredProcedure to create and return new ID for each table value, however, it gets wrong value on last_insert_id() from MySQL WorkBench and Java application.
This procedure will be called from multiple sessions.
CALL `GET_NEW_ID`('test', #test);
select #test;
It gives me "141215000000" and this means last_insert_id() returns 0 all the time.
I see it correctly inserts new data into seq_data as supposed though.
CREATE PROCEDURE `GET_NEW_ID`(IN V_TABLE VARCHAR(10), OUT V_ID VARCHAR(12))
BEGIN
INSERT INTO seq_data ( id, `name`, `stat_date`)
SELECT IFNULL(MAX(id), 0)+1, V_TABLE, DATE_FORMAT(NOW(),'%Y%m%d') FROM seq_data WHERE name = V_TABLE AND stat_date = DATE_FORMAT(NOW(),'%Y%m%d');
SET V_ID = concat(DATE_FORMAT(NOW(),'%y%m%d'),LPAD(LAST_INSERT_ID(), 6, '0'));
END
Table looks like this.
CREATE TABLE `seq_data` (
`id` int(6) NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8_bin NOT NULL,
`stat_date` varchar(8) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`,`name`,`stat_date`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
My goal is like...
CALL `GET_NEW_ID`('test', #test);
select #test;
return 141215000001
CALL `GET_NEW_ID`('test', #test);
select #test;
return 141215000002
CALL `GET_NEW_ID`('hello', #test);
select #test;
return 141215000001
As stated in the MySQL documentation, LAST_INSERT_ID() returns a BIGINT (64-bit) value representing the first automatically generated value that was set for an AUTO_INCREMENT column by the most recently executed INSERT statement to affect such a column.
In your case, you are inserting the id, so an AUTO_INCREMENT value is not generated, thus LAST_INSERT_ID returns 0.
You may try something like:
CREATE PROCEDURE `GET_NEW_ID`(IN V_TABLE VARCHAR(10), OUT V_ID VARCHAR(12))
BEGIN
INSERT INTO seq_data (`name`, `stat_date`)
SELECT V_TABLE, DATE_FORMAT(NOW(),'%Y%m%d') FROM seq_data WHERE name = V_TABLE AND stat_date = DATE_FORMAT(NOW(),'%Y%m%d');
SET V_ID = concat(DATE_FORMAT(NOW(),'%y%m%d'),LPAD(LAST_INSERT_ID(), 6, '0'));
END
I have two tables, A and B. When inserting a new row into table B, how do I insert a FK as a reference to a record in table A?
I've got the two below tables:
--
-- Table structure for table `sector`
--
CREATE TABLE IF NOT EXISTS `sector` (
`sector_id` int(11) NOT NULL AUTO_INCREMENT,
`sector_name` varchar(100) NOT NULL,
`sector_url` varchar(500) NOT NULL,
PRIMARY KEY (`sector_id`),
UNIQUE KEY `sector_id` (`sector_id`,`sector_name`,`sector_url`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `constituent` (
`constituent_id` int(11) NOT NULL AUTO_INCREMENT,
`constituent_name` varchar(100) DEFAULT '',
`constituent_ticker` varchar(10) NOT NULL,
`constituent_isin_number` varchar(50) DEFAULT '',
`constituent_currency` varchar(10) DEFAULT '',
`sector_id` int(11) NOT NULL,
PRIMARY KEY (`constituent_id`),
KEY `sector_id` (`sector_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Constraints for table `constituent`
--
ALTER TABLE `constituent`
ADD CONSTRAINT `constituent_ibfk_1` FOREIGN KEY (`sector_id`) REFERENCES `sector` (`sector_id`);
When I do an insert, how can I structure the query such that when I insert into the table 'constituent', I'm using the primary key of 'sector'?
INSERT into constituent (constituent_name, constituent_ticker, constituent_isin_number, constituent_currency, sectorFK)
values ("the name", "the ticker", "the number", "the currency", "the foreign key???")
To be able to get a primary key value after inserting into table B, in order to insert it into the table A, you could use last_insert_id() function, which when used without a parameter returns a last automatically generated value that was set for an AUTO_INCREMENT column:
For example:
insert into B(col)
values(1);
insert into A(t1_id, col)
values(last_insert_id(), 2);
insert into A(t1_id, col)
values(last_insert_id(), 3);
SQLFIddle Demo
Assuming there is a sector with sector_name 'sector 1' you could do something like this.
INSERT into constituent (constituent_name, constituent_ticker, constituent_isin_number, constituent_currency, sector_id) (select 'the name', 'the ticker', 'the number', 'the currency', sector_id from sector where sector_name = "sector 1");