Using OUTPUT with joined tables - sql

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.

Related

loading fact table using pentaho data integation

I am using pentaho DI to insert data into fact table . Thing is the table from which I am populating my fact table contains 10000 reccords and changes frequently . Using database lookups and insert update I am able to load my fact table correctly once . But when new records are added to my souce table(say it becomes 15000) and I am again inserting records into fact table then these 15000 recods are again added to my fact table . What I want is to add new 5000 records that do not exist in fact table .Please suggest me on what transformations I need to perform to acheive this .
try doing an upsertion instead insertion (if the row exists then update , if not insert)
You can use some DB function.
In SQL Server 2008, there is a merge sql that solve this type problem.
It is a example as follows in SQL Server 2008:
MERGE Production.UnitMeasure AS target
USING (SELECT #UnitMeasureCode, #Name) AS source (UnitMeasureCode, Name)
ON (target.UnitMeasureCode = source.UnitMeasureCode)
WHEN MATCHED THEN
UPDATE SET Name = source.Name
WHEN NOT MATCHED THEN
INSERT (UnitMeasureCode, Name)
VALUES (source.UnitMeasureCode, source.Name)
OUTPUT deleted., $action, inserted. INTO #MyTempTable;

Update trigger with GROUP BY

I'm using insert-/update triggers to update a second table's column Price.
The insert trigger seems to work perfectly, but when I try to change a single record in SSMS, I get an error:
The row value(s) updated or deleted either do not make the row
unique or they alter multiple rows(2 rows).
This is my update-trigger:
CREATE TRIGGER [dbo].[trgUpdateMasterData] ON [dbo].[tabSparePartMasterData_Temp]
AFTER UPDATE
AS
UPDATE tabSparePart
SET Price = MD.Price
FROM tabSparePart INNER JOIN
(
SELECT inserted.[Material Number (SAP)] AS MaterialNumber, inserted.Price
FROM inserted
GROUP BY [Material Number (SAP)], inserted.Price
) MD
ON tabSparePart.SparePartName = MD.MaterialNumber
I need to group by Material-Number because there are redundant rows inserted into table tabSparePartMasterData_Temp which i'm only using to update the Sparepart-Price in tabSparePart. But i assumed that the group by would sort out the duplicates(Price is same for any duplicate).
It's possible that the inserted/updated records' MaterialNumber is not available in tabSparepart. In this case this record should be "skipped". Does the INNER JOIN takes that into account?
Try adding SET NOCOUNT ON to the trigger
This error doesn't look like a SQL error and I'm guessing the client code is getting confused by the 2nd update in the trigger.
Edit: this error can be caused by the data grid view in SSMS being silly.
This isn't a SQL message as I thought: it is an SSMS being stupid message
See these which all says "learn to write SQL"
http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/dealing-with-the-row-value-s-updated-or (Less than dot blog)
Trigger that modifies multiple rows on diffrent table then it was invoked on in SQL Server 2005
SSMS permits duplicate records in a table, but not subsequent updates
Saying that, there is a KB article about a bug in SQL Server 2005...

SQL Server 2005, bulk UPDATE or INSERT

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)

Using SQl Server CE; Possible to Insert Only If Not Exists and Delete if Exists?

I have a One Field Table in SQL CE which I need a SQL Statement for. The objective is to Delete the record if it already exists and insert the record if it does not exist. Is the possible with SQL CE?
INSERT INTO Source_Table
SELECT 'myvalue' AS Expr1
WHERE (NOT EXISTS
(SELECT Source_Data
FROM Source_Table AS Source_Table_1
WHERE (Source_Data = 'myvalue')))
Why not just...
DELETE Source_Table WHERE Source_Data = 'myvalue'
GO
INSERT INTO Source_Table (Source_Data) values('myvalue')
I'm not sure what the point of deleting a record and then inserting the same data would be, but this should accomplish it.
If the aim is to literally delete if it exists and only insert it if it does not exist, then you need to do what you've written.
If the aim is to insert if it doesn't exist and replace if it does, Adam's correct that you may as well just always run the delete followed by the insert. I'd run both in the same statement batch, to save overhead.
Were there more than one field, of course you'd do an update, not a delete followed by insert. (But delete followed by insert is how Sybase internally performs updates.)

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?