翻译SQL Server' OUTPUT'到Oracle?

时间:2016-06-22 08:12:06

标签: sql sql-server oracle

我在将MSSQL(sql-server)查询转换为Oracle(PL-SQL)时遇到了大问题。

目标是在一个线程安全操作中对更新的字段进行更新和选择。

我当前的MSSQL查询:

UPDATE PDFCONVERT_G
SET PDF_STATUS = 1, PDF_STARTDATE = GETDATE(), PDF_CONVERTERNAME='inputConverterName'
OUTPUT Inserted.PDF_ACTION as Action,
       Inserted.PDF_ARKMERK_VE As ARKMERK, 
       Inserted.PDF_TYPE_DL as DlTypeDT, 
       Inserted.PDF_DOKID_VE as DocId, 
       Inserted.PDF_DOKMALID_VE as DOKMALID, 
       Inserted.PDF_FILREF_VE as FILREF, 
       Inserted.PDF_FILTYPE_LF as Filtype,
       Inserted.PDF_JPID_JP as JpId, 
       Inserted.PDF_LOCFILREF_VE as LOCFILREF, 
       Inserted.PDF_SAID_SA as SaId, 
       Inserted.PDF_SJEKKETUT_VE as SJEKKETUT, 
       Inserted.PDF_TGKODE_VE as TGKODE, 
       Inserted.PDF_VARIANT_VE as Variant, 
       Inserted.PDF_VERSJON_VE as Version, 
       Inserted.PDF_CHECKINAFTERCONVERT as CheckinAfterConvert
FROM PDFCONVERT_G t1
INNER JOIN (
    SELECT TOP(1) *
    FROM PDFCONVERT_G A WHERE (
        (A.PDF_LAGRENH_VE = 'PROD' OR EXISTS(SELECT * FROM PDFCONVERT_G B WHERE A.PDF_JOBID=B.PDF_JOBID AND B.PDF_LAGRENH_VE='PROD' AND B.PDF_ACTION='MERGE')) 
        AND PDF_STATUS = 0 AND NOT EXISTS(
            SELECT * FROM PDFCONVERT_G B where a.pdf_jobid = b.pdf_jobid and b.pdf_status > 0 and a.pdf_action != b.pdf_action)) 
    ORDER BY A.PDF_PRIORITY DESC, A.PDF_JOBID, A.PDF_RNR
    ) t2 ON t2.PDF_JOBID = t1.PDF_JOBID

我可以在我的.net代码中执行此查询,结果将是输出变量。

我知道Oracle有RETURNING INTO语法,但总结一下我的WHERE子句有多复杂,我只是一直都会遇到语法错误。

我更喜欢在不创建函数的情况下编写查询,但即使我必须这样做,我也遇到了问题。

1 个答案:

答案 0 :(得分:1)

SELECT TOP(1) *
FROM PDFCONVERT_G A
WHERE (
    (   A.PDF_LAGRENH_VE = 'PROD'
     OR EXISTS(SELECT *
               FROM   PDFCONVERT_G B
               WHERE  A.PDF_JOBID=B.PDF_JOBID
               AND    B.PDF_LAGRENH_VE='PROD'
               AND    B.PDF_ACTION='MERGE')
    ) 
    AND PDF_STATUS = 0
    AND NOT EXISTS(
        SELECT *
        FROM   PDFCONVERT_G B
        where  a.pdf_jobid = b.pdf_jobid
        and    b.pdf_status > 0
        and    a.pdf_action != b.pdf_action
    )
) 
ORDER BY A.PDF_PRIORITY DESC, A.PDF_JOBID, A.PDF_RNR

可以重写(没有相关的子查询):

SELECT *
FROM   (
  SELECT a.*,
         ROW_NUMBER() OVER ( ORDER BY PDF_PRIORITY DESC, PDF_JOBID, PDF_RNR ) AS rn
  FROM   (
    SELECT a.*,
           COUNT(
             CASE WHEN DF_LAGRENH_VE = 'PROD'
                  AND  PDF_ACTION    = 'MERGE'
                  THEN 1 END
           ) OVER ( PARTITION BY pdf_jobid )
             AS num_prod_merge,
           COUNT(
             CASE WHEN pdf_status > 0 THEN 1 END
           ) OVER ( PARTITION BY pdf_jobid )
             AS num_all_actions,
           COUNT(
             CASE WHEN pdf_status > 0 THEN 1 END
           ) OVER ( PARTITION BY pdf_jobid, pdf_action )
             AS num_same_actions
    FROM   PDFCONVERT_G a
  ) a
  WHERE  ( PDF_LAGRENH_VE = 'PROD' OR num_prod_merge > 0 )
  AND    PDF_STATUS = 0
  AND    num_all_actions = num_same_actions
)
WHERE  rn = 1;

然后,您可以将UPDATE重写为:

UPDATE PDFCONVERT_G
SET PDF_STATUS       = 1,
    PDF_STARTDATE    = SYSDATE,
    PDF_CONVERTERNAME='inputConverterName'
WHERE ROWID = (
  SELECT ROWID
  FROM   (
    -- as above
  )
  WHERE  rn = 1
)
RETURNING PDF_ACTION -- , ...
INTO      :Action    -- , ...

(注意:目前无法对此进行测试,因此可能存在一些小的语法错误,但您应该得到一般的想法。)