views:

245

answers:

2

I've been asked to convert this statement from PL/SQL to SQL Server:

UPDATE pdi_nb_process_complete pdi_end1
SET    (pdi_end1.adp_issue_date_time, pdi_end1.adp_print_date_time) = 
(SELECT DISTINCT pdi_end1.completion_date + 2
                ,pdi_end1.completion_date
 FROM   cl100 cl
 WHERE  cl.polref = pdi_end1.policy_reference
 AND    cl.doctyp = 'PSP')
WHERE  pdi_end1.adp_print_date_time IS NULL

A straight copy/paste doesn't work - you get a compile error. The closest I have managed is this:

UPDATE pdi_end1
SET    pdi_end1.adp_issue_date_time = pdi_end1.completion_date + 2,
       pdi_end1.adp_print_date_time = pdi_end1.completion_date
from pdi_nb_process pdi_end1
INNER JOIN cl100 cl ON  cl.polref = pdi_end1.policy_reference
     AND cl.doctyp = 'PSP'
WHERE  pdi_end1.adp_print_date_time IS NULL

But this leaves me short of the DISTINCT. Does anyone have any suggestions?

You can assume the Oracle and SQL Server Databases have the same tables and fields.

Thanks

A: 

You could change the inner join into a subquery:

inner join (
    select distinct policy_reference
    from cl100
    where doctyp = 'PSP'
) cl on cl.polref = pdi_end1.policy_reference

Or maybe more readable, remove the inner join altogether and replace it with a WHERE statement:

WHERE  pdi_end1.adp_print_date_time IS NULL
AND EXISTS (
    select * 
    from cl100 cl
    where cl.polref = pdi_end1.policy_reference
    and cl.doctyp = 'PSP'
)
Andomar
+2  A: 

I would move the AND cl.doctyp='PSP' condition to the WHERE, because it is not a join condition.

try this:

UPDATE pdi_end1
    SET pdi_end1.adp_issue_date_time=pdi_end1.completion_date + 2
        ,pdi_end1.adp_print_date_time)=pdi_end1.completion_date
    FROM pdi_nb_process_complete pdi_endl
        INNER JOIN cl100               cl ON cl.polref=pdi_end1.policy_reference
    WHERE pdi_end1.adp_print_date_time IS NULL
        AND cl.doctyp='PSP'

I would not worry about the DISTINCT, SQL Server will only update the rows one time, see this example:

SET NOCOUNT ON
DECLARE @Test table (RowID int, RowValue int, OtherRowValue int)
INSERT INTO @Test VALUES ( 1, 1, 10)
INSERT INTO @Test VALUES ( 2, 2, 20)
INSERT INTO @Test VALUES ( 3, 3, 30)
INSERT INTO @Test VALUES ( 4, 4, 40)
INSERT INTO @Test VALUES ( 5, 5, 50)
INSERT INTO @Test VALUES ( 6, 6, 60)
INSERT INTO @Test VALUES ( 7, 7, 70)
INSERT INTO @Test VALUES ( 8, 8, 80)
INSERT INTO @Test VALUES ( 9, 9, 90)
INSERT INTO @Test VALUES (10,10,100)

DECLARE @TestJoin table (RowID int, RowValue int)
INSERT INTO @TestJoin VALUES (1,10)
INSERT INTO @TestJoin VALUES (1,10)
INSERT INTO @TestJoin VALUES (1,10)
INSERT INTO @TestJoin VALUES (2,20)
INSERT INTO @TestJoin VALUES (2,20)
INSERT INTO @TestJoin VALUES (2,20)
INSERT INTO @TestJoin VALUES (2,20)
INSERT INTO @TestJoin VALUES (2,20)
INSERT INTO @TestJoin VALUES (3,30)
INSERT INTO @TestJoin VALUES (3,30)
SET NOCOUNT OFF

SELECT ---------------------------returns 5 rows, DISTINCT would only return 1
    t.OtherRowValue+2
    FROM @Test                t
        INNER JOIN @TestJoin  j ON t.RowID=j.RowID
    WHERE t.OtherRowValue=20
        AND j.RowValue=20

UPDATE t--------------------------updates only 1 row
    SET t.RowValue=t.OtherRowValue+2
    FROM @Test                t
        INNER JOIN @TestJoin  j ON t.RowID=j.RowID
    WHERE t.OtherRowValue=20
        AND j.RowValue=20

OUTPUT:

-----------
22
22
22
22
22

(5 row(s) affected)

(1 row(s) affected)

The SELECT returns 5 rows, however when that same select is put into the UPDATE, only 1 row is affected.

KM
"I would move the AND cl.doctyp='PSP' condition to the WHERE, because it is not a join condition." - Is this because it more efficient, or is it just personal preference?
James Wiseman
in this case, personal preference, but it can makes difference in what rows are actually returned. Using my example code above, run this query: **SELECT t.*,j.RowValue FROM @Test t LEFT OUTER JOIN @TestJoin j ON t.RowID=j.RowID AND j.RowValue=20** and then run it moving the **j.RowValue=20** into a WHERE clause, you will get a different result set
KM
Thanks brilliant answer!
James Wiseman