Using value in deleted record in SQL Server - sql

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.

Related

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.

Push deleted items into temporary table after MERGE

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

How do I delete one record matching some criteria in SQL? (Netezza)

I've got some duplicate records in a table because as it turns out Netezza does not support constraint checks on primary keys. That being said, I have some records where the information is the exact same and I want to delete just ONE of them. I've tried doing
delete from table_name where test_id=2025 limit 1
and also
delete from table_name where test_id=2025 rowsetlimit 1
However neither option works. I get an error saying
found 'limit'. Expecting a keyword
Is there any way to limit the records deleted by this query? I know I could just delete the record and reinsert it but that is a little tedious since I will have to do this multiple times.
Please note that this is not SQL Server or MySQL.This is for Netezza
If it doesn't support either "DELETE TOP 1" or the "LIMIT" keyword, you may end up having to do one of the following:
1) add some sort of an auto-incrementing column (like IDs), making each row unique. I don't know if you can do that in Netezza after the table has been created, though.
2) Programmatically read the entire table with some programming language, eliminate duplicates programmatically, then deleting all the rows and inserting them again. This might not be possible if they are references by other tables, in which case, you might have to temporarily remove the constraint.
I hope that helps. Please let us know.
And for future reference; this is why I personally always create an auto-incrementing ID field, even if I don't think I'll ever use it. :)
The below query works for deleting duplicates from a table.
DELETE FROM YOURTABLE
WHERE COLNAME1='XYZ' AND
(
COLNAME1,
ROWID
)
NOT IN
(
SELECT COLNAME1,
MAX(ROWID)
FROM YOURTABLENAME
WHERE COLNAME = 'XYZ'
GROUP BY COLNAME1
)
If the records are identical then you could do something like
CREATE TABLE DUPES as
SELECT col11,col2,col3,col....... coln from source_table where test_id = 2025
group by
1,2,3..... n
DELETE FROM source_table where test_id = 2025
INSERT INTO Source_table select * from duoes
DROP TABLE DUPES
You could even create a sub-query to select all the test_ids HAVING COUNT(*) > 1 to automatically find the dupes in steps 1 and 3
-- remove duplicates from the <<TableName>> table
delete from <<TableName>>
where rowid not in
(
select min(rowid) from <<TableName>>
group by (col1,col2,col3)
);
The GROUP BY 1,2,3,....,n will eliminate the dupes on the insert to the temp table
Does the use rowid is allowed in Netezza...As far as my knowledge is concern i don't think this query will executed in Netezza...

dynamically create table statement in sql

how to dynamically create a table with same columns as that of previous table. in sql
select * into new_table from table where 1 = 0
select * into new_table from table
Thats works in SQL2005
I believe that both of the above answers will work, but since you don't need the data and you just need the format, I would do the following:
select * into new_table from table
TRUNCATE new_table; -- I'm sure you know this, but just in case someone is new and doesn't, truncate leaves the table structure and removes all of the data.

Copy Data from a table in one Database to another separate database

Basically I have a two databases on SQL Server 2005.
I want to take the table data from one database and copy it to another database's table.
I tried this:
SELECT * INTO dbo.DB1.TempTable FROM dbo.DB2.TempTable
This didn't work.
I don't want to use a restore to avoid data loss...
Any ideas?
SELECT ... INTO creates a new table. You'll need to use INSERT. Also, you have the database and owner names reversed.
INSERT INTO DB1.dbo.TempTable
SELECT * FROM DB2.dbo.TempTable
SELECT * INTO requires that the destination table not exist.
Try this.
INSERT INTO db1.dbo.TempTable
(List of columns here)
SELECT (Same list of columns here)
FROM db2.dbo.TempTable
It's db1.dbo.TempTable and db2.dbo.TempTable
The four-part naming scheme goes:
ServerName.DatabaseName.Schema.Object
Hard to say without any idea what you mean by "it didn't work." There are a whole lot of things that can go wrong and any advice we give in troubleshooting one of those paths may lead you further and further from finding a solution, which may be really simple.
Here's a something I would look for though,
Identity Insert must be on on the table you are importing into if that table contains an identity field and you are manually supplying it. Identity Insert can also only be enabled for 1 table at a time in a database, so you must remember to enable it for the table, then disable it immediately after you are done importing.
Also, try listing out all your fields
INSERT INTO db1.user.MyTable (Col1, Col2, Col3)
SELECT Col1, COl2, Col3 FROM db2.user.MyTable
We can three part naming like database_name..object_name
The below query will create the table into our database(with out constraints)
SELECT *
INTO DestinationDB..MyDestinationTable
FROM SourceDB..MySourceTable
Alternatively you could:
INSERT INTO DestinationDB..MyDestinationTable
SELECT * FROM SourceDB..MySourceTable
If your destination table exists and is empty.
Don't forget to insert SET IDENTITY_INSERT MobileApplication1 ON to the top, else you will get an error. This is for SQL Server
SET IDENTITY_INSERT MOB.MobileApplication1 ON
INSERT INTO [SERVER1].DB.MOB.MobileApplication1 m
(m.MobileApplicationDetailId,
m.MobilePlatformId)
SELECT ma.MobileApplicationId,
ma.MobilePlatformId
FROM [SERVER2].DB.MOB.MobileApplication2 ma
Im prefer this one.
INSERT INTO 'DB_NAME'
(SELECT * from 'DB_NAME#DB_LINK')
MINUS
(SELECT * FROM 'DB_NAME');
Which means will insert whatsoever that not included on DB_NAME but included at DB_NAME#DB_LINK. Hope this help.
INSERT INTO DB1.dbo.TempTable
SELECT * FROM DB2.dbo.TempTable
If we use this query it will return Primary key error.... So better to choose which columns need to be moved, like
INSERT INTO db1.dbo.TempTable // (List of columns here)
SELECT (Same list of columns here)
FROM db2.dbo.TempTable
Try this
INSERT INTO dbo.DB1.TempTable
(COLUMNS)
SELECT COLUMNS_IN_SAME_ORDER FROM dbo.DB2.TempTable
This will only fail if an item in dbo.DB2.TempTable is in already in dbo.DB1.TempTable.
This works successfully.
INSERT INTO DestinationDB.dbo.DestinationTable (col1,col1)
SELECT Src-col1,Src-col2 FROM SourceDB.dbo.SourceTable
You can copy one table to other db table even with some additional columns.
insert into [SchoolDb1].[dbo].Student(Col1, Col2,Col3, CreationTime, IsDeleted)
select Col1, Col2,Col3,,getdate(),0 from [SchoolDb2].[dbo].Student
These are additional columns: (CreationTime is datatime and IsDeleted is boolean)
select * from DBA1.TABLENAMEA;
create table TABLENAMEA as (select * from DBA1.TABLENAMEA);
These manual way provides more flexibility, but at the same time, works for table whose size is smaller to few thousands.
Do select * from <table name> from DB, once whole table is displayed, scroll till it's bottom.
Right click and do Export table as Insert statement, provide the name of the destination table and export the table as .sql file.
Use any text editor to further do regular find and replace operation to include more column names etc.
Use the INSERT statement in destination DB.