1
1
<!--
2
- $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.24 2001/03/17 18:08:14 petere Exp $
2
+ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.25 2001/03/23 22:07:50 tgl Exp $
3
3
-->
4
4
5
5
<chapter id="plpgsql">
@@ -2407,13 +2407,6 @@ WITH (isstrict, iscachable);
2407
2407
This function should probably be integrated into the core.
2408
2408
</comment>
2409
2409
2410
- <para>
2411
- The third function (that takes 4 parameters) is implemented in
2412
- PL/Tcl but I plan on porting it to PL/pgSQL so in case we want to
2413
- include it in OpenACS we don't need to require PL/Tcl. Plus
2414
- PL/pgSQL should be more efficient.
2415
- </para>
2416
-
2417
2410
<programlisting>
2418
2411
--
2419
2412
-- instr functions that mimic Oracle's counterpart
@@ -2424,127 +2417,128 @@ WITH (isstrict, iscachable);
2424
2417
-- not passed, assume 1 (search starts at first character).
2425
2418
--
2426
2419
-- by Roberto Mello (rmello@fslc.usu.edu)
2420
+ -- modified by Robert Gaszewski (graszew@poland.com)
2427
2421
-- Licensed under the GPL v2 or later.
2428
2422
--
2429
2423
2430
- DROP FUNCTION instr(varchar, varchar);
2431
- CREATE FUNCTION instr(varchar, varchar) RETURNS integer AS '
2424
+ DROP FUNCTION instr(varchar,varchar);
2425
+ CREATE FUNCTION instr(varchar,varchar) RETURNS integer AS '
2432
2426
DECLARE
2433
2427
pos integer;
2434
2428
BEGIN
2435
- pos:= instr($1, $2, 1);
2429
+ pos:= instr($1,$2,1);
2436
2430
RETURN pos;
2437
2431
END;
2438
- ' LANGUAGE 'plpgsql';
2432
+ ' language 'plpgsql';
2433
+
2434
+
2435
+ DROP FUNCTION instr(varchar,varchar,integer);
2436
+ CREATE FUNCTION instr(varchar,varchar,integer) RETURNS integer AS '
2437
+ DECLARE
2438
+ string ALIAS FOR $1;
2439
+ string_to_search ALIAS FOR $2;
2440
+ beg_index ALIAS FOR $3;
2441
+ pos integer NOT NULL DEFAULT 0;
2442
+ temp_str varchar;
2443
+ beg integer;
2444
+ length integer;
2445
+ ss_length integer;
2446
+ BEGIN
2447
+ IF beg_index > 0 THEN
2448
+
2449
+ temp_str := substring(string FROM beg_index);
2450
+ pos := position(string_to_search IN temp_str);
2451
+
2452
+ IF pos = 0 THEN
2453
+ RETURN 0;
2454
+ ELSE
2455
+ RETURN pos + beg_index - 1;
2456
+ END IF;
2457
+ ELSE
2458
+ ss_length := char_length(string_to_search);
2459
+ length := char_length(string);
2460
+ beg := length + beg_index - ss_length + 2;
2461
+
2462
+ WHILE beg > 0 LOOP
2463
+
2464
+ temp_str := substring(string FROM beg FOR ss_length);
2465
+ pos := position(string_to_search IN temp_str);
2466
+
2467
+ IF pos > 0 THEN
2468
+ RETURN beg;
2469
+ END IF;
2470
+
2471
+ beg := beg - 1;
2472
+ END LOOP;
2473
+ RETURN 0;
2474
+ END IF;
2475
+ END;
2476
+ ' language 'plpgsql';
2439
2477
2440
- DROP FUNCTION instr(varchar, varchar, integer);
2441
- CREATE FUNCTION instr(varchar, varchar, integer) RETURNS integer AS '
2478
+ --
2479
+ -- Written by Robert Gaszewski (graszew@poland.com)
2480
+ -- Licensed under the GPL v2 or later.
2481
+ --
2482
+ DROP FUNCTION instr(varchar,varchar,integer,integer);
2483
+ CREATE FUNCTION instr(varchar,varchar,integer,integer) RETURNS integer AS '
2442
2484
DECLARE
2443
2485
string ALIAS FOR $1;
2444
2486
string_to_search ALIAS FOR $2;
2445
2487
beg_index ALIAS FOR $3;
2488
+ occur_index ALIAS FOR $4;
2446
2489
pos integer NOT NULL DEFAULT 0;
2447
- ending integer;
2490
+ occur_number integer NOT NULL DEFAULT 0 ;
2448
2491
temp_str varchar;
2449
2492
beg integer;
2493
+ i integer;
2450
2494
length integer;
2451
- temp_int integer;
2495
+ ss_length integer;
2452
2496
BEGIN
2453
2497
IF beg_index > 0 THEN
2454
- -- Get substring from 1 to beg_index
2498
+ beg := beg_index;
2499
+ temp_str := substring(string FROM beg_index);
2455
2500
2456
- temp_str := substring(string FROM beg_index);
2457
- pos := position(string_to_search IN temp_str);
2501
+ FOR i IN 1..occur_index LOOP
2502
+ pos := position(string_to_search IN temp_str);
2503
+
2504
+ IF i = 1 THEN
2505
+ beg := beg + pos - 1;
2506
+ ELSE
2507
+ beg := beg + pos;
2508
+ END IF;
2509
+
2510
+ temp_str := substring(string FROM beg + 1);
2511
+ END LOOP;
2458
2512
2459
2513
IF pos = 0 THEN
2460
2514
RETURN 0;
2461
2515
ELSE
2462
- RETURN pos + beg_index - 1 ;
2516
+ RETURN beg ;
2463
2517
END IF;
2464
-
2465
2518
ELSE
2519
+ ss_length := char_length(string_to_search);
2466
2520
length := char_length(string);
2521
+ beg := length + beg_index - ss_length + 2;
2467
2522
2468
- IF beg_index = -1 THEN
2469
- ending := length;
2470
- beg := ending;
2471
- temp_int := 1;
2472
- ELSE
2473
- ending := length - abs(beg_index);
2474
- beg := ending;
2475
- temp_int := ending - beg;
2476
- END IF;
2477
-
2478
- WHILE pos = 0 AND beg <> 1 LOOP
2479
-
2480
- temp_str := substring(string FROM beg FOR temp_int);
2523
+ WHILE beg > 0 LOOP
2524
+ temp_str := substring(string FROM beg FOR ss_length);
2481
2525
pos := position(string_to_search IN temp_str);
2482
2526
2483
- -- Keep moving left
2527
+ IF pos > 0 THEN
2528
+ occur_number := occur_number + 1;
2529
+
2530
+ IF occur_number = occur_index THEN
2531
+ RETURN beg;
2532
+ END IF;
2533
+ END IF;
2484
2534
2485
2535
beg := beg - 1;
2486
- temp_int := (ending - beg) + 1;
2487
2536
END LOOP;
2488
- END IF;
2489
2537
2490
- IF pos = 0 THEN
2491
2538
RETURN 0;
2492
- ELSE
2493
- RETURN beg + 1;
2494
2539
END IF;
2495
2540
END;
2496
- ' LANGUAGE 'plpgsql';
2497
-
2498
- --
2499
- -- The next one (where all four params are passed) is in PL/Tcl
2500
- -- because I had no more patience to do it in PL/pgSQL.
2501
- -- It'd probably be faster in PL/pgSQL (that being the reason why
2502
- -- I implemented the first two functions in PL/pgSQL) so someday I'll do it.
2503
- --
2504
-
2505
- DROP FUNCTION instr(varchar, varchar, integer, integer);
2506
- CREATE FUNCTION instr(varchar, varchar, integer, integer) RETURNS integer AS '
2507
- set string1 $1
2508
- set string2 $2
2509
- set n $3
2510
- set m $4
2511
-
2512
- if { $n > 0 } {
2513
- set pos [string first $string2 $string1 [expr $n -1]]
2514
- if { $pos < 0 } {
2515
- return 0
2516
- } else {
2517
- for { set i 1 } { $i < $m } { incr i } {
2518
- set pos [string first $string2 $string1 [expr $pos + 1]]
2519
- if { $pos < 0 } {
2520
- return 0
2521
- }
2522
- }
2523
- }
2524
- }
2525
-
2526
- if { $n < 0 } {
2527
- set pos [string last $string2 $string1 [expr [string length $string1] + $n]]
2528
-
2529
- if { $pos < 0 } {
2530
- return 0
2531
- } else {
2532
- for { set i 1 } { $i < $m } { incr i } {
2533
- # n is negative so we add
2534
- set pos [string last $string2 $string1 [expr $pos - 1]]
2535
- if { $pos < 0 } {
2536
- return 0
2537
- }
2538
- }
2539
- }
2540
- }
2541
-
2542
- if { $pos < 0 } {
2543
- return 0
2544
- } else {
2545
- return [expr $pos + 1]
2546
- }
2547
- ' LANGUAGE 'pltcl';
2541
+ ' language 'plpgsql';
2548
2542
</programlisting>
2549
2543
</sect3>
2550
2544
</sect2>
0 commit comments