我在将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子句有多复杂,我只是一直都会遇到语法错误。
我更喜欢在不创建函数的情况下编写查询,但即使我必须这样做,我也遇到了问题。
答案 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 -- , ...
(注意:目前无法对此进行测试,因此可能存在一些小的语法错误,但您应该得到一般的想法。)