Skip to Main Content
  • Questions
  • using oracle text function contains in anymous block with binding variable

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: September 27, 2003 - 5:19 pm UTC

Last updated: May 11, 2009 - 4:42 pm UTC

Version: 8.1.7

Viewed 1000+ times

You Asked

hi tom,

i can easily query an oracle text query with binding through NDS


declare
myval varchar2(253);
begin
myval:= '!google';
execute immediate 'declare ct number; begin SELECT count(*) into ct FROM table WHERE CONTAINS
(col,:x,1)>0 ;dbms_output.put_line(''the count: ''||ct);end;' using myval;

end;

could you please provide a example a oracle text query using contains function with dbms_sql package?

thanks for your advice.

georges

and Tom said...

it is not any different then using a bind with ANY query in dbms_sql.

ops$tkyte@ORA920> /*
DOC>drop table t;
DOC>create table t ( x varchar2(4000) );
DOC>insert into t
DOC>select object_name || ' ' || object_type || ' ' || owner from all_objects;
DOC>create index t_idx on t(x) indextype is ctxsys.context;
DOC>*/
ops$tkyte@ORA920>
ops$tkyte@ORA920> declare
2 l_theCursor integer default dbms_sql.open_cursor;
3 l_columnValue varchar2(4000);
4 l_status integer;
5 l_query varchar2(1000) default 'select x from t where contains( x, :x ) > 0';
6 begin
7 dbms_sql.parse( l_theCursor, l_query, dbms_sql.native );
8 dbms_sql.bind_variable( l_theCursor, ':x', 'SCOTT' );
9 dbms_sql.define_column( l_theCursor, 1, l_columnValue, 4000 );
10
11 l_status := dbms_sql.execute(l_theCursor);
12
13 while ( dbms_sql.fetch_rows(l_theCursor) > 0 )
14 loop
15 dbms_sql.column_value( l_theCursor, 1, l_columnValue );
16 dbms_output.put_line( l_columnValue );
17 end loop;
18
19 dbms_sql.close_cursor(l_theCursor);
20 end ;
21 /
SALGRADE TABLE SCOTT
EMP_PK INDEX SCOTT
EMP_IND1 INDEX SCOTT
EMP TABLE SCOTT
DUMMY TABLE SCOTT
DEPT_PK INDEX SCOTT
DEPT TABLE SCOTT
BONUS TABLE SCOTT

PL/SQL procedure successfully completed.



Rating

  (8 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Java binding runtime variables in Oracle Text

Alan, January 12, 2005 - 7:23 pm UTC

I am using the following syntax in performing an Oracle Text search.

CONTAINS(nm_lst, 'fuzzy(THIERRY,40, 2500, weight)', 2) > 0

I tried writing the following java sql:

CONTAINS(nm_lst, 'fuzzy(? ,40, 2500, weight)', 2) > 0

and binding it at runtime like this:
preparedStatement.setString(1, "THIERRY");

However, I am getting SQLExceptions in doing this? Can you give me a solution for this?

Tom Kyte
January 12, 2005 - 7:48 pm UTC

you would

contains( nm_lst, ?, 2 ) > 0

OR

contains( nm_lst, 'fuzzy(' || ? || ', 40, 2500, weight)', 2 ) > 0


the contains clause takes a "string", you cannot bind in the "middle of a string"

you either bind the string

or a concatention of that string with some other strings.....




Think of it this way:


select * from t where x = 'This ? and that';

? is just a "character" in that string, same with contains.



Excellent Review

Alan, January 21, 2005 - 1:44 pm UTC

Thanks Tom. Exactly what I needed.

Unique Intermedia Search Results

Alan, September 27, 2005 - 10:33 am UTC

Below are two different queries that do not bring back consistent results (the way I see it), and wanted to check with you to see if there is a reason for it.

select nm_upr_lst, nm_upr_frst from person where CONTAINS(NM_UPR_LST, ' fuzzy({ADAM}, 68, 6, weight) ', 2) >0;
* This brings back records with the name ADAM as well as variations of the name ADAM. It sounds correct.

select nm_upr_lst, nm_upr_frst from person where CONTAINS(NM_UPR_LST, ' fuzzy({WILL}, 68, 6, weight) ', 2) >0;
* This brings back only variations of the name WILL but not the name WILL itself; unlike in the example above. I know that the name WILL exists, because it comes back when I do a direct lookup.

My Questions:
1. Is there any way I can change the SQL to have the second example work the same as the first?
2. Is this controlled by the Intermedia search parameters. If so, how do I determine what the optimal parameters are for a name search.

Tom Kyte
September 27, 2005 - 12:06 pm UTC

WILL is a stopword.

http://docs.oracle.com/docs/cd/B10501_01/text.920/a96517/query.htm#1007652

ops$tkyte@ORA9IR2> drop table t;

Table dropped.

ops$tkyte@ORA9IR2> create table t ( x varchar2(100) );

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> insert into t values ( 'Will Adam help them? The Shadow knows....' );

1 row created.

ops$tkyte@ORA9IR2> create index t_idx on t(x) indextype is ctxsys.context;

Index created.

ops$tkyte@ORA9IR2> select token_text from DR$T_IDX$I;

TOKEN_TEXT
----------------------------------------------------------------
ADAM
HELP
KNOWS
SHADOW
THEM



You can modify the default stop list or create your own (perhaps empty) one to use 

Modifying default Stoplist

Alan, September 27, 2005 - 1:15 pm UTC

Thanks for the prompt response.

I looked through the default stoplist for the Englist language and all the rest seem legitimate in our case, with the exception of this word. I am better off keeping the rest of the stopwords. I am trying to write a PL/SQL proc to remove the WILL from the default stoplist.

SET SERVEROUTPUT OFF size 100000;
declare
default_stoplist varchar2(100) := CTXSYS.DEFAULT_STOPLIST;
begin
ctx_ddl.remove_stopword( default_stoplist,'will');
end;

Will this work?

Tom Kyte
September 27, 2005 - 1:54 pm UTC

when you tested it, what happened? (remember, rebuild after making that change..)

Rebuilding Oracle Text Index

Alan, September 27, 2005 - 4:56 pm UTC

The script ran fine and removed the stop word from the default list. I then dropped and created the indexes and it worked fine.

However, I have a question about this. When I created another record with the name 'Will', I ran

Ctx_Ddl.optimize_index('index_name', 'FULL' );

This time, the record did not come back until I actually dropped and recreated all indexes again.

Does this mean that I have to drop and recreate all indexes each time? Or am I doing something incorrectly?

Tom Kyte
September 27, 2005 - 8:19 pm UTC

got a script to recreate the entire situation for me? from dropping the stop word on.....

(gotta have a test case...)

My Error!

Alan, September 27, 2005 - 7:02 pm UTC

I figured out my error. I should have been doing a sync instead of an optimize. It works fine now!

Thanks!

Using bind variable with Oracle Text Query Rewrite in Perl

A reader, September 29, 2005 - 2:11 pm UTC

This is great info. I searched and tried for hours to find a way to use bind variables in the middle of a query that uses Oracle Text Query Rewrite. Using || concatenation characters to build the query was the solution (<textquery>' || :1 || '). This is executed from a Perl application.

SELECT * FROM (
SELECT customer_name, score(1), contact_name, date_opened, tn, domain_name
FROM owner.table_name
WHERE contains(domain_name,'
<QUERY>
<textquery>' || :1 || '
<progression>
<seq><REWRITE>transform((TOKENS, "{" , "}", " " ))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "{" , "}", "AND"))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "{" , "}", "OR" ))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "${", "}", " " ))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "${", "}", "AND"))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "${", "}", "OR" ))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "?{", "}", " " ))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "?{", "}", "AND"))</REWRITE></seq>
<seq><REWRITE>transform((TOKENS, "?{", "}", "OR" ))</REWRITE></seq>
</progression>
</textquery>
</QUERY>
',1 )> 0
ORDER BY score(1) DESC
) WHERE ROWNUM <= :2


Probelm with Oracle Text contains

Raouel, May 09, 2009 - 9:33 am UTC

Hi tom,
i have this Select Querry in a PL/SQL Procedure, but is not worked, please HELP ME!

select e.DOKUMENT_NR ,
e.ABTEILUNG ,
e.DATUM ,
e.username1,
e.username2,
concat (concat (d.NACHNAME, ' '), d.VORNAME) as Bearbeiter1 ,
concat (concat (r.NACHNAME, ' '), r.VORNAME) as Bearbeiter2 ,
e.ABLAGE,
e.VERTEILER ,
e.SACHE ,
e.SCHLÜSSELWÖRTER ,
e.TYP ,
e.SCHUTZKLASSE ,
be_rotbuch2005.ENTWICKLUNGSBERICHTE_BLOBS.DOKUMENT_TYPE ,
f.Permission
FROM be_rotbuch2005.ENTWICKLUNGSBERICHTE e
FULL OUTER JOIN be_rotbuch2005.ENTWICKLUNGSBERICHTE_BLOBS
ON (e.dokument_nr = be_rotbuch2005.ENTWICKLUNGSBERICHTE_BLOBS.dokument_nr)
FULL OUTER JOIN be_rotbuch2005.ENTWICKLUNGSBERICHTACL f
ON (e.dokument_nr = f.DOCUMENTID)
FULL OUTER JOIN ASPNET.ORA_ASPNET_USERPROFILES d
ON (e.username1 = d.username )
FULL OUTER JOIN ASPNET.ORA_ASPNET_USERPROFILES r
ON (e.username2 = r.username )
where contains (e.SCHLÜSSELWÖRTER, P_Search_String) > 0
or contains (e.sache, P_Search_String) > 0

the error is.

ERROR
ORA-29900: Operator-Bindung ist nicht vorhanden
ORA-06553: PLS-307: Zu viele Deklarationen von 'CONTAINS' entsprechen diesem Aufruf

Tom Kyte
May 11, 2009 - 4:42 pm UTC

got example?

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library