Oracle text phrase error (DRG-50920). Query parsing and SYN function - oracle

I just started working with Oracle Text, already red the docs but I really struggle to find a solution.
Currently using with progressive relaxation but I keep getting the following error:
ORA-29902: error in executing ODCIIndexStart() routine
ORA-20000: Oracle Text error:
DRG-50920: part of phrase not itself a phrase or equivalence
29902. 00000 - "error in executing ODCIIndexStart() routine"
*Cause: The execution of ODCIIndexStart routine caused an error.
*Action: Examine the error messages produced by the indextype code and
take appropriate action.
I have two questions:
How to escape the query in the tag? Maybe {} ? Without escaping it won't work when I type something like COCA COLA 0,5L.
On the other hand, when the query is enclosed in the escape chars ({ }) and I try with "EL K" it thorws the same exception. "EL" is part of a thesaurus.
Code
Table and index creation:
CREATE TABLE "DAVID"."INVENTAR_DEV" (
"ID" VARCHAR2(16 BYTE)
NOT NULL ENABLE,
"NAME" VARCHAR2(255 BYTE)
NOT NULL ENABLE
);
CREATE INDEX "DAVID"."INV_DEV_NAME_IDX" ON
"DAVID"."INVENTAR_DEV" (
"NAME"
)
INDEXTYPE IS "CTXSYS"."CONTEXT" PARAMETERS ( 'DATASTORE CTXSYS.DEFAULT_DATASTORE FILTER CTXSYS.NULL_FILTER LEXER INVENTAR_DEV_LEXER WORDLIST INV_DEV_WORDLIST STOPLIST CTXSYS.EMPTY_STOPLIST'
);
The SELECT which I'm using:
SELECT /*+ FIRST_ROWS(150) */
XMLELEMENT("object",
XMLForest(i.id "id",
i.name "name"
).getStringVal()
FROM david.inv_dev i
WHERE contains(i.name,
'<query>
<textquery grammar="context"> {EL KOS}
<progression>
<seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " "))</rewrite></seq>
<seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " AND "))</rewrite></seq>
</progression>
</textquery>
<score datatype="FLOAT" algorithm="DEFAULT"/>
<order>
<orderkey> Score DESC </orderkey>
</order>
</query>', 1) > 0;
Also created my own WORDLIST and LEXER:
BEGIN
ctx_ddl.create_preference('INVENTAR_DEV_LEXER','BASIC_LEXER');
ctx_ddl.set_attribute('INVENTAR_DEV_LEXER', 'numgroup',',');
ctx_ddl.set_attribute('INVENTAR_DEV_LEXER', 'numjoin','.');
ctx_ddl.set_attribute('INVENTAR_DEV_LEXER', 'skipjoins','.-_%:;/,()?!*+');
ctx_ddl.create_preference('INV_DEV_WORDLIST', 'BASIC_WORDLIST');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','FUZZY_MATCH','GENERIC');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','FUZZY_SCORE','70');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','FUZZY_NUMRESULTS','10');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','SUBSTRING_INDEX','FALSE');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','STEMMER','NULL');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','PREFIX_INDEX','TRUE');
ctx_ddl.set_attribute('INV_DEV_WORDLIST','PREFIX_MIN_LENGTH',3);
ctx_ddl.set_attribute('INV_DEV_WORDLIST','PREFIX_MAX_LENGTH',7);
Ctx_thes.create_thesaurus('inv_thes', FALSE); -- NAMEE, CASE-SENSITIVE
CTX_THES.CREATE_RELATION('inv_thes','el','SYN','elektro');
END;
Update
I realized that SYN({something}, thes) doesn't work when there are multiple words devided by spaces.
So there must be an operator between those words.
The query works with the SYN if I remove the following line from the textquery:
<seq><rewrite>transform((TOKENS, "FUZZY(SYN({", "}, inv_thes), 70, 10, weight)", " "))</rewrite></seq>
But I'm still not sure what could be the reason.

My solution to the problem was to use a custom workaround function instead of SYN and a custom query parsing function.
The workaround function for SYN:
FUNCTION f_synonyms(p_word IN VARCHAR2)
RETURN VARCHAR2
AS
CURSOR c_synonyms (p_word IN VARCHAR2)
IS
SELECT REPLACE(CTX_THES.SYN(p_word, g_thesaurus_name), '|','=')
FROM SYS.dual;
v_retVal VARCHAR(255);
BEGIN
OPEN c_synonyms(p_word);
FETCH c_synonyms INTO v_retVal;
CLOSE c_synonyms;
RETURN v_retVal;
END;

Related

"Invalid SQL type: sqlKind = UNINITIALIZED" While running query from JMeter

The following query I am trying to execute it from JMeter,
DECLARE
j number(4)
BEGIN
FOR j in 11 .. 12 LOOP
INSERT INTO FWA_STAGE_TU
(ID,EXT_ID,BATCH_NO,OPERATION,BLOCK_ROLL_UP_LAST_RECORD,LAST_UPDATED_DATE,ERROR_FLAG,TRIAL_NO,TRIAL_ALIAS_CODE,
COUNTRY_CODE,DISPLAY_UNIT_NO,GROUP_NO,TRIAL_UNIT_REFERENCE,PRIMARY_INVESTIGATOR,PRIMARY_CENTRE,OCATION_NO,
PURPOSE_CODE,MANAGING_MED_UNIT_CODE,UPDATING_MED_UNIT_CODE,FINANCE_MED_UNIT_CODE,PATIENTS_ALL_SET_UP_FLAG,
PATIENT_MONITORING_FLAG,COMMENTS,CONFIRMED_FLAG,CONFIRMED_BY,CONFIRMED_DATE,ROLLUP_ROLLDOWN_PLANNED_FIGS,
DOC_COLLECTION_INDICATOR,VALIDATED_PAT_CAP,MAXIMUM_PAT_CAP,PREFERRED_LANGUAGE_CODE,NEW_DISPLAY_UNIT_NO,
TOTAL_OPEN_DCF_ISSUES_NO,ORDER_INTERVAL,ORDER_INTERVAL_UNITS,DATA_SOURCE_CODE,RANK_SEQ)
VALUES
(j, 1, 10, 'I', NULL, SYSDATE, 'N', 102922, 'TESTTRIAL4', 'BEL',
j, NULL, 'BELTU'||j, 130262, 124236, NULL, 'PATTR', 'FP', 'FP', 'FP', 'N', 'Y', 'TESTTU'||j,
'Y', 999999, SYSDATE, NULL, 'P', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
END LOOP
END
When I wrap them the entire query inside "DECLARE .....END" and execute I am getting the following errors,
With
transaction isolation type 'TRANSACTION_SERIALIZABLE' and Query Type callable I am getting Invalid SQL type: sqlKind = UNINITIALIZED
transaction isolation type 'TRANSACTION_SERIALIZABLE' and Query Type update I am getting Invalid SQL type: sqlKind = UNINITIALIZED
When I wrap them "" and + at the end of every line something like
"DECLARE" +.......
"j number(4)" + ......"END LOOP" +....
"END"
transaction isolation type 'TRANSACTION_SERIALIZABLE' and Query Type callable I am getting Invalid SQL type: sqlKind = UNINITIALIZED
transaction isolation type 'TRANSACTION_SERIALIZABLE' and Query Type update I am getting Invalid SQL type: sqlKind = UNINITIALIZED
When I wrap them inside {call .... } something like
{call DECLARE ......END} I am getting
ORA-06550: line 3, column 1:
PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following:
:= ; not null default character
The symbol ";" was substituted for "BEGIN" to continue.
ORA-06550: line 17, column 1:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
; <an identifier> <a double-quoted delimited-identifier>
The symbol ";" was substituted for "END" to continue.
How to resolve this issue ? It worked fine from Oracle SQL Developer.
Transaction isolation level has nothing to do with your problem, see Using JDBC Sampler in JMeter article for comprehensive information on what each setting mean.
Your problem is that you're trying to run PL/SQL script and you're supposed to provide an SQL statement.
The options are in:
Create a stored procedure in your Oracle DB and invoke the stored procedure using JMeter's "Callable Statement"
Wrap your PL/SQL script into EXECUTE IMMEDIATE
Use JMeter's Loop Controller instead of Oracle's loop in order to run your INSERT query as many times as you need

how to save synonyms in database ( Oracle Text )

I am using oracle text for Arabic language.
I want to save the synonyms list in a database table, so the domain index read from this table, any idea ?
I found a solution :
1- I uploaded my synonyms list to a table called words( contains all the terms and their synonyms' IDs ) and master table called synset (contains synonyms)
2- create thesaurus :
begin
ctx_thes.create_thesaurus ('MyThesaurus');
end;
3- create a stored procedure to read from my table [words] and create relationship between synonyms:
create or replace procedure CreateSynonyms is
CURSOR syn_cur is select s.name_abstract,w.root,w.word_abstract
from p words w , synset s
where w.synset_id=s.synset_id and w.root<>s.name_abstract and w.word_abstract<> s.name_abstract
order by s.synset_id;
syn_rec syn_cur%rowtype;
BEGIN
OPEN syn_cur;
LOOP
FETCH syn_cur into syn_rec;
EXIT WHEN syn_cur%notfound;
begin
ctx_thes.create_relation ('MyThesurus', syn_rec.name_abstract, 'syn', syn_rec.word_abstract);
END LOOP;
END;
4- rewrite my query to select synonyms:
select /*+ FIRST_ROWS(1)*/ sentence_id,score(1) as sc, isn
where contains(PROCESSED_TEXT,'<query>
<textquery>
search for somthing here
<progression>
<seq><rewrite>transform((TOKENS, "{", "}", ","))</rewrite></seq>
<seq><rewrite>transform((TOKENS, "syn(", ",listing)", " , "))</rewrite>/seq>
</progression>
</textquery>
<score datatype="INTEGER" algorithm="COUNT"/></query>',1)>0
Hope this will help someone

ORA-29902: error in executing ODCIIndexStart() routine ORA-20000: Oracle Text error: DRG-50901: text query parser syntax error on line 1, column 19

SELECT person_no sub_sys_individual_id,
nm_e,
nm_a,
nvl(sex, -1) sex,
nvl(prs_nat, -999) prs_nat,
person_no,
'NA' prog_where_not_allowed,
'NA' udb_no,
person_tp,
pass_no
FROM ban_inq_tab
WHERE contains (nm_e ,'xxstart JUHETI BT MEMED ASMANI%') >0
AND (trans_flag IS NULL OR trans_flag = 'C');
please help me in this issue and getting parser syntax error
You must escape the BT special word (but you can just escape the entire string).
SELECT person_no sub_sys_individual_id,
nm_e,
nm_a,
nvl(sex, -1) sex,
nvl(prs_nat, -999) prs_nat,
person_no,
'NA' prog_where_not_allowed,
'NA' udb_no,
person_tp,
pass_no
FROM ban_inq_tab
WHERE contains (nm_e ,'{xxstart JUHETI BT MEMED ASMANI}%') >0
AND (trans_flag IS NULL OR trans_flag = 'C');
FYI, you'll also get this error (i'm on Oracle 12.2) if you have the input parameter to a stored proc that will be the query in a contains predicate as an NVARCHAR2.
So if you have input params to a stored proc as NVARCHAR2 and that parameter is destined for the query in the contains predicate, then change it to VARCHAR (or maybe CLOB) and it will no longer throw this error.
The error is causing the BT, which is a reserved word. The solution is described in the Oracle Community forum.

Expected CHAR got NUMBER

DB: Oracle 11g
Query:
SELECT CASE
WHEN rs.OPTION = '3'
THEN
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_GRP cg
ON cg.GROUP_ID = ex.GRP_ID
)
ELSE
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_POL cg
ON cg.GROUP_ID = ex.GRP_ID
)
END AS PROPTS
FROM PR_OPTS
I am getting error 'expected CHAR got NUMBER', here EXTS,GROUP_ID & GRP_ID are numeric. Then how there is a chance of expecting CHAR?
Generally when Oracle compares different datatypes such as a NUMBER with a CHARACTER, implicit conversion kicks in and all is well (provided the data can be converted.) For example, if you have a function that expects a CHARACTER value but you pass it a NUMBER, all is well - Oracle simply converts the NUMBER to character.
E.g. a function like this:
create or replace function get_something(p_id VARCHAR2) return number ...
works if you call it with this:
get_dno(10);
or this:
get_dno('10');
and in SQL:
select * from some_table where numeric_column = '10' -- no problem.
A popular place where you see this kind of error is with the return values in CASE statements. For instance, you'll get that error if you have something like this:
SQL> SELECT CASE WHEN 1 = 1 THEN '1' ELSE 2 END
2 FROM dual
3 ;
SELECT CASE WHEN 1 = 1 THEN '1' ELSE 2 END
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected CHAR got NUMBER
(The datatype from the first WHEN clause is what it expects in the other WHEN/ELSE clauses that follow.)
But in your case the WHEN and THEN both return counts - the datatypes are consistent. So, I think you have a red-herring in there.
As Alex mentioned above, OPTION is a keyword and if you try and create a table with that as a column name, Oracle disagrees:
SQL> create table dummy
2 (option varchar2(10)
3 );
(option varchar2(10)
*
ERROR at line 2:
ORA-00904: : invalid identifier
This works:
SQL> create table dummy
2 (option_col varchar2(10)
3 );
Table created.
or you could do it with quotes:
SQL> create table dummy
2 ("option" varchar2(10));
Table created.
But now you're in a world of hurt - you need quotes from now on:
SQL> select option from dummy;
select option from dummy
*
ERROR at line 1:
ORA-00936: missing expression
SQL> select d.option from dummy d;
select d.option from dummy d
*
ERROR at line 1:
ORA-01747: invalid user.table.column, table.column, or column specification
With quotes:
SQL> select d."option" from dummy d;
no rows selected
So, if your query is really giving you "expected CHAR, got NUMBER", it looks to me like something is off.
Essentially, it means some of the fields you are using aren't compatible with each other. It's basically a "type mismatch". Just check to see if any types of CHAR are being used with types of NUMBER. Then you can either switch the type of one, or simply use a conversion as part of the query.
The issue is OPTION = '3', the quotation marks indicate that you're looking for a string containing the solitary character 3.
Try this instead:
SELECT CASE
WHEN rs.OPTION = 3
THEN
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_GRP cg
ON cg.GROUP_ID = ex.GRP_ID)
ELSE
(SELECT COUNT(DISTINCT ex.EXTS) AS TMPCOL0
FROM CRSIDM.SUB_OPTS ex
INNER JOIN CRSIDM.SUB_OPTS_POL cg
ON cg.GROUP_ID = ex.GRP_ID)
END AS PROPTS
FROM PR_OPTS

Error on ORACLE trigger

I have this sexy trigger, that takes a value from a field REFERENT, parses it, finds a row in some view and fills some data to original row that needs to be inserted. I also then re-write the REFERENT field and eliminate the extra data.
The REFERENT field looks like this: "-XXX-123", where 123 is the key that i search data in the view. Hope it makes sense.
CREATE OR REPLACE TRIGGER TRI_UPDATE
BEFORE INSERT
ON TBLASCENTOUTPUT_X
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
WHEN (
new.STEVILKA_NAROCILA is NULL
)
DECLARE
PARSED_STNAROC VARCHAR(255);
PARSED_PRIMARY_VALUE VARCHAR(255);
BEGIN
PARSED_STNAROC := SUBSTR(NEW.REFERENT, INSTR(NEW.REFERENT, '-', -1, 1) + 1);
PARSED_PRIMARY_VALUE := SUBSTR(NEW.REFERENT, 1, INSTR(NEW.REFERENT, '-', -1, 1) - 1);
select distinct v.STNAROCILA, v.DATNAROCILA, v.SIFKUPCA, v.STPONUDBE, PARSED_PRIMARY_VALUE
into :NEW.STEVILKA_NAROCILA, :NEW.DATUM_NAROCILA, :NEW.SIFRA_KUPCA, :NEW.STEVILKA_PONUDBE, :NEW.REFERENT
from ARH_NAROC v
where v.STNAROCILA = PARSED_STNAROC;
END;
I am getting the following error on compile:
On line: 6
TRIGGER EASY.TRI_UPDATE
PLS-00201: identifier 'NEW.REFERENT' must be declared
Help please.
A colon character is missed before NEW.REFERENT

Resources