SQL Server 2005, bulk UPDATE or INSERT - sql

I'm looking for a solution to perform Insert, on duplicate key Update like operation in SQL Server 2005. This operation might Insert or Update large number of entries. SQL Server 2008 has a neat operation MERGE which would do it perfectly, the problem is we're stuck with SQL Server 2005.
I've looked into standard solutions, but all of them are not good, because they assume, that only one entry is updated/inserted.
Does anyone know a way to replicate MERGE behavior in older versions of SQL Server?

Alex Kuznetsov's blog contains a suggestion using the OUTPUT clause of an UPDATE statement. To paraphrase the example from that blog entry (untested):
DECLARE #updated_ids table(id int)
UPDATE table
SET ...
OUTPUT inserted.id INTO #updated_ids
FROM table INNER JOIN data-to-insert ON table.id = data-to-insert.id
INSERT INTO table
SELECT ...
FROM data-to-insert
WHERE id NOT IN (SELECT id FROM #updated_ids)

Related

SQL trigger to insert data from one table to another if a condition is met

I am miserably failing to build a sql trigger (in background) where I want to insert data from one table to another if a certain condition is met, something like this:
Create trigger on table Invoice
If inv_number starts with inv
Then Insert into Document (var1,var2,var3) values (inv_number, inv_date, inv_amount)
Thanks
If you're using SQL Server (as I said in comments - triggers are highly vendor-specific, so if you're using something else, you'll have to adapt as needed), you can use something like this:
CREATE TRIGGER trgInvoiceInsert
ON dbo.Invoice
AFTER INSERT -- adapt if you need to run this after UPDATE or DELETE, too
AS
BEGIN
/* In SQL Server, if you inserting a bunch of rows
at once using an `INSERT INTO .... SELECT ....`
approach, then this trigger will be called only *ONCE*,
with all the inserted rows in the "Inserted" pseudo table.
Handle it accordingly - in a set-based manner
*/
INSERT INTO dbo.Document (col1, col2, col3)
SELECT i.inv_number, i.inv_date, i.inv_amount)
FROM Inserted i
WHERE i.inv_number LIKE 'inv%'
END
For further details, check out the official Microsoft documentation on SQL Server triggers

Updating columns values from another table SQL

I want to update my table from another table in another database.I have two table that has two same columns.There are ID and iexp column.What i want is update every row from k_monster table to my database's k_monster table but there are other columns such as iHP iMP so i want to just update iExp column.what do you suggest?
Assuming Target_Database is the database where the table is that you want to update and Source_Database is the database where the table is you are using to update from.
Your query should look something like this.....
USE [Target_Database]
GO
UPDATE t
SET t.iexp = S.iexp
FROM K_monster t
INNER JOIN [Source_Database].[Schema].[K_monster] S
ON t.ID = S.ID
GO
Please check this link similar to this type of question:
Additionally I would suggest you to search before you ask any questions.
UPDATE record in one database with values from another in SQL Server 2008?
This link has similar answer to your question.
More links:
Update database table from one SQL Server database table to another?
https://dba.stackexchange.com/questions/30228/how-to-update-one-database-from-another
https://dba.stackexchange.com/questions/58371/sql-update-column-with-data-from-another-table
With Regards

How to get last inserted row from a table?

I tried below query but results in more than one row and [SCOPE_IDENTITY] as NULL.What are the alternates?
SELECT TOP 1000
[RTID],xxx,xxx
FROM [RouteTiming]
GO
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
GO
SELECT ##IDENTITY AS [##IDENTITY];
GO
Depending on the server version (SQL Server 2005+) you can use the OUTPUT clause:
INSERT INTO tablename (column names)
OUTPUT --this is where you put your select statement to get returned IDs etc.
VALUES (values in here, or you can use a select statememt as per usual)
MSDN Article: OUTPUT Clause (Transact-SQL)
If you are inside a stored procedure or a function, you can use INSERTED table (there is also a DELETED table) which is stored in memory until the scope is completed.
Once you have performed your insert, you can join the inserted table just like any other as long as it is within the same scope. I believe the inserted table has been around since SQL Server 2000, but it is definitely in 2005+.
MSDN Examples: Use the inserted and deleted Tables

Using OUTPUT with joined tables

Why doesn't the following work?
INSERT INTO dbo.Pending_Break
(Pending_Pod_ID, Break_Date_Time, Break_Length, Booked_Length)
OUTPUT INSERTED.Pending_BH_ID -- This is the inserted identity
, INSERTED.Pending_Pod_ID
, INSERTED.Break_Name
, INSERTED.Break_Date_Time
, pb.PENDING_BH_ID -- complains on this one
INTO #InsertedPendingBreaks
SELECT ippod.Pending_Pod_ID,
pb.Break_Date_Time
pb.break_length,
0
FROM PendingBreak pb
JOIN InsertedPod ippod ON ...
Can I not use anything other than Inserted or Deleted in the OUTPUT clause?
Can I not use anything other than Inserted or Deleted in the OUTPUT
clause?
No you can't. At least not with an insert. In SQL Server 2008 you can convert your insert to a merge statement instead and there you can use values from the source table in the output clause.
Have a look at this question how to do that in SQL Server 2008. Using merge..output to get mapping between source.id and target.id
The inserted and deleted tables are available only in DML triggers. I'm not sure if you just pulled a code snippet out of a trigger, but if that is a standalone batch then it won't work.
Also, there is no updated table. An update is a delete and then an insert for this. deleted contains the old data and inserted contains the new data on an UPDATE.

Using SQL Server DTS Package to Conditionally Insert / Update Rows in Destination Table

I want to create a DTS Package to pull data from an Oracle table into a SQL2K
table. How can I insert rows that are not already in the SQL2K table and
update rows that already exist in the SQL2K table?
I guess I could truncate and repopulate the entire table or create a
temporary table and then do updates/inserts from the temp table into the
destination table.
Is there any easier way using DTS?
Thanks,
Rokal
You can do that in a DTS package using two data driven query tasks: one for the inserts and one for the updates. The data driven query tasks are a bit of a pain to use, but they work. I've also done this (a "merge") in sql server 2000 with an AS/400 database using a dynamic t-sql. You'd write a t-sql script that outputs psql and runs it againt a linked server to the Oracle database.
UPDATE:
A DTS "data driven query task" will let you insert|update data from the sql server connection in DTS to an oracle server connection in DTS w/o a temp table or a linked server.
Update2; here's some more info on what I mean:
http://www.databasejournal.com/features/mssql/article.php/3315951
http://msdn.microsoft.com/en-us/library/aa933507(SQL.80).aspx
Are you keeping the same primary key values?
If you are you have a number of options, some versions of SQL support the MERGE statement which will update or insert just like you require.
Or you can write your own.
Something along the lines of loading all the rows into a staging table in your SQL database and row by row checking for the existence of your primary key in your main SQL table. If the key exists update the row and if not insert it.
Yes, the primary key values in the source and destination will match.
I was hoping to accomplish this task without the use of a temporary (staging) table.
Also, I am using sql server 2000 so the MERGE statement is not available.
Try:
DELETE FROM dbo.WhateverTable WHERE WhateverTableID IN (SELECT WhateverTableID FROM MySource)
It might be pretty slow, use join instead:
Delete a
from firstTable a join secondTable b on a.id = b.id
There's no way with TSQL to do a INSERT or UPDATE in the same statement, but you could very easily do it in two statements (as you mentioned above).
Statement 1:
DELETE FROM dbo.WhateverTable
WHERE WhateverTableID IN (SELECT WhateverTableID FROM MySource)
Statement 2:
INSERT INTO dbo.WhateverTable
SELECT * FROM MySource
Also, is there any reason why you don't want to use a temp table?