Update a single row in a table in SQL - sql

So, I am creating a new table that gets populated from another table. NewTableA.ColA is getting populated from an existing OldTableB.ColB
Source query that populates NewTableA.ColA:
SELECT TOP (1) EXEC_END_TIME
FROM CR_STAT_EXECUTION AS cse
WHERE (EXEC_NAME = 'ETL')
ORDER BY EXEC_END_TIME DESC
Destination Table (NewTableA.ColA) When scripted out:
SELECT TOP 1 [EXEC_END_TIME]
FROM [SSISHelper].[dbo].[ETLTimeCheck]
ORDER BY EXEC_END_TIME DESC
The problem I am facing is, I only want to have 1 row in the NewTableA.ColA that updates the current value in the ColA from the other table. I already setup an SSIS job to populate the table every day from OldTableB.ColB... I just couldn't figure out how I can only update 1 row from OldTableB.ColB?
Thanks.

Use IF condition in SQL:
Example:
IF EXISTS (SELECT * FROM EXEC_END_TIME WHERE COLUMNX='xValue')
BEGIN
(...update...i guess)
END
ELSE
BEGIN
(...insert...i guess)
END

Related

Delete Duplicate in I$ table in ODI

We have a load plan in ODI. We get a repeating error in some on our scenarios due to duplicate records in the I% table. What we do is manually run the script every time the load plan fails.
DELETE FROM adw12_dw. I$_1558911580_4
WHERE (EFFECTIVE_FROM_DT, DATASOURCE_NUM_ID, INTEGRATION_ID) IN
( SELECT EFFECTIVE_FROM_DT,
DATASOURCE_NUM_ID,
INTEGRATION_ID
FROM adw12_dw . I$_1558911580_4
GROUP BY EFFECTIVE_FROM_DT,
DATASOURCE_NUM_ID,
INTEGRATION_ID
HAVING COUNT (1) > 1)
AND ROWID NOT IN
( SELECT MIN (ROWID)
FROM adw12_dw . I$_1558911580_4
GROUP BY EFFECTIVE_FROM_DT,
DATASOURCE_NUM_ID,
INTEGRATION_ID
HAVING COUNT (1) > 1)
commit;
Is there a way to automate the deletion of duplicate records in the Integration table?
If you have duplicates in the source, best would be to handle that in the logic of the mapping.
What could work is to add an expression component to add a row_rank column using an analytical function to rank the duplicates : row_number() over (partition by EFFECTIVE_FROM_DT, DATASOURCE_NUM_ID, INTEGRATION_ID order by ROWID).
You can then add a filter with the condition row_rank = 1.
If you prefer to do a delete after inserting, you can edit the IKM and add the delete step before loading the target table.
You could also divide the integration in 3 different steps :
a mapping that would load a staging table instead of your final target table, with the duplicate
an ODI procedure that would perform the delete to remove the duplicates in the staging table
a mapping that would load the data from the staging area to the target table
Maybe your duplicate counts over 2 because we must execute the delete query recursively. For example:
CREATE OR REPLACE PROCEDURE delete_dublicates
IS
BEGIN
DELETE FROM TABLE1 WHERE ID IN
(
SELECT max(ID) FROM TABLE1
GROUP BY USER_ID, TYPE_ID
HAVING count(*) > 1
);
IF (SQL%ROWCOUNT > 0) THEN
delete_dublicates;
END IF;
END delete_dublicates;

SQL - Delete selected row/s from database

I'm quite new to SQL and I'm having issues with deleting a selected row/s from a table.
I've written a query that selects the desired rows from the table, but when I try to execute DELETE FROM table_name WHERE EXISTS it deletes all the rows in the database.
Here is my complete query:
DELETE FROM USR_PREF WHERE EXISTS (
SELECT *
FROM USR_PREF
WHERE USR_PREF.USR_ID = 1
AND ((USR_PREF.SRV NOT IN (SELECT SEC_ENTITY_FOR_USR_ACTION_VIEW.ENTITYT_ID
FROM SEC_ENTITY_FOR_USR_ACTION_VIEW
WHERE SEC_ENTITY_FOR_USR_ACTION_VIEW.USR_ID = 1
AND SEC_ENTITY_FOR_USR_ACTION_VIEW.ENTITYTYP_CODE = 2
AND USR_PREF.DEVICE IS NULL)
OR (USR_PREF.DEVICE NOT IN (SELECT SEC_ENTITY_FOR_USR_ACTION_VIEW.ENTITYT_ID
FROM SEC_ENTITY_FOR_USR_ACTION_VIEW
WHERE SEC_ENTITY_FOR_USR_ACTION_VIEW.USR_ID = 1
AND SEC_ENTITY_FOR_USR_ACTION_VIEW.ENTITYTYP_CODE = 3)))))
The select query returns the desired rows, but the DELETE command just deletes that entire table.
Please assist.
Your where clause WHERE EXISTS (SOME QUERY) is the problem here. You are basically saying "Delete everything if this subquery returns even one result".
You need to be more explicit. Perhaps something like:
DELETE FROM USR_PREF
WHERE USR_FIELD IN (
SELECT USR_FIELD
FROM USR_PREF
WHERE USR_PREF_T.USER_ID=1
AND ((USR_PREF.SRV NOT IN ...
and so on... With this, only records that match records returned in your subquery will be deleted.

Update the date fields from the values returned from a subquery Oracle SQL

I have an application that scans a table for IDs that do not have a processed date. When an ID is processed, a process date is added to Table 1 and the entire record is copied to another table (table 2) if it completes the application.
I need to compare IDs in the tables looking for IDs from table 1 that are not in table 2 but has a date for when it was processed. This is a sign that the id was processed but never made it to the end of the application and failed along the way.
I then need to update these IDs (records) from table 1 by setting the processing date to null so the application picks it up in the next run.
Here is a query that gets the IDs I need.
SELECT Subject_Number
From Table1
WHERE NOT EXISTS(SELECT NULL
FROM Table2
WHERE Table2.Subject_Number = Table1.Subject_Number)
AND Table1.Processed_Date IS NOT NULL.
Now I just need to update the processed date to null for the IDs this returns.
Any help will be greatly appreciated.
This query something like this
UPDATE <table> SET <fields> WHERE <table.id> IN (
SELECT Subject_Number
From Table1
WHERE NOT EXISTS(
SELECT NULL
FROM Table2
WHERE Table2.Subject_Number = Table1.Subject_Number)
AND Table1.Processed_Date IS NOT NULL.)

Efficiently checking if more than one row exists in a recordset

I'm using SQL Server 2008 R2, and I'm trying to find an efficient way to test if more than 1 row exists in a table matching a condition.
The naive way to do it is a COUNT:
IF ( SELECT COUNT(*)
FROM Table
WHERE Column = <something>
) > 1 BEGIN
...
END
But this requires actually computing a COUNT, which is wasteful. I just want to test for more than 1.
The only thing I've come up with is a COUNT on a TOP 2:
IF ( SELECT COUNT(*)
FROM ( SELECT TOP 2 0 x
FROM Table
WHERE Column = <something>
) x
) > 1 BEGIN
...
END
This is clunky and requires commenting to document. Is there a more terse way?
If you have a PK in the table that you're checking for >1 row, you could nest another EXISTS clause. Not sure if this is faster, but it achieves your record result. For example, assuming a Station table with a PK named ID that can have zero-to-many Location table records with a PK named ID, Location has FK StationID, and you want to find the Stations with at least two Locations:
SELECT s.ID
FROM Station s
WHERE EXISTS (
SELECT 1
FROM Location L
WHERE L.StationID = s.ID
AND EXISTS (
SELECT 1
FROM Location L2
WHERE L2.StationID = L.StationID
AND L2.ID <> L.ID
)
)
I have the following solution to share, which may be lighter performance-wise.
I suppose that you are trying to fetch the first record and process it once you make sure that your SQL selection returns a single record. Therefore, go on and fetch it, but once you do that, try to fetch the next record right away, and if successful, you know that more than one record exists, and you can start your exception processing logic. Otherwise, you can still process your single record.

Check whether a table contains rows or not sql server 2005

How to Check whether a table contains rows or not sql server 2005?
For what purpose?
Quickest for an IF would be IF EXISTS (SELECT * FROM Table)...
For a result set, SELECT TOP 1 1 FROM Table returns either zero or one rows
For exactly one row with a count (0 or non-zero), SELECT COUNT(*) FROM Table
Also, you can use exists
select case when exists (select 1 from table)
then 'contains rows'
else 'doesnt contain rows'
end
or to check if there are child rows for a particular record :
select * from Table t1
where exists(
select 1 from ChildTable t2
where t1.id = t2.parentid)
or in a procedure
if exists(select 1 from table)
begin
-- do stuff
end
Like Other said you can use something like that:
IF NOT EXISTS (SELECT 1 FROM Table)
BEGIN
--Do Something
END
ELSE
BEGIN
--Do Another Thing
END
FOR the best performance, use specific column name instead of * - for example:
SELECT TOP 1 <columnName>
FROM <tableName>
This is optimal because, instead of returning the whole list of columns, it is returning just one. That can save some time.
Also, returning just first row if there are any values, makes it even faster. Actually you got just one value as the result - if there are any rows, or no value if there is no rows.
If you use the table in distributed manner, which is most probably the case, than transporting just one value from the server to the client is much faster.
You also should choose wisely among all the columns to get data from a column which can take as less resource as possible.
Can't you just count the rows using select count(*) from table (or an indexed column instead of * if speed is important)?
If not then maybe this article can point you in the right direction.
Fast:
SELECT TOP (1) CASE
WHEN **NOT_NULL_COLUMN** IS NULL
THEN 'empty table'
ELSE 'not empty table'
END AS info
FROM **TABLE_NAME**