Insert Into two tables with conditions - sql

Im doing a reservation application and was wondering how would i handle the following scenario; if a booking has 2 or more "extra" items on it how do i create a SP or a trigger even to handle this? the SP i have now works fine for a booking with a single extra item on it. Im i making any sense?
ALTER PROCEDURE [dbo].[CreateBooking]
#DateFrom datetime,
#DateTo datetime,
#RoomID int,
#PersonID int,
#ProductID int,
#OrderAmount int
AS
BEGIN TRANSACTION
SET NOCOUNT ON;
INSERT INTO booking(created_on, startdate, enddate, room_id, person_id)
VALUES (getdate(), #DateFrom, #DateTo, #RoomID, #PersonID)
IF ##error <> 0
ROLLBACK TRANSACTION
ELSE
INSERT INTO booking_details (booking_id,prod_id,order_amount)
VALUES (SCOPE_IDENTITY(), #ProductID, #OrderAmount)
COMMIT TRANSACTION

You can pass an xml parameter then loop through it and write them.
CREATE PROCEDURE
SelectByIdList(#productIds xml) AS
DECLARE #Products TABLE (ID int)
INSERT INTO #Products (ID) SELECT
ParamValues.ID.value('.','VARCHAR(20)')
FROM #productIds.nodes('/Products/id')
as ParamValues(ID)
SELECT * FROM
Products INNER JOIN
#Products p ON Products.ProductID = p.ID

Related

While loop on SELECT, DELETE ,INSERT statement

I have list of duplicate Transaction IDs and want to insert first the information to table Customer_Deleted_OrderRecordes as log then delete them from Orderstable.
This is my query:
DECLARE #Date Datetime
DECLARE #CustomerName nvarchar(90)
DECLARE #ItemID int
DECLARE #TransactionID int
DECLARE #Invoice int
----selecting values------
SELECT
#Date = O.date,
#CustomerName = c.FullName=,
#ItemID = O.ItemID,
#TransactionID = O.TransactionID,
#Invoice = O.Invoice
FROM
CustomerTable c
INNER JOIN
OrdersTable O ON c.ID = O.CustomerId
WHERE
O.TransactionID IN (1680339,1680340,1680341,1680342,1680343,1680344,1680345,1680346,1680347,1680348,1680349,1680350,1680351,1680352,1680353,1680354,1680355,1680356,1680357,1680358,1680359)
---This will insert values before deleting as log ---
INSERT INTO Customer_Deleted__OrderRecordes ([Date], [CustomerName], [ItemID], [TransactionID], [Invoice])
VALUES (#date, #CustomerName, #ItemID, #TransactionID, #Invoice)
---This will delete values after inserting
DELETE FROM OrdersTable
WHERE TransactionID IN (1680339,1680340,1680341,1680342,1680343,1680344,1680345,1680346,1680347,1680348,1680349,1680350,1680351,1680352,1680353,1680354,1680355,1680356,1680357,1680358,1680359)
My query only effects one row instead of the all values selected in the select statement. How to write a while loop on SELECT, INSERT, DELETE statements?
I don't get why you need to declare variables and use a loop, you can just insert with a select and then delete:
INSERT Customer_Deleted_OrderRecordes
(Date, CustomerName, ItemID, TransactionID, Invoice)
SELECT O.date, c.FullName, O.ItemID, O.TransactionID, O.Invoice
FROM CustomerTable c
INNER JOIN OrdersTable O ON c.ID = O.CustomerId
WHERE O.TransactionID IN
(1680339, 1680340, 1680341, 1680342, 1680343, 1680344, 1680345,
1680346, 1680347, 1680348, 1680349, 1680350, 1680351, 1680352,
1680353, 1680354, 1680355, 1680356, 1680357, 1680358, 1680359)
And then just run the delete.
If you need a loop, (in current situation you wont need one), but as you said in comments there can be a situation where you would need to use variables and insert it according to the values, you can do a while loop like:
while #TransactionID < 1680359
begin
INSERT INTO Customer_Deleted_OrderRecordes (Date, CustomerName, ItemID, TransactionID, Invoice)
VALUES (#date, #CustomerName, #ItemID, #TransactionID, #Invoice)
#TransactionID++
end
You can also add the delete inside the loop before you update the counter variable, so after each inserted row it should delete that row in other table.
But I would highly suggest you not to use a loop when you don't need one, because it would add so much to execution time.

DELETE Trigger for Microsoft SQL

I am creating two triggers. One to catch the inserted values for the Rewards table and one to catch the deleted values for the Rewards table. The triggers main function is to record what type of change was made into the the audit table.
Rewards Table:
enter image description here
Audit Table:
enter image description here
The SQL for the audit_insert_trigger is :
CREATE TRIGGER tr_rewards_insert
ON Rewards AFTER INSERT, UPDATE
AS IF UPDATE(category)
BEGIN
DECLARE #category char(6)
DECLARE #type_change char(20)
SELECT #category = (SELECT category FROM inserted)
IF EXISTS (SELECT * FROM inserted)
BEGIN
SELECT #type_change = 'Inserted'
END
INSERT INTO audit_rewards
VALUES (
#category, USER_NAME(), GETDATE(), #type_change)
END
CREATE TRIGGER tr_rewards_delete
ON Rewards AFTER UPDATE
AS IF UPDATE(category)
BEGIN
DECLARE #category char(6)
DECLARE #type_change char(20)
SELECT #category = (SELECT category FROM deleted)
IF EXISTS (SELECT * FROM deleted)
BEGIN
SELECT #type_change = 'Deleted'
END
INSERT INTO audit_rewards
VALUES (
#category, USER_NAME(), GETDATE(), #type_change)
END
My idea was to just replace where "inserted" was and put "deleted". I'm not really understanding 1. the logic as to why that will not work and 2. How to get the deleted values into the audit table and record that it was a delete.
Cannot make it in one trigger. Must be two independent triggers.
Your insert trigger is incorrect. I think it should be:
CREATE TRIGGER tr_rewards_insert
ON Rewards AFTER INSERT, UPDATE
AS IF UPDATE(category)
BEGIN
INSERT INTO audit_rewards
SELECT 'INSERTED, USER_NAME(), GETDATE(), category
FROM inserted;
END;
The DELETED trigger would basically be the same. Never assume that inserted and deleted have only a single row.
Figured out the answer:
CREATE TRIGGER tr_rewards_insert
ON Rewards AFTER INSERT, UPDATE
AS IF UPDATE(category)
BEGIN
DECLARE #category char(2)
DECLARE #type_change char(20)
SELECT #category = (SELECT category FROM inserted)
SELECT #type_change = 'Inserted'
INSERT INTO audit_rewards
VALUES (#category, USER_NAME(), GETDATE(), #type_change)
END
CREATE TRIGGER tr_rewards_delete
ON Rewards AFTER DELETE, UPDATE
AS IF UPDATE(category)
BEGIN
DECLARE #category char(2)
DECLARE #type_change char(20)
SELECT #category = (SELECT category FROM deleted)
SELECT #type_change =
INSERT INTO audit_rewards
VALUES (#category, USER_NAME(), GETDATE(), #type_change)
END

SQL Server: How to use result from one INSERT for another INSERT

I have a stored procedure that is meant to update two tables at once.
My problem here is that the first table has an auto-incrementing ID column ("commentID") and my second table has a relationship on this so I need the newly created ID from the first INSERT in order to make the second INSERT.
I tried the following which I can save without errors but it doesnt execute as it should and does not update the tables as intended.
Can someone tell me what I am doing wrong here ?
My SQL:
ALTER PROCEDURE [dbo].[MOC_UpdateComment]
#imgID int,
#commentID int = '999999',
#comment nvarchar(1000),
#lastUpdate nvarchar(50),
#modBy varchar(50)
AS
BEGIN
DECLARE #temp AS TABLE
(
commentID int
)
SET NOCOUNT ON;
BEGIN TRANSACTION;
INSERT INTO MOC_BlogComments
(
imgID,
comment
)
OUTPUT inserted.commentID INTO #temp(commentID)
SELECT #imgID,
#comment
INSERT INTO MOC_LogComments
(
commentID,
lastUpdate,
modTime,
modBy
)
SELECT commentID,
#lastUpdate,
GETDATE(),
#modBy
FROM #temp
COMMIT TRANSACTION;
END
DECLARE #imgID INT,
#commentID INT = '999999',
#comment NVARCHAR(1000),
#lastUpdate NVARCHAR(50),
#modBy VARCHAR(50)
DECLARE #MORC_BlogComments AS TABLE
(
id INT IDENTITY(1, 1) NOT NULL,
imgid INT,
comment VARCHAR(100)
)
DECLARE #MORC_LogComments AS TABLE
(
commentid INT,
lastupdate DATETIME,
modtime DATETIME,
modby VARCHAR(100)
)
DECLARE #TEMP AS TABLE
(
commentid INT
)
SET nocount ON;
BEGIN TRANSACTION;
INSERT INTO #MORC_BlogComments
(imgid,
comment)
output inserted.id
INTO #TEMP(commentid)
VALUES (#imgID,
#comment)
INSERT INTO #MORC_LogComments
(commentid,
lastupdate,
modtime,
modby)
SELECT commentid,
#lastUpdate,
Getdate(),
#modBy
FROM #temp
SELECT *
FROM #MORC_LogComments
Function SCOPE_IDENTITY() returns the identity of last insert operation. You can use it to get the value which you need to use in second INSERT statement
You can use it like this in your statement:
INSERT INTO MORC_BlogComments (imgID, comment)
VALUES (#imgID, #comment)
INSERT INTO MORC_LogComments (commentID, lastUpdate, modTime, modBy)
VALUES (SCOPE_IDENTITY(), #lastUpdate, GETDATE(), #modBy)

Stored procedure insert into function

I have two tables
First table is CUSTOMERS with columns CustomerId, CustomerName
Second table is LICENSES with columns LicenseId, Customer
The column Customer in the second table is the CustomerId from the First table
I wanted to create a stored procedure that insert values into table 2
Insert into Licenses (Customer)
Values(CustomerId)
How can I get this data from the other table?
Thanks in advance for any help
this looks to me like simply a syntax question - I think what you want is
INSERT INTO Licenses (Customer) SELECT CustomerId FROM customers where ...
CREATE PROCEDURE uspInsertToTable
#CustomerID INT OUTPUT,
#CustomerName VARCHAR(50),
#LicenseID INT,
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO CUSTOMERS
VALUES (#CustomerName);
SET #CustomerID=SCOPE_IDENTITY();
INSERT INTO LICENSES
VALUES (#LicenseID, #CustomerID)
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION;
END
END CATCH;
END;
];
if CustomerID is identity, I wish that it will be work... :)
If you're using SQL Server and your PK is autocorrelative using identity(1,1) do this:
CREATE PROC Register #CustomerName varchar(25)
AS BEGIN
INSERT INTO CUSTOMERS (Customer) VALUES (#CustomerName)
INSERT INTO LICENSES (SELECT MAX(CustomerId) FROM CUSTOMERS)
END
But if you don't want to use identity (1,1) do this:
CREATE PROC Register #CustomerName varchar(25)
AS BEGIN
DECLARE #idc int = SELECT MAX(CustomerId) FROM CUSTOMERS;
DECLARE #idl int = SELECT MAX(LicenseId) FROM LICENSES ;
INSERT INTO CUSTOMERS (CustomerId, CustomerName) VALUES (#idc,#CustomerName)
INSERT INTO LICENSES (LicenseId, Customer) VALUES (#idl,#idc)--I guess your field Customer is the foreign key
END

How to have multiple inserts in one sql query that uses the identities from the previous table

I am trying to insert data into many tables in one SQL Server stored procedure. I am also using the identities from the tables that I have inserted data into to then resolve the many to many relationship by writing those identities to another table.
In theory the logic seems to be there for the stored procedure, but on execution only the first insert statement has been executed. Please could anyone assist with this.
The stored procedure is as follows:
Create Procedure [dbo].[InsertAllCustomerDetails]
(
--#CustomerID Bigint output,
#Firstname varchar(100),
#LastName varchar(100),
#Initials varchar(10),
#Title varchar(20),
#DateCreated datetime,
#isDeleted Bit,
--#ContactNumberID BIGINT Output,
#ContactNumber Varchar(100),
#ContactTypeID bigint,
#Street Varchar(550),
#AreaID BIGINT,
#isPreferred Bit
--#AddressID Bigint OutPut
)
AS
Insert Into Customer
(
FisrtName,
LastName,
Initials,
[Title],
DateCreated,
isDeleted
)
Values
(
#Firstname,
#LastName,
#Initials,
#Title,
#DateCreated,
#isDeleted
)
Declare #CustomerID BIGINT
SELECT #CustomerID = ##IDENTITY
RETURN #CustomerID
--This will now insert the contact details for the customer
Insert Into ContactNumber
(
ContactNumber,
ContactTypeID
)
Values
(
#ContactNumber,
#ContactTypeID
)
Declare #ContactNumberID BIGINT
SELECT #ContactNumberID = ##IDENTITY
--This will insert into the CustomerContactNumber
Insert Into CustomerContactNumber
(
ContactNumberID,
CustomerID
)
Values
(
#ContactNumberID,
#CustomerID
)
--This will insert the address
Insert Into [Address]
(
Street,
AreaID,
isPreferred
)
Values
(
#Street,
#AreaID,
#isPreferred
)
Declare #AddressID BIGINT
SELECT #AddressID = ##IDENTITY
--This will insert the relationship for the customer Address table
Insert into CustomerAddress
(
CustomerID,
AddressID
)
Values
(
#CustomerID,
#AddressID
)
I see two things:
You seem to have a typo in the Customer insert:
Insert Into Customer
(
FisrtName, <-- should be FirstName?
LastName,
You are RETURNing after the Customer insert - that's why only the first one runs
Declare #CustomerID BIGINT
SELECT #CustomerID = ##IDENTITY
RETURN #CustomerID <---- This exits the sproc
--This will now insert the contact details for the customer
Insert Into ContactNumber
I'm guessing the RETURN was there for debugging and not removed since it's obscured by the indentation.