I have two tables whereby the primary key(foreign key on the other table) is auto incremented at run time (using TOAD for mysql).
How can I insert data into the two tables at the same time using a transaction.
This is the ddl for the first table:
CREATE TABLE `suspendedsales` (
`SID` int(11) NOT NULL AUTO_INCREMENT,
`SequenceNo` int(11) NOT NULL DEFAULT '0',
`ProductCode` varchar(100) DEFAULT NULL,
`ItemName` varchar(100) DEFAULT NULL,
`Quantity` int(11) DEFAULT NULL,
`Discount` double DEFAULT NULL,
`ItemCost` double DEFAULT NULL,
PRIMARY KEY (`SID`,`SequenceNo`),
CONSTRAINT `SIDFKey` FOREIGN KEY (`SID`) REFERENCES `suspendedsalesdetails` (`SID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The ddl for the second table:
CREATE TABLE `suspendedsalesdetails` (
`SID` int(11) NOT NULL DEFAULT '0',
`Date` date DEFAULT NULL,
`Total` double DEFAULT NULL,
PRIMARY KEY (`SID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
N.B: The major challenge would be to get the auto-incremented key value from on the primary key to be inserted into the other table at run time.
Thanks in anticipation.
If your database is a MySql database you can insert a record in the first table use the following function
SELECT LAST_INSERT_ID();
to get the last inserted id and you can use it in the second insert. Commit all only after the second insert
How about this:
private void insert() {
OraclePreparedStatement statement = null;
try {
Connection dbConnection = getConnection();
statement = dbConnection.createStatement();
String insertToSuspendedsales = "insert into suspendedsales (SequenceNo, ProductCode,ItemName,Quantity,Discount,ItemCost) "
+ "values(:segNo, :prodNo, :itmeName, :quantity, :discount, :itemCost) returning SID into ?";
statement.setIntAtName("segNo", intValue);
....
int id = statement.registerReturnParameter(1, OracleTypes.INTEGER)
statement.executeUpdate(insertToSuspendedsales);
String insertToSuspendedsalesdetails = "insert into suspendedsalesdetails (SID, Date, Total) "
+ "values(:sid, :date, :total) returning SID into ?";
statement.setIntAtName("sid", id);
....
statement.executeUpdate(insertToSuspendedsalesdetails);
} catch (SQLException ex) {
ex.printStackTrace();
//rollback
} finally {
//close Connection
}
}
Related
I've got tables Artist, Concert, and Artist_Concert, which contains many-to many connections between Artist and Concert.
The problem is: after adding a Concert with few Artists, when trying to delete rows from Artist_Concert, it only deletes only one row and nothing happens when trying to delete any others.
This is how I'm trying to delete rows in Java:
stat = connect.createStatement();
res = stat.executeQuery ("SELECT idConcert FROM concerthall.concert where ConcertName = '"+conc+"';");
res.first();
int idconc = res.getInt(1);
stat.execute ("DELETE FROM concerthall.artist_concert WHERE idConc="+idconc+"");
Artist
CREATE TABLE IF NOT EXISTS `concerthall`.`Artist` (
`idArtist` INT NOT NULL AUTO_INCREMENT,
`ArtName` VARCHAR(45) NOT NULL,
`ArtFee` INT NULL,
PRIMARY KEY (`idArtist`))
ENGINE = InnoDB
Artist-Concert
CREATE TABLE IF NOT EXISTS `concerthall`.`Artist_Concert` (
`idCA` INT NOT NULL AUTO_INCREMENT,
`idArt` INT NOT NULL,
`IdConc` INT NOT NULL,
INDEX `idart_idx` (`idArt` ASC),
INDEX `idconc_idx` (`IdConc` ASC),
PRIMARY KEY (`idCA`),
CONSTRAINT `idart2`
FOREIGN KEY (`idArt`)
REFERENCES `concerthall`.`Artist` (`idArtist`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `idconct4`
FOREIGN KEY (`IdConc`)
REFERENCES `concerthall`.`Concert` (`idConcert`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
Concert
CREATE TABLE IF NOT EXISTS `concerthall`.`Concert` (
`idConcert` INT NOT NULL AUTO_INCREMENT,
`ConcertName` VARCHAR(45) NOT NULL,
`ConcertDateTime` DATETIME NOT NULL,
`Organizator` INT NOT NULL,
PRIMARY KEY (`idConcert`),
INDEX `concertorg_idx` (`Organizator` ASC),
CONSTRAINT `concertorg`
FOREIGN KEY (`Organizator`)
REFERENCES `concerthall`.`Organizator` (`idOrganizator`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
The easiest way to drop duplicates is:
ALTER IGNORE TABLE table ADD UNIQUE INDEX( a, b );
In the INDEX() part, enter the name(s) of the column(s) you only want unique entries for. I think you want:
ALTER IGNORE TABLE concerthall.artist_concert ADD UNIQUE INDEX( idConc );
Then drop the index.
I have a problem with the auto incremented values in preparedStatement. Here is my database
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`isbn` varchar(10) NOT NULL,
`title` varchar(20) NOT NULL,
`pages` int(11) NOT NULL,
`price` decimal(5,2) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `isbn` (`isbn`)
and here is my preparedStatement:
String title = fieldTitle.getText();
String isbn = fieldISBN.getText();
double price = Double.parseDouble(fieldPrice.getText());
int pages = Integer.parseInt(fieldPages.getText());
conn = DBUtil.connect();
try {
prepState = conn.prepareStatement("insert into book values(?,?,?,?)");
prepState.setString(1, isbn);
prepState.setString(2, title);
prepState.setInt(3, pages);
prepState.setDouble(4, price);
prepState.execute();
However, when I fill in the fields I get the following error:
java.sql.SQLException: Column count doesn't match value count at row 1. I know that when the field in the database is autoincremented I do not have to put it in the query...
Any ideas?
Modify you query to include column names:-
INSERT INTO book (isbn, title, pages, price) VALUES (?,?,?,?)
I'm trying to use Derby in my school project but i have some issues.
my DB is named theaterDB, derby 10.2.1, JDBC 3.0.0
Each SQL request i make through java does not succeed... I can't understand why.
For example, the request:
SELECT * FROM User returns an exception:
java.sql.SQLSyntaxErrorException: Schema 'ADMIN' does not exist
Another SQL that is not working :
ALTER table theaterDB."Projection" ADD INDEX(fk_Projection_Movie(Movie_id));
Syntax error: Encountered "" at line 1, column 45.
Here is the java :
public Connection getConnection()
{
try
{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
System.out.println("Connection to: jdbc:derby:C:\\Users\\acouty\\theaterDB;create=true");
// DriverManager.get
return DriverManager.getConnection("jdbc:derby:C:\\Users\\acouty\\theaterDB;create=true", "admin", "");
}
catch (final Exception e)
{
e.printStackTrace();
return null;
}
}
public List<User> listUsers()
{
final ArrayList<User> users = new ArrayList<User>();
System.out.println("List user request");
try
{
final Connection connection = getConnection();
final String query = "SELECT * FROM User";
System.out.println("query is : " + query);
final ResultSet rs = connection.createStatement().executeQuery(query);
while (rs.next())
{
System.out.println("salut");
}
return null;
}
catch (final Exception e)
{
e.printStackTrace();
}
return null;
}
Here is the .sql :
CREATE TABLE theaterDB."Users"
(
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
name VARCHAR(45) NOT NULL,
lastname VARCHAR(45) NOT NULL ,
email VARCHAR(45) NOT NULL ,
adress VARCHAR(45) NOT NULL ,
city VARCHAR(45) NOT NULL ,
zip VARCHAR(45) NOT NULL ,
login VARCHAR(45) NOT NULL ,
password VARCHAR(45) NOT NULL ,
admin SMALLINT NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE theaterDB."Movie"
(
id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
title VARCHAR(45) NOT NULL ,
resume VARCHAR(500) ,
genre VARCHAR(60) ,
grade INT ,
review_pub VARCHAR(200) ,
review_gen VARCHAR(200) ,
poster VARCHAR(100) ,
duration INT ,
release_date VARCHAR(45) ,
PRIMARY KEY (id)
);
CREATE TABLE theaterDB."Projection" (
id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
date DATE ,
length INT ,
Movie_id INT NOT NULL ,
price DECIMAL(10,0) ,
location VARCHAR(45) NOT NULL ,
place_nbr INT NOT NULL ,
PRIMARY KEY (id)
);
ALTER TABLE theaterDB."Projection"
ADD FOREIGN KEY(Movie_id)
REFERENCES theaterDB."Movie" (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
CREATE TABLE theaterDB."command"
(
id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
Projection_id INT NOT NULL ,
User_id INT NOT NULL ,
paid SMALLINT NOT NULL ,
PRIMARY KEY (id)
);
ALTER TABLE theaterDB."command"
ADD FOREIGN KEY(Projection_id)
REFERENCES theaterDB."Projection" (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
ALTER TABLE theaterDB."command"
ADD FOREIGN KEY(User_id)
REFERENCES theaterDB."Users" (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
Thank you
I had to change executeQuery to execute and Users to "THEATERDB"."USERS"
Here are the working requests:
SELECT * FROM "THEATERDB"."Users"
insert into "THEATERDB"."Users"(NAME, LASTNAME, EMAIL, ADRESS, CITY, ZIP, LOGIN, PASSWORD, ADMIN) values ('salut', 'salut', 'salut', 'salut', 'salut', 'salut', 'salut', 'salut', 1)
Thanks for you help :).
When I enter data with my java program (simple dictionary ) it throws an error:
MySQLIntegrityConstraintViolationException: Cannot add or update a
child row: a foreign key constraint fails (singlehaw.card,
CONSTRAINT card_ibfk_1 FOREIGN KEY (wordId) REFERENCES word
(wordId))
But when I enter data through query in command prompt I don't face any problem.
here I post my method:
public boolean insert(Card card) {
Connection connection = MySqlUtils.getInstance().getConnection();
PreparedStatement statement = null;
ResultSet resultSet = null;
int cardId = -1;
try {
String INSERT_INTO_TABLE_CARD_QUERY = "INSERT INTO "
+ TBL_CARD + " ("
+ STATUS + ", "
+ RATING + ", "
+ INSERT_TIME + ", "
+ DIC_ID + ", "
+ WORD_ID
+ ") VALUES (?,?,NOW(),?,?)";
statement = connection.prepareStatement(INSERT_INTO_TABLE_WORDS_QUERY, Statement.RETURN_GENERATED_KEYS);
statement.setString(1, card.getStatus().name());
statement.setInt(2, card.getRating());
statement.setInt(3, card.getDictionaryId());
statement.setInt(4, card.getWordId());
statement.execute();
// get last inserted id
resultSet = statement.getGeneratedKeys();
if (resultSet.next())
cardId = resultSet.getInt(1);
} catch (SQLException e) {
e.printStackTrace();
return false;
} finally {
try {
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
card.setCardId(cardId);
return true;
}
and also scripts of creating tables:
CREATE TABLE dictionary (
dictionaryId SERIAL,
dictionary VARCHAR(128) NOT NULL,
PRIMARY KEY (dictionaryId)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE word (
wordId SERIAL,
word VARCHAR(255) NOT NULL UNIQUE,
transcription VARCHAR(255),
PRIMARY KEY (wordId)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE card (
cardId SERIAL,
status ENUM ('EDIT', 'POSTPONED', 'TO_LEARN', 'LEARNT') NOT NULL DEFAULT 'TO_LEARN',
rating TINYINT DEFAULT '0' NOT NULL,
insert_time TIMESTAMP DEFAULT NOW(),
update_time TIMESTAMP,
dictionaryId BIGINT UNSIGNED NOT NULL,
wordId BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (cardId),
FOREIGN KEY (wordId) REFERENCES word (wordId),
FOREIGN KEY (dictionaryId) REFERENCES dictionary (dictionaryId) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Perhaps, the fact your wordID fields on the tables have different data types is affecting your program. SERIAL is an alias for Bigint. Idea discarded.
Print somwehere in the logs the actual statement being executed. Maybe there's something that's not being included.
Thnx guys a lot. Understood many things from this topic. Right now the problem has gone. The problem was due to populating tables via JUnit tests and because of maven my tests gone in a wrong order so it was difficult to recognize the real problem.
You can switch off your constraints ,execute your query, and switch constraints on.
SET FOREIGN_KEY_CHECKS=0;
... here is your sql ...
SET FOREIGN_KEY_CHECKS=1;
Hi I'm trying to get the foreig key for a given table, I'm using this code :
ResultSet rs = meta.getImportedKeys(_con.getCatalog(), null, _tableName);
while (rs.next())
{
//get the foreignKeys
}
ResultSet rs2 = meta.getExportedKeys(_con.getCatalog(), null, _tableName);
while (rs2.next())
{
//get the foreignKeys
}
The resultSet is empty, although the table contains a foreign key and is a foreign key to another table,
the getImportedKeys works fine.
Thanks for any suggestions.
Tables :
CREATE TABLE `COMMANDE` (
`COMMANDE_ID` int(11) NOT NULL,
`CLIENT_ID` int(100) DEFAULT NULL,
`TOURNEE_ID` int(100) DEFAULT NULL,
PRIMARY KEY (`COMMANDE_ID`),
KEY `CLIENT_ID` (`CLIENT_ID`),
KEY `TOURNEE_ID` (`TOURNEE_ID`),
CONSTRAINT `commande_ibfk_1` FOREIGN KEY (`CLIENT_ID`) REFERENCES `CLIENT` (`CLIENT_ID`),
CONSTRAINT `commande_ibfk_2` FOREIGN KEY (`TOURNEE_ID`) REFERENCES `TOURNEE` (`TOURNEE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `CLIENT` (
`CLIENT_ID` int(100) NOT NULL,
`LIBELLE` varchar(100) DEFAULT NULL,
PRIMARY KEY (`CLIENT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I tried the code with both tables.
I think the problem is from the rather curious naming of the methods in JDBC, and the hard to grok description.
To get primary keys of a table, you should use getPrimaryKeys(), to get the foreign key of a table (and the primary key they reference), use getImportedKeys()
There are additional methods
- getExportedKeys() exposes the foreign keys that reference the specified table (so the table parameter specifies the table with the primary key)
- getCrossReference() is a combination of all of the above: you need to specify the tables on both sides of the constraint