Push deleted items into temporary table after MERGE - sql

A simple query on the INTO clause. When i try the below statement, the items get pushed into CustomersBackup2013 whether the table exists or not.
SELECT *
INTO CustomersBackup2013
FROM Customers;
However, when i try using the into clause in a MERGE like
MERGE TargetTable tt
USING SyncTable st on <condition>
.
.
WHEN Not MATCHED BY SOURCE
DELETE
OUTPUT deleted.* INTO #Sometemptable;
I get an error saying invalid object name '#Sometemptable'
Isnt it supposed to create the table if it does not exist? Is there something I am doing wrong.
Is there any way i can modify the clause to push items into #Sometemptable?

No, the table has to exists for the output clause to work.
First create the #temp table and then you can output deleted values in it. Columns in the temp table must match columns from output by ordinal and type.

select into table creates a table if required. it is much like oracle's create table as select. see here select into table
merge only inserts, updates or deletes

Related

Using value in deleted record in SQL Server

I need to delete record and search by its Id in anther query as this
select * from Flat
WHERE Flat.nu in (delete top (1) from temp output deleted.nu)
I think you can't run those with each other.
I suggest you to use a (temporary table): tempIds(id int).
Then use output clause like this:
delete top(1) from temp
output deleted.id into tempIds;
Note: It's better to use CTE to delete first row.
Then query over tempIds table and after that clear tempIds.
Try this way.. it may help you out.
DECLARE #ID_CAPTURE TABLE (ID Int)
DELETE TOP(1) FROM TEMP
OUTPUT deleted.Nu into #ID_CAPTURE
SELECT * FROM FLAT WHERE NU IN (SELECT * FROM #ID_CAPTURE)
The above snippet will work for you in case of multiple records too.

Add column with data from another stdinfo5table into viewtable in sql query

select name into viewtable from stdinfo5
My error is:
There is already an object named 'viewtable' in the database.
Can someone explain: I want column with data (adding) into viewtable from the stdinfo5 table.
Thanks!
select ... into SomeTarget from SomeSource will create a physical table with the name SomeTarget!
You can use DROP TABLE SomeTarget to delete this table (carefull with real data!!!) or, what might be better, use select ... into #SomeTarget ....
The # before the name will create this table as temp table which is deleted automatically when it gets out of scope.
In your case it seems, that you do not want to delete the table, but you just want to add one more column. In this case you'd need something like ALTER TABLE viewtable ADD TheColumnName TheColumnType; and then use an UPDATE statement to fill this column. If possible, it was easier to delete the table and re-create it with the missing column...

What is the meaning of 1=2 when copying database structure?

I've come across
create table new_table as select * from old_table where 1=2;
What is the meaning of the where 1=2 condition and what function does it perform?
1=2 always evaluates as false. This is a common trick to utilize the create as select to copy a table's structure without copying any of its rows (as none of them will pass the test of 1=2).
Just it will copy the structure of a table not data present in a table. 1=0 or 1=2 will always returns false in where clause so select query doesn't return any rows from table it's just a trick for create a table as like another table in your schema .
1=2 essentially results in none of the current records in the old table being selected when you create the new table and thus that you only use the structure of the old table to make the new table.
WHERE 1=2 means a false condition WHERE no rows will be taken from the table and the target table will be similar to the source table except data

OUTPUT Clause in Sql Server (Transact-SQL)

I Know that OUTPUT Clause can be used in INSERT, UPDATE, DELETE, or MERGE statement. The results of an OUTPUT clause in a INSERT, UPDATE, DELETE, or MERGE statements can be stored into a target table.
But, when i run this query
select * from <Tablename> output
I didn't get any error. The query executed as like select * from tablename with out any error and with same no. of rows
So what is the exact use of output clause in select statement. If any then how it can be used?
I searched for the answer but i couldn't find a answer!!
The query in your question is in the same category of errors as the following (that I have also seen on this site)
SELECT *
FROM T1 NOLOCK
SELECT *
FROM T1
LOOP JOIN T2
ON X = Y
The first one just ends up aliasing T1 AS NOLOCK. The correct syntax for the hint would be (NOLOCK) or ideally WITH(NOLOCK).
The second one aliases T1 AS LOOP. To request a nested loops join the syntax would need to be INNER LOOP JOIN
Similarly in your question it just ends up applying the table alias of OUTPUT to your table.
None of OUTPUT, LOOP, NOLOCK are actually reversed keywords in TSQL so it is valid to use them as a table alias without needing to quote them, e.g. in square brackets.
OUTPUT clause return information about the rows affected by a statement. OUTPUT Clause is used along with INSERT, UPDATE, DELETE, or MERGE statements as you mentioned. The reason it is used is because these statements themselves just return the number of rows effected not the rows effected. Thus the usage of OUTPUT with INSERT, UPDATE, DELETE, or MERGE statements helps the user by returning actual rows effected.
SELECT statement itself returns the rows and SELECT doesn't effect any rows. Thus the usage of OUTPUT clause with SELECT is not required or supported. If you want to store the results of a SELECT statement into a target table use SELECT INTO or the standard INSERT along with the SELECT statement.
EDIT
I guess I misunderstood your question. AS #Martin Smith mentioned its is acting an alias in the SELECT statement you mentioned.
IF OBJECT_ID('tempdelete') IS NOT NULL DROP TABLE tempdelete
GO
IF OBJECT_ID('tempdb..#asd') IS NOT NULL DROP TABLE #asd
GO
CREATE TABLE tempdelete (
name NVARCHAR(100)
)
INSERT INTO tempdelete VALUES ('a'),('b'),('c')
--Creating empty temp table with the same columns as tempdelete
SELECT * INTO #asd FROM tempdelete WHERE 1 = 0
DELETE FROM tempdelete
OUTPUT deleted.* INTO #asd
SELECT * FROM #asd
This is how you can put all the deleted records in to a table. The problem with that is that you have to define the table with all the columns matching the table from which you are deleting. This is how i do it.

Filtering duplicate records while importing data from source table to target table

This may be a simple query to some of you. But I am not strong in Sql, so expecting some solution for my problem.
I have 2 tables, ProductVenueImport and SupplierVenueImport.
We are dumping all the records from SupplierVenueImport to ProductVenueImport using MERGE clause and a Temp table. Temp will have valid records from SupplerVenuImport and from Temp table we are importing records to ProductVenueImport.
But before importing data to ProductVenueImport from Temp table I need to check for the duplicate records in my target (ProductVenueImport).
For example if I am importing a record with name as 'A', I need to look into ProductVenueImport whether 'A' already existing or not. If it is not existing then only I need to insert 'A' otherwise not.
Could somebody tell me how to do this?
Is using Cursors only the option?
Thanks,
Naresh
Assuming the Temp table itself doesn't have duplicates, you could use MERGE like this:
Insert non-existing products.
Do a NO-OP in case of an existing product.
Use $action in the OUTPUT clause to mark which rows were considered for insertion (and inserted) and which for update (but not really updated).
This is what I mean:
DECLARE #noop int; -- needed for the NO-OP below
MERGE INTO ProductVenueImport AS tgt
USING Temp AS src
ON src.ProductID = tgt.ProdutID
WHEN NOT MATCHED THEN
INSERT ( column1, column2, ...)
VALUES (src.column1, src.column2, ...)
WHEN MATCHED THEN
UPDATE SET #noop = #noop -- the NO-OP instead of update
OUTPUT $action, src.column1, src.column2, ...
INTO anotherTempTable
;
I think this would do this :
INSERT INTO PRODUCTTBL(FEILD1, FIELD2, FIELD3, FIELD4, FIELD5)
SELECT (FIELD1,FIELD2,FIELD3,FIELD4,FIELD5) FROM TEMP WHERE CRITERIAFIELD NOT IN(SELECT DISTINCT CRITERIAFIELD FROM PRODUCTTBL)
This should allow you to check for duplicates in a table
select columnname from tablename
group by columnname
having count(columnname) >1
sorry if I am not getting the question right, can't you use the merge statement on the source table with "When not matched Insert" to insert the new records alone
so in your case it should be like this
merge into ProductVenueImport using temp on (<condition for duplicate>)
when not matched then insert <clause>;
the merge clause will make sure that no duplicate records are inserted into your source table.