我想从PLSQL脚本中提取“创建语句”。 我知道可以使用Lexer / Parser完成此操作,但是我正在尝试使用JavaScript Regex进行此操作。
鉴于此内容的“脚本”,我想提取不同的语句。
CREATE OR REPLACE TYPE BODY Cheopsregbp.SITE_OT AS
CONSTRUCTOR FUNCTION SITE_OT (
p_site_list_id VARCHAR2
, p_traductions TRADUCTIONS_MAP_ENTRY_CT := new TRADUCTIONS_MAP_ENTRY_CT()
)
RETURN SELF AS RESULT
AS
BEGIN
SELF.site_list_id := p_site_list_id;
SELF.traductions := p_traductions;
RETURN;
END;
STATIC FUNCTION convert_to_date(p_date_string in VARCHAR2, p_field_name_in in VARCHAR2, p_field_name_out IN OUT NOCOPY VARCHAR2) RETURN DATE IS
BEGIN
-- function to convert string to date and keep track of which field we are converting => needed to produce error
p_field_name_out := p_field_name_in; -- this will cause fieldName (declared in verify) to be updated before potential fail in next line
RETURN cast(to_timestamp(p_date_string, Cheopsregbp.API_CONST_HLPR.DATE_FORMAT) as date);
END convert_to_date;
STATIC FUNCTION convert_to_number(p_number_string in VARCHAR2, p_field_name_in in VARCHAR2, p_field_name_out IN OUT NOCOPY VARCHAR2) RETURN NUMBER IS
BEGIN
-- function to convert string to number and keep track of which field we are converting => needed to produce error
p_field_name_out := p_field_name_in; -- this will cause fieldName (declared in verify) to be updated before potential fail in next line
RETURN cast(p_number_string as number);
END convert_to_number;
STATIC FUNCTION from_json(p_json_object in BLOB) RETURN SITE_OT IS -- $$ref-ot-fromJson-BLOB
l_clob CLOB;
l_warning INTEGER;
l_offset INTEGER := 1;
l_csId INTEGER := nls_charset_id('UTF8');
l_lang_context INTEGER := DBMS_LOB.default_lang_ctx;
l_amount INTEGER := DBMS_LOB.lobMaxSize;
BEGIN
IF p_json_object IS NULL THEN
RETURN null;
END IF;
dbms_lob.createTemporary(lob_loc => l_clob, cache => false);
dbms_lob.convertToClob( dest_lob => l_clob
,src_blob => p_json_object
,amount => l_amount
,dest_offset => l_offset
,src_offset => l_offset
,blob_csId => l_csId
,lang_context => l_lang_context
,warning => l_warning);
apex_json.parse(l_clob);
RETURN from_json(''); -- '' => root-path -- works with apex_json.g_values!
END from_json;
STATIC FUNCTION from_json(p_parent in VARCHAR2) -- works with apex_json.g_values!
RETURN SITE_OT IS -- $$ref-ot-fromJson-CLOB
l_arr_count INTEGER;
l_parent VARCHAR2(2048 CHAR) := p_parent;
l_api_error API_ERROR_OT;
l_field_name Cheopsregbp.API_CONST_HLPR.CHAR256;
l_traductions TRADUCTIONS_MAP_ENTRY_CT := new TRADUCTIONS_MAP_ENTRY_CT();
l_result SITE_OT;
BEGIN
IF p_parent IS NOT NULL THEN l_parent := p_parent || '.'; END IF;
-- prepare list of traductions
l_arr_count := apex_json.get_count(p_path => l_parent || 'traductions'); -- works with apex_json.g_values!
IF l_arr_count > 0 THEN
FOR i in 1 .. l_arr_count LOOP
l_traductions.extend;
l_traductions(l_traductions.last) := TRADUCTIONS_MAP_ENTRY_OT.from_json( l_parent || 'traductions['||i||']'); -- $$ref-fromJSONListItemFn
END LOOP;
END IF;
l_result := SITE_OT( -- $$ref-fromJSONReturn
p_site_list_id => apex_json.GET_VARCHAR2( l_parent || 'site_list_id'), -- $$ref-returnJSONField
p_traductions => l_traductions
);
RETURN l_result;
EXCEPTION -- $$ref-fromJSONExceptions
WHEN NO_DATA_FOUND THEN
l_api_error := new API_ERROR_OT(Cheopsregbp.API_CONST_HLPR.NO_DATA_FOUND, Cheopsregbp.API_CONST_HLPR.HTTP_404, l_field_name);
l_api_error.sqlcode := sqlcode;
l_api_error.sqlerrm := sqlerrm;
l_api_error.stacktrace := 'SITE_OT.verify';
API_CORE_HLPR.add_error(l_api_error);
RETURN NULL;
WHEN OTHERS THEN
l_api_error := new API_ERROR_OT(Cheopsregbp.API_CONST_HLPR.INVALID_DATA, Cheopsregbp.API_CONST_HLPR.HTTP_400, l_field_name);
l_api_error.sqlcode := sqlcode;
l_api_error.sqlerrm := sqlerrm;
l_api_error.stacktrace := 'SITE_OT.verify';
API_CORE_HLPR.add_error(l_api_error);
RETURN NULL;
END from_json;
MEMBER PROCEDURE verify(p_parent IN VARCHAR2 := null) AS -- $$ref-ot-verify
l_params Cheopsregbp.API_CONST_HLPR.CHAR1024;
l_parent Cheopsregbp.API_CONST_HLPR.CHAR256;
l_api_error API_ERROR_OT;
BEGIN
IF p_parent IS NOT NULL THEN
l_parent := p_parent || '.';
END IF;
-- key field does not have to be present. POST => new => no PK yet; PUT => PK is in URL!
-- If PK value is specified in body then it should be checked against URL param value though (in business logic)!
/** traductions is REQUIRED!! */
IF SELF.traductions IS NULL THEN
l_api_error := new API_ERROR_OT('REQUIRED', 400, l_parent||'traductions');
l_api_error.sqlerrm := 'REQUIRED' || ':'|| l_parent||'traductions';
l_api_error.stacktrace := 'SITE_OT.verify';
API_CORE_HLPR.add_error(l_api_error);
END IF;
-- validate children (if any)
/** verify all traductions */
IF SELF.traductions IS NOT NULL AND SELF.traductions.COUNT > 0 THEN
<<verify_fields_loop>>
FOR i IN 1 .. SELF.traductions.COUNT LOOP
SELF.traductions(i).verify('traductions['||(i-1)||']'); -- $$verifyChild (UI zero-based)
END LOOP verify_fields_loop;
END IF;
END verify;
MEMBER PROCEDURE add_traductions(p_traductions_map_entry IN TRADUCTIONS_MAP_ENTRY_OT) IS -- $$OOT.ADD2
BEGIN
SELF.traductions.extend;
SELF.traductions(SELF.traductions.last) := p_traductions_map_entry;
END add_traductions;
END;
/
GRANT EXECUTE ON SITE_OT TO Cheopsregbp;
/
我将必须获得2条声明:
我正在考虑多次扫描文本以查找不同的已知语句。 第二个很简单,但是第一个很困难。 第一个命令几乎是全文。它在第二个文本的上方结束。
我不能以'CREATE OR REPLACE ...'开头并以'END;'结尾,因为END;也可以是另一条语句的一部分。
所以实际上我需要找到文本CREATE OR REPLACE ... END;但跳过任何中级
'BEGIN ... END ;'
'IF ... END IF;'
“ LOOP ... END LOOP;”
更难的是,这三个语句中的任何一个都可以在';'之前加一个“标签” 因此,“ LOOP ... END ” LOOP some_label;也应该跳过。
我能够找到所有BEGIN ... END块,而不必使用正则表达式BEGIN\s+.*?\s+END(?!\s+IF|\s+LOOP).*?;
停在中间END IF或END LOOP零件上,但是对于完整的CREATE ... END我似乎做不对。声明。
我想到了正则表达式CREATE(BEGIN\s+.*?\s+END(?!\s+IF|\s+LOOP).*?;|.*?)END
,但是它在第一个begin块的END处再次停止。
答案 0 :(得分:0)
我仅针对Java regex(而非javascript)进行了测试,因此YMMV
尝试(CREATE(BEGIN\s+.*?\s+END(?!\s+IF|\s+LOOP).*?;|.*?)END?).*
I.E。在END上放一个“贪婪”的限定词;