insert in to two table using one query inner join - mysql

I have two tables. One is user_info and the other is user_login. I want to insert data into both these tables in one query using an inner join. The data comes from user registration.
My login table:
user_id(pk) user_name user_password
1 jinesh secret
2 mahesh secret
My info table:
user_id(fk) name address phno
1 jinesh n banglore 9845***
2 mahesh m chennai 7345**

You can't make one query to insert values in two tables
However if you want to have the two querys in only one statement then
this can be done if you seperate the statements with ;
$query = "insert into table_1 (data1, data2) values ('value1', 'value2');insert into table_2 (data1,data2) values ('value1', 'value2')";

The best way is to use Stored Procedure.
CREATE PROCEDURE `Proc_User` (IN username VARCHAR(225), IN password VARCHAR(255),
IN uname VARCHAR(255),IN addr VARCHAR(255),IN phno VARCHAR(20))
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
BEGIN
-- ERROR or WARNING
ROLLBACK;
END;
START TRANSACTION;
DECLARE userid INT;
INSERT INTO login (user_name,user_password) VALUES(username,password);
SET userid = (SELECT LAST_INSERT_ID());
INSERT INTO info(user_id,name,address,phno)
VALUES(userid,uname,addr,password);
COMMIT;
END
And to call the Stored Procedure in PHP
$proc = mysqli_prepare('CALL Proc_User(?, ?, ?,?,?);');
mysqli_stmt_bind_param('sssss', $username, $password, $name,$address,$phoneno);
mysqli_stmt_execute($proc);

Related

mysql procedure with if condition

I'm in my first databases class and I'm trying to write a conditional block for a mysql procedure.
This is the procedure:
delimiter //
CREATE PROCEDURE add_ascent(IN cid INT, IN pid INT)
BEGIN
DECLARE count_ascents INT;
SET count_ascents = 0;
SELECT COUNT(`cid`) INTO count_ascents FROM ascents WHERE `cid`=cid AND `pid`=pid;
IF count_ascents < 1 THEN
INSERT INTO ascents (`cid`, `pid`) VALUES (cid, pid);
UPDATE climbers SET climbers.ascents = climbers.ascents + 1 WHERE climbers.id=cid;
UPDATE problems SET problems.ascents = problems.ascents + 1 WHERE problems.id=pid;
END IF;
END;
//
delimiter ;
The goal of the procedure is to only perform the insert and updates if the (cid, pid) pair is not in the the ascents database. After testing, the program doesn't seem to go into the if block at all.
FYI, you might want to consider using an UPSERT, instead of "select/if/insert". For example, mySQL offers INSERT ON DUPLICATE KEY UPDATE.
Here, I suggest:
giving your parameters a DIFFERENT name than the column name, for example iCid and iPid, then
Typing SELECT COUNT(cid) INTO count_ascents FROM ascents WHERE cid=iCid AND pid=iPid and checking the result.

How to return the value of a column immediately after an INSERT statement? [duplicate]

Is it possible to insert a row and get the values inserted in the same query?
Something like...
INSERT INTO `items` (`item`, `number`, `state`)
(SELECT '3', `number`, `state` FROM `item_bug` WHERE `id`='3')
And then, get ID and execute a
SELECT * FROM `items` WHERE `id`='$id'
But using only one query.
Execute your insert statement and then you can do this:
SELECT * FROM `items` WHERE `id`= LAST_INSERT_ID()
you can call a stored procedure which will perform the insert and return a resultset in a single call from your app layer to mysql:
Stored procedure call
mysql> call insert_user('bar');
+---------+----------+
| user_id | username |
+---------+----------+
| 1 | bar |
+---------+----------+
1 row in set (0.02 sec)
$sqlCmd = sprintf("call insert_user('%s')", ...);
Simple example:
drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) unique not null
)
engine=innodb;
drop procedure if exists insert_user;
delimiter #
create procedure insert_user
(
in p_username varchar(32)
)
begin
declare v_user_id int unsigned default 0;
insert into users (username) values (p_username);
set v_user_id = last_insert_id();
-- do more stuff with v_user_id e.g. logs etc...
select * from users where user_id = v_user_id;
end#
delimiter ;
call insert_user('bar');
No, it's not possible in MySQL (unlike PostgreSQL, SQL Server and PL/SQL in Oracle).
You will have to do it in separate queries.
You can do this using multiple statements if you like to choose that route. Firstly when you connect to your database make sure that multiple statements is set to true:
var connection = mysql.createConnection({
host: databaseHost,
user: databaseUser,
password: databasePassword,
database: databaseName,
multipleStatements: true
});
Then you can just define your sql as:
var sql = "your insert statement; your select statement";
Just separate individual statements using the semi colon. Your select result will be results[1] in this example.
if you are using php then
instead of this you can use
mysql_insert_id();
which will give the id of last inserted record.
The other data will be same as inserted.
Only id will change which you can get by mysql_insert_id()
So you do not need to run second query.

Mysql trigger to insert on two connected tables

I have 3 mysql tables:
user_followers has columns id,user_id
notification has columns id,user_id
notification_object has columns notification_id , type
On insert on user_followers i want to insert
user_id=New.user_id in notification
and then using the id of notification just inserted
notification_object.type = "2" and notification_object.notification_id = just inserted id in notifcication table
now the problem is how can i find the id of notifcation table:
DELIMITER //
CREATE TRIGGER follow_notification AFTER INSERT ON user_friends
FOR EACH ROW
Begin
insert into notification(user_id) values(New.user_id);
insert into notification_object(notification_id,type) values(????,"2");
End
//
if notifications.id is auto-incremented, mysql includes a function last_insert_id() that will return (with caveats) the lastly inserted id.
DELIMITER //
CREATE TRIGGER follow_notification AFTER INSERT ON user_friends
FOR EACH ROW
Begin
declare v_notification_id INT;
insert into notification(user_id) values(New.user_id);
/* set a variable to the last id inserted to the db */
set v_notification_id=(select last_insert_id());
/* use the variable in the next insert */
insert into notification_object(notification_id,type) values(v_notification_id,"2");
End//

How to write a stored procedure to insert values in multiple tables

How do I write a stored procedure to add a person record with multiple addresses?
It is easy if the person has only one address but I'm not sure how to write a stored procedure to add a person with multiple addresses.
Here is the stored procedure to add a person with one address:
DELIMITER $$
CREATE PROCEDURE `log`.`spAddPerson` (
IN personID INT,
IN personName VARCHAR(100),
IN addressLine1 VARCHAR(45),
IN addressLine2 VARCHAR(45),
IN myCity VARCHAR(45),
IN myState VARCHAR(45),
IN myCountry VARCHAR(45)
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
INSERT INTO person VALUES(personID,personName);
-- addressid is automatically generated
INSERT INTO address(Line1, Line2,City,State,Country) VALUES
(addressLine1, addressLine2, myCity,myState, myCountry);
INSERT INTO personAddress(personID, last_insert_id());
COMMIT;
END
The above code works fine. However, I do not know how to handle a person with multiple addresses without writing a separate stored procedure. Is there a simple way to do this?
You cannot pass a variable number of variables to a procedure, nor a non-scalar type.
A possible trick would be building a temporary table with the addresses before calling this procedure. Either the temporary table is pre-determined, or pass its name as a VARCHAR parameter(and use it to build dynamic SQL statements). Eg:
CREATE PROCEDURE spAddPerson (tmp_table VARCHAR(10), ...)
BEGIN
...
PREPARE s AS CONCAT(
'INSERT INTO address (line1, ...) VALUES SELECT * FROM ', tmp_table
);
EXECUTE s;
...
END
-- use it like this
CREATE TEMPORARY TABLE tmp_addresses (line1 VARCHAR(255), ...);
INSERT INTO tmp_addresses VALUES ('1 Cherry Lane'), ... ;
CALL spAddPerson ('tmp_addresses', ...);
However, I would rather split the action in two parts. Do you really want to prevent the creation of the person altogether if its address creation fails? And even then, wouldn't you want to advise your user why the transaction failed (user creation or address creation)?
I would rather treat these two exceptions separately at the application level:
issue a "START TRANSATION"
try to insert a person (call stored proc 1)
if it failed, rollback and notify user
for each address
try to insert an address (call stored proc 2)
if it failed, rollback and notify user
issue a "COMMIT"
> DECLARE #LAST_INSERT_ID INT
> DECLARE #EXECUTION_OK char(1)
> SET #EXECUTION_OK = 1
>
> insert into base_table(imgPath,store,apparelType) values (imgPath,store,apparelType)
>
> SELECT #LAST_INSERT_ID = SCOPE_IDENTITY()
>
> insert into data_table(cvID,color) values (#LAST_INSERT_ID, color)
> GO
>
> If exists( Select cvID from data_table where cvID= #LAST_INSERT_ID)
> Begin
> #EXECUTION_OK = 0
> End

Stored procedure for Inserting Data into 3 tables. Not working.

I have 3 tables-
1. Country (CountryName, CID (PK- AutoIncrement))
2. State (SID(PK- AutoIncrement), StateName, CID (FK to Country)
3. City (CityName, CID, SID (FK to State)
Now I need to insert only the name into the three tables with CountryName, StateName and CityName.. The IDs need to get updated.
Create PROCEDURE sp_place(
#CountryName char(50),
#StateName varchar(50),
#CityName nchar(20)
)
AS
DECLARE #CountryID int, #StateID int, #CityID int;
Set NOCOUNT OFF
BEGIN TRANSACTION
INSERT INTO dbo.Country VALUES (#CountryName);
SET #CountryID = SCOPE_IDENTITY();
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
Insert into dbo.State VALUES (#StateName, #CountryID);
SET #StateID = SCOPE_IDENTITY();
IF ##ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
Insert into dbo.City VALUES (#CityName, #StateID);
SET #CityID= SCOPE_IDENTITY();
Commit
When I Enter Country twice, the value shouldn't get changed.
Eg: If I enter India the value of CountryID=1, when I again enter India, the value of CountryID shouldn't get increased.
How'd I perform that? My SP changes for every insertion.
You can check if the country already exist and retrieve the countryID
IF NOT EXISTS(Select 1 FROM Country Where CountryName=#Country)
BEGIN
INSERT INTO dbo.Country VALUES (#CountryName);
SET #CountryID = SCOPE_IDENTITY();
END
ELSE
Select #CountryID = CountryID From Country Where CountryName=#Country
You can do the same for State and City if required
Hello try with this syntax
IF EXISTS (SELECT * FROM Country WHERE CountryName= #CountryName)
BEGIN
UPDATE dbo.Country
SET CountryName = #CountryName
WHERE CountryId = (SELECT CountryId FROM dbo.Country WHERE CountryName= #CountryName);
END
ELSE
BEGIN
INSERT INTO dbo.Country(CountryName) VALUES (#CountryName);
END
-- For the identity you must just add identity to your column in your creation script
Why dont you set Unique Constraint on CountryName column that won't allow you to insert duplicate countries at all
You need the MERGE syntax
http://technet.microsoft.com/en-us/library/bb510625.aspx
or to check manually (ie: with IF EXISTS (...) ) for the existence of the country before inserting.