Update table row with inserted identity ID - sql

I have the following query:
INSERT INTO dbo.Products
( Code ,
ProducerCode ,
CustomerId ,
EanCode ,
ChangedDateTime ,
ChangedById ,
Deleted
)
SELECT Code ,
ProducerCode ,
CustomerId ,
EanCode ,
GETDATE(),
GETDATE(),
0
FROM dbo.BulkProducts
WHERE ProductId is NULL AND BulkProducts.BulkId = #BulkId
The Products table has an IDENTITY ID column, which is assigned automatically on insert. What I want to achieve is, after the insertion in Products, have the assigned ID of the product in the row from BulkProducts. I have read a bit about##IDENTITY, IDENT_CURRENT and SCOPE_IDENTITY but I cannot seem to get it to work for my example. Any help appreciated. I am using SQL Server 2012.

You can achieve it using Output clause, like this -
DECLARE #OutProduct TABLE
(
ProductID INT,
Code INT
)
INSERT INTO dbo.Products
( Code ,
ProducerCode ,
CustomerId ,
EanCode ,
ChangedDateTime ,
ChangedById ,
Deleted
)
OUTPUT INSERTED.ID, INSERTED.Code INTO #OutProduct (ProductID, Code)
SELECT Code ,
ProducerCode ,
CustomerId ,
EanCode ,
GETDATE(),
GETDATE(),
0
FROM dbo.BulkProducts
WHERE ProductId is NULL AND BulkProducts.BulkId = #BulkId
So Now all your inserted data are in #OutProduct table. Now you can update your BulkProducts table using that temp table like below.
UPDATE bprod
SET productID = tmp.ProductID
FROM BulkProducts bprod
INNER JOIN #OutProduct tmp
ON bprod.Code = tmp.Code
WHERE bprod.ProductId is NULL AND bprod.BulkId = #BulkId

Apparently this cannot be solved without a MERGE. The final solution looks like this:
MERGE INTO dbo.Products
USING dbo.BulkProducts AS src
ON 1 = 0 -- Never match
WHEN NOT MATCHED THEN
INSERT(EanCode, ChangedDateTime, ChangedById, Deleted)
VALUES(src.EanCode, GETDATE(), GETDATE(), 0)
OUTPUT
inserted.Id,
src.Id
INTO #OutProduct;
And like this, my #OutProduct table contains tuples of BulkProductId and ProductId which I can then use to update my BulkProducts table.

Related

i want copy data from table to another without duplicate using triggers

i have two tables
in table number one it's add rows every moment depend on user insert
and in table number two i want to copy every row has been added on table one but with specific criteria
and also table number two have some additional columns i need them later
i want do that by triggers but i don't know how to do that
i'v already try stored procedure but not automatically
INSERT INTO ax.RETAILTRANSACTIONSALESTRANS2
(
[BARCODE]
, [CREATEDDATETIME]
,[Name]
, [ITEMID]
, [NETAMOUNTINCLTAX]
, [QTY]
, [STAFFID]
, [TERMINALID]
, [TRANSDATE]
,[PERIODICPERCENTAGEDISCOUNT]
,[ReceiptID]
)
SELECT ab.[BARCODE]
, ab.[CREATEDDATETIME]
,[ax].[ECORESPRODUCTTRANSLATION].[NAME]
, ab.[ITEMID]
, ab.[PRICE]
, ab.[QTY]
, ab.[STAFFID]
, ab.[TERMINALID]
, ab.[TRANSDATE]
, ab.[PERIODICPERCENTAGEDISCOUNT]
,ab.RECEIPTID
FROM ax.RetailTransactionSalesTrans ab
inner join [ax].[INVENTTABLE] on ab.[ITEMID] =[ax].[INVENTTABLE].[ITEMID]
inner join [ax].[ECORESPRODUCTTRANSLATION] on [ax].[INVENTTABLE].PRODUCT =[ax].[ECORESPRODUCTTRANSLATION].[PRODUCT]
LEFT JOIN ax.RETAILTRANSACTIONSALESTRANS2 a ON
a.[BARCODE] = ab.[BARCODE]
AND a.[CREATEDDATETIME] = ab.[CREATEDDATETIME]
AND a.[ITEMID] = ab.[ITEMID]
AND a.[NETAMOUNTINCLTAX] = ab.[PRICE]
AND a.[QTY] = ab.[QTY]
AND a.[STAFFID] = ab.[STAFFID]
AND a.[TERMINALID] = ab.[TERMINALID]
AND a.[TRANSDATE] = ab.[TRANSDATE]
AND a.[PERIODICPERCENTAGEDISCOUNT]=ab.[PERIODICPERCENTAGEDISCOUNT]
and a.Process=null and a.Checked=null and a.[Select]=null
where ab.[QTY]>0 and ab.[RECEIPTID]!='' and ab.[TRANSDATE] >= DATEADD(day, #daycount*-1, GetDate())
and NOT EXISTS(select * from ax.RETAILTRANSACTIONSALESTRANS2 where [CREATEDDATETIME] = ab.[CREATEDDATETIME])
i want to convert that as trigger but i don't how do that
note: #daycount i take it from another table but i pass that by my program
you can use the below and edit the needed columns , the idea is FROM Inserted you can select all rows that inserted to the main table.
CREATE TRIGGER TRetailTransactionSalesTrans ON RetailTransactionSalesTrans
FOR INSERT
AS
BEGIN
INSERT INTO RETAILTRANSACTIONSALESTRANS2
SELECT [BARCODE]
,[CREATEDDATETIME]
,[Name]
,[ITEMID]
,[NETAMOUNTINCLTAX]
,[QTY]
,[STAFFID]
,[TERMINALID]
,[TRANSDATE]
,[PERIODICPERCENTAGEDISCOUNT]
,[ReceiptID]
FROM Inserted;
END

Insert where not exists Violation of PRIMARY KEY

I'm having troubles with an Insert where not exists and I'm not sure if a MERGE statement would be more efficient or what's wrong with my statement.
I have en existing View and need to insert the new records of this View into a Table.
The Table looks like:
CREATE TABLE [dbo].[ser_number_all]
(Serialnumber nvarchar(100) PRIMARY KEY,
TypeName nvarchar(max),
Date datetime,
Parent_Serialnumber nvarchar(100),
JobNumber nvarchar(30),
ProductNode hierarchyid,
);
The Insert statement looks like this:
insert into [dbo].[ser_number_all]
( Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode)
select Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode
from dbo.Hierachical_View_with_Jobnumbers as ser_number_all
where not exists (select 1
from Hierachical_View_with_Jobnumbers as hv
where hv. Serialnumber = ser_number_all.Serialnumber
and hv. TypeName = ser_number_all.TypeName
and hv. Date = ser_number_all.Date
and hv. Parent_Serialnumber = ser_number_all.Parent_Serialnumber
and hv. JobNumber = ser_number_all.JobNumber
and hv. ProductNode = ser_number_all.ProductNode);
As long the View has not any new records, it looks ok and I'm not getting any error, the output is 0 records as it should be.
When I add a new record to the origin table and the view has 1 record more, I'm always getting this error:
Msg 2627, Level 14, State 1, Line 4
Violation of PRIMARY KEY constraint 'PK__ser_numb__F2753A12C4ABA976'. Cannot insert duplicate key in object 'dbo.ser_number_all'. The duplicate key value is (.x3666AB05).
The statement has been terminated.
I don't get it why it will insert a duplicate value in the primary key column because in my WHERE clause I can't see any mistake.
I have also tried with IS NULL instead = ser_number_all.TypeName and for all other columns where it could have a NULL value, but still the same.
Again, I'm coming from Oracle and it looks like I have to learn many diversities with MS SQL compared to Oracle.
Appreciate any suggestion :-)
Thx
EDIT:
Here the code of the View:
CREATE VIEW [dbo].[Hierachical_View_with_Jobnumbers]
AS
WITH ProductList
AS
(
SELECT p.Serialnumber,
p.Type_Id,
p.Parent_Serialnumber,
p.ActiveJob_Jobnumber as JobNumber,
N'/' + CONVERT(NVARCHAR(4000), ROW_NUMBER() OVER (ORDER BY p.Serialnumber)) + N'/' AS ProductNode_AsChar
FROM Products AS p
WHERE p.Parent_Serialnumber IS NULL
UNION ALL
SELECT p.Serialnumber,
p.Type_Id,
p.Parent_Serialnumber,
JobNumber,
pl.ProductNode_AsChar + CONVERT(NVARCHAR(4000), ROW_NUMBER() OVER (ORDER BY p.Serialnumber)) + N'/'
FROM Products AS p
INNER JOIN ProductList AS pl ON p.Parent_Serialnumber = pl.Serialnumber
)
SELECT Serialnumber,
pt.Name as TypeName,
Parent_Serialnumber,
JobNumber,
CONVERT(HIERARCHYID, ProductNode_AsChar) AS ProductNode
FROM ProductList as pl
INNER JOIN ProductTypes as pt on pl.Type_Id = pt.Id;
#TheGameiswar
Sorry, now I got it what you meant ;-) Stupid me...
Here the solution which works now with correctly correlating:
insert into [dbo].[ser_number_all]
( Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode)
select Serialnumber
, TypeName
, Date
, Parent_Serialnumber
, JobNumber
, ProductNode
from dbo.Hierachical_View_with_Jobnumbers as hv
where not exists (select 1
from ser_number_all as sna
where hv. Serialnumber = sna.Serialnumber);
Thank you all for your time and guiding me to the right direction :-)

Output Inserted.Id AND another field

I have the following query:
DECLARE #OutProduct TABLE
(
ProductID INT,
BulkProductId INT
)
INSERT INTO dbo.Products
( EanCode ,
ChangedDateTime ,
ChangedById ,
Deleted
)
OUTPUT INSERTED.ID, BulkProducts.Id INTO #OutProduct (ProductID, BulkProductId)
SELECT EanCode ,
GETDATE(),
GETDATE(),
0
FROM dbo.BulkProducts
WHERE ProductId is NULL
Assuming Products.Id & BulkProducts.Id are auto-incrementing identity columns:
What I'm trying to achieve:
#OutProduct temp table contains tuples made up of the just-inserted Products.Id and the Id of the row in BulkProducts.
What I've stumbled upon: BulkProducts.Id cannot be used in the OUTPUT INSERTED.ID, BulkProducts.Id INTO statement, as it's not valid syntax.
How can I solve this?
EDIT: I'm using SQL Server 2012.
You might want to explore MERGE:
MERGE INTO dbo.Products
USING dbo.BulkProducts AS src
ON 1 = 0 -- Never match
WHEN NOT MATCHED THEN
INSERT(EanCode, ChangedDateTime, ChangedById, Deleted)
VALUES(src.EanCode, GETDATE(), GETDATE(), 0)
OUTPUT
inserted.Id,
src.Id
INTO #OutProduct;
Reference:
Dr. OUTPUT or: How I Learned to Stop Worrying and Love the MERGE by Adam Machanic

Distinct Rows In Sql

I have a table that record events as it happens and as such could record same ID multiple times. I want to return single row for each unique RefID as 'Y' is substituted for 'N' in relevant columns. Below is a mock-up
DECLARE #Ref TABLE
(
RefID INT
, InvoiceNo INT
, InvoicedDate Date
, CustID INT
, PaidOnTime CHAR(1)
, Paidlate CHAR(1)
, PaidByCash CHAR(1)
, PaidByCard CHAR(1)
)
INSERT INTO #Ref VALUES
(23,50,'22-jun-2015', 11,'Y','N','Y','N')
, (23,50,'22-jun-2015', 11,'Y','N','N','Y')
, (27,11,'12-Aug-2015', 11,'Y','N','N','Y')
, (27,11,'22-Aug-2015', 11,'N','Y','N','Y')
, (45,67,'28-jun-2015', 11,'N','Y','Y','N')
, (45,67,'28-jun-2015', 11,'N','N','N','Y')
, (48,51,'18-jun-2015', 11,'Y','N','Y','N')
SELECT * FROM #Ref --would return values like so:
For example, RefID of 23 should be "23,50,22/06/2015,11,Y,N,Y,Y"
Group by the columns you want to be unique and use max() to get the highest value for every group (since Y is alphabetically higher than N)
SELECT RefID, InvoiceNo, InvoicedDate, CustID,
max(PaidOnTime), max(Paidlate), max(PaidByCash), max(PaidByCard)
FROM #Ref
GROUP BY RefID, InvoiceNo, InvoicedDate, CustID

SQL Server 2008 - Stored inserted IDs in a variable table for another query use later

I have an INSERT query to insert multiple records and returns a set if CompanyID that inserted, and this query is working fine. I would like to stored those returned CompanyIDs into a table variable, so I can run another query after that using those CompanyIDs. I tried, but got stuck.
Please help.
-- Create a table variable
DECLARE #CompanyIDs TABLE
(
CompanyID INT NOT NULL
)
INSERT INTO #CompanyIDs -- STUCK right here and it failed
-- This INSERT query is working fine, and will return the CompanyIDs that inserted.
INSERT INTO [Apps].[dbo].[ERP_Company]
(
[Name]
,[Type]
,[ImportFrom]
,[InActiveFlag]
,[CreatedDate]
,[CreatedBy]
,[CompanyOwnerID]
,[ModifiedDate]
,[HQAddress]
,[HQCity]
,[HQState]
,[HQZip]
,[Type2]
,[Segment]
,[Industry]
)
output inserted.CompanyID
SELECT DISTINCT(Company) AS Company
, 'End-User'
, 'MarketingUpload'
, '0'
, GETDATE()
, '1581'
, '1581'
, GETDATE()
, [Address]
, City
, [State]
, ZipCode
, 'Customer'
, Segment
, Industry
FROM dbo.Import_CompanyContact icc
WHERE RefNum = 14
AND MatchFlag = 3
AND NOT Exists (SELECT * FROM dbo.ERP_Company
WHERE REPLACE(Name, '''', '') = REPLACE(icc.Company, '''', '')
)
OUTPUT inserted.CompanyID INTO #YourTable