2009-09-18 60 views
0

我一直要求從PL/SQL這種說法轉換到SQL Server:如何將此PL/SQL更新語句轉換爲適用於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 

直複製/粘貼不工作 - 你得到一個編譯錯誤。我已成功最接近的是這樣的:

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 

但是,這給我留下短DISTINCT的。有沒有人有什麼建議?

您可以假設Oracle和SQL Server數據庫具有相同的表和字段。

感謝

回答

2

我會將和cl.doctyp ='PSP'條件移到WHERE,因爲它不是連接條件。

試試這個:

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' 

我就不會擔心了DISTINCT,SQL Server將只更新行一次,看看這個例子:

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) 

SELECT返回5行,但是當相同的select放入UPDATE時,只有1行受到影響。

+0

「我會將AND cl.doctyp ='PSP'條件移到WHERE,因爲它不是連接條件。」 - 這是因爲它更有效率,還是僅僅是個人喜好? – 2009-09-18 13:21:34

+0

在這種情況下,個人偏好,但它可以使實際返回的行有所不同。使用我上面的示例代碼,運行此查詢:** SELECT t。*,j.RowValue FROM @Test t LEFT OUTER JOIN @TestJoin j ON t.RowID = j.RowID AND j.RowValue = 20 **然後運行它將** j.RowValue = 20 **移到WHERE子句中,您將得到不同的結果集 – 2009-09-18 13:29:51

+1

謝謝輝煌的回答! – 2009-09-18 15:32:16

0

你可以改變內部連接成一個子查詢:

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

或許更具可讀性,取下內共加入,並用WHERE語句替換:

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' 
) 
相關問題