2013-06-25 79 views
1

我嘗試通過複製xpath規則在聲納(plsql)中編寫自定義規則。這條規則的任務是在保存點語句丟失的地方標記「回退到保存點」語句。XPath-1.0:標記相對節點丟失的節點

對於2保存點和3條ROLLBACK語句的AST(抽象語法樹)的樣子:

<PROCEDURE_DEFINITION> 
    ... 
    <SAVEPOINT> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spA" /> 
    <SEMICOLON tokenValue=";" /> 
    </SAVEPOINT> 
    ... 
    <SAVEPOINT> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spB" /> 
    <SEMICOLON tokenValue=";" /> 
    </SAVEPOINT> 
    ... 
    <ROLLBACK> 
    <IDENTIFIER tokenValue="ROLLBACK" /> 
    <TO /> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spB" /> 
    <SEMICOLON tokenValue=";" /> 
    </ROLLBACK> 
    ... 
    <ROLLBACK> 
    <IDENTIFIER tokenValue="ROLLBACK" /> 
    <TO /> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spA" /> 
    <SEMICOLON tokenValue=";" /> 
    </ROLLBACK> 
    ... 
    <ROLLBACK> 
    <IDENTIFIER tokenValue="ROLLBACK" /> 
    <TO /> 
    <IDENTIFIER tokenValue="SAVEPOINT" /> 
    <IDENTIFIER tokenValue="spX" /> 
    <SEMICOLON tokenValue=";" /> 
    </ROLLBACK> 
    ... 
</PROCEDURE_DEFINITION> 

我要尋找的XPath查詢,因爲保存點SPX缺少這標誌着最後回滾。 但是這個XPath標記最後,兩人都回滾

//PROCEDURE_DEFINITION//ROLLBACK[ 
    IDENTIFIER[ 
     @tokenValue = 
      ./ancestor::PROCEDURE_DEFINITION 
       //SAVEPOINT/IDENTIFIER[2]/@tokenValue 
    ] 
] 

有什麼建議?

編輯:
我發現這個次優解:

//PROCEDURE_DEFINITION//ROLLBACK 
[ 
    not(
    ./IDENTIFIER[3]/@tokenValue = 
    ancestor::PROCEDURE_DEFINITION//SAVEPOINT/IDENTIFIER[2]/@tokenValue 
) 
] 

PLSQL不區分大小寫。但是當我添加翻譯功能,我得到標記的第一個和最後一個ROLLBACK節點。我認爲所有回滾的名稱都會與第一個保存點的名稱一致?

回答

1

首先,根據您展示AST,在我看來,這是您要運行在你的XPath查詢的PL/SQL代碼:當我運行你的第一個XPath查詢

DECLARE 
    PROCEDURE foo AS 
    BEGIN 
    SAVEPOINT spA; 
    SAVEPOINT spB; 

    ROLLBACK spB; -- Compliant 
    ROLLBACK spA; -- Compliant 

    ROLLBACK spX; -- Non-Compliant 
    END; 
BEGIN 
    NULL; 
END; 
/

使用SSLR PL/SQL Toolkit,選擇「spB」和「spA」的回滾,但不是「spX」的回滾。

您的第二個XPath查詢選擇所有這些查詢。

在我看來,你只想選擇'spX',因爲沒有相應的保存點。

你的第一個查詢瑣碎的變化允許逆向選擇的節點,通過使用不()否定條件:

//PROCEDURE_DEFINITION//ROLLBACK[ 
    not(IDENTIFIER[ 
     @tokenValue = 
      ./ancestor::PROCEDURE_DEFINITION 
       //SAVEPOINT/IDENTIFIER[2]/@tokenValue 
    ]) 
] 

但我真的建議你把查詢的PROCEDURE_DEFINITION一部分, SAVEPOINT和ROLLBACK語句在函數或匿名塊中也是有效的:

//ROLLBACK[not(IDENTIFIER[@tokenValue = //SAVEPOINT/IDENTIFIER[2]/@tokenValue])] 
+0

謝謝Dinesh。你猜猜PL/SQL代碼是否正確(程序是程序包的一部分)。無論如何,你的XPath查詢手段很好。但是它並沒有在這個「保存點SpA;回滾spA;」上運行,因爲與XPath相比,PL/SQL是大案例。 – MintiSE

+0

你是對的@MintiSE,雖然這是可以在純XPath 1.0中解決的,但我們在SSLR上有一張票,以使它更容易:[SSLR-310](http://jira.sonarsource.com/browse/SSLR-310 ) –

+0

此外,這個規則將被包含在下一個PL/SQL插件版本中,因爲它對每個人都是有價值的(不僅僅是你):[PLSQL-443](http://jira.sonarsource.com/browse/) PLSQL-443) –