powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Ошибка при разборе getStringVal
14 сообщений из 14, страница 1 из 1
Ошибка при разборе getStringVal
    #39525325
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет. Может кто-то наведет на правильную мысль. Есть такая конструкция:

Код: plsql
1.
2.
3.
4.
5.
6.
SELECT TRANSLATE (
                        XMLAGG (XMLELEMENT ("node", d1.name)).getStringVal (),
                        '<node>/',
                        ' ')
                FROM ICC_RSR.DICT_REGIONS d1
               WHERE opv.text_value LIKE '%' || TO_CHAR (d1.reg_id) || '%'



В которую передается строка вида:
Код: sql
1.
1,2,6


то названия из справочника региона подтягиваются правильно, согласно классификации reg_id
Но, если передать строку вида:
Код: sql
1.
24


то отработка происходит, по 2, 4 и 24 ! Почему так происходит, может есть вариант как можно четко организовать правильную передачу ,в чем загвоздка?
Код: plsql
1.
2.
3.
4.
5.
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE	10.2.0.5.0	Production
TNS for Linux: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525328
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А мозг включить?

Код: plsql
1.
opv.text_value LIKE '%' || TO_CHAR (d1.reg_id) || '%'



превращаетcя для d1.reg_id = 2 в

Код: plsql
1.
'24' LIKE '%2%'



и результат = TRUE. Для d1.reg_id = 4 в

Код: plsql
1.
'24' LIKE '%4%'



и результат = TRUE. Для d1.reg_id = 24 в

Код: plsql
1.
'24' LIKE '%24%'



и результат тоже TRUE. Проверять надо:

Код: plsql
1.
',' || opv.text_value || ',' LIKE '%,' || TO_CHAR (d1.reg_id) || ',%' and d1.reg_id IS NOT NULL



А лучше:

Код: plsql
1.
d1.reg_id in (select regexp_substr(opv.text_value,'[^,]+',1,level) from dual connect by level <= regexp_count(opv.text_value,',') + 1)



SY.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525339
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не заметил версию 10.2, так-что замени REGEXP_COUNT на REGEXP_REPLACE + LENGTH. Надеюсь сообразишь. А если гоняешься за миллисекундами, то замени REGEXPы на SUBSTR + INSTR.

SY.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525341
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Спасибо.

Но я не понял почему для
Код: plsql
1.
opv.text_value LIKE '%' || TO_CHAR (d1.reg_id) || '%'


когда поступает строка именно 24 , а она режется на 2, затем 4 и 24.

И почему лучше использовать:

Код: plsql
1.
d1.reg_id in (select regexp_substr(opv.text_value,'[^,]+',1,level) from dual connect by level <= regexp_count(opv.text_value,',') + 1)
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525343
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sheriffua,

Для тех кто в т-34, LIKE '%2%' означает поверку на наличие двойки в любой позиции, так что резльтат будет "да" для любого значения opv.text_value в котором присутствует двойкa.

SY.
P.S. Забыл что у тебя разделитeль дробной части зпт а не тчк как у мeня. И вообще, чтобы избежать NLS проблем используй другoй разделитeль в opv.text_value, например, pipe вкупе с:

Код: plsql
1.
'|' || opv.text_value || '|' LIKE '%|' || TO_CHAR (d1.reg_id) || '|%' and d1.reg_id IS NOT NULL
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525344
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SheriffuaИ почему лучше использовать:


d1.reg_id может быть проиндексирован.

SY.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525385
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYSheriffua,

Для тех кто в т-34, LIKE '%2%' означает поверку на наличие двойки в любой позиции , так что резльтат будет "да" для любого значения opv.text_value в котором присутствует двойкa.

SY.
P.S. Забыл что у тебя разделитeль дробной части зпт а не тчк как у мeня. И вообще, чтобы избежать NLS проблем используй другoй разделитeль в opv.text_value, например, pipe вкупе с:

Код: plsql
1.
'|' || opv.text_value || '|' LIKE '%|' || TO_CHAR (d1.reg_id) || '|%' and d1.reg_id IS NOT NULL



)))

Еще раз - строка opv.text_value = 24 , но разбор происходит как 2 и 4 и 24... этим выражением:
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT TRANSLATE (
                        XMLAGG (XMLELEMENT ("node", d1.name)).getStringVal (),
                        '<node>/',
                        ' ')
                FROM ICC_RSR.DICT_REGIONS d1
               WHERE opv.text_value LIKE '%' || TO_CHAR (d1.reg_id) || '%'


Т.е. в строку
Код: sql
1.
WHERE opv.text_value LIKE '%' || TO_CHAR (d1.reg_id) || '%'


почему происходит преобразование в 2, затем в 4, и затем в 24? Это getStringVal так преобразует или что смотреть чтобы понять отчего происходит такой разбор?
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525388
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sheriffuaчто смотреть чтобы понять отчего происходит такой разбор? 20818315 - просто снимись с ручника, там Соломон всё подробнейше разжевал.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525430
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sheriffuaпочему происходит преобразование в 2, затем в 4, и затем в 24? Это getStringVal так преобразует или что смотреть чтобы понять отчего происходит такой разбор?

Да причем тут getStringVal??? Я кажется ясно обьяснил что без обрамления разделитeлями LIKE '%' || TO_CHAR (d1.reg_id) || '%' выдаст "да" если d1.reg_id является частью одного из чисел в opv.text_value:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
with d1 as (
            select 2  reg_id from dual union all
            select 4  reg_id from dual union all
            select 24 reg_id from dual
           )
select  reg_id
  from  d1
  where '24' like '%' || to_char(d1.reg_id) || '%'
/

    REG_ID
----------
         2 -- символ двойка присутствует в строке '24' (мы сраниваем строки, не числа) посему '24' like '%2%' дает "да"
         4 -- символ четверка присутствует в строке '24' (мы сраниваем строки, не числа) посему '24' like '%4%' дает "да"
        24 -- символ двойка за которой слeдует символчетверка (мы сраниваем строки, не числа) присутствует в строке '24' посему '24' like '%24%' дает "да" 

SQL>



SY.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525445
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

спасибо за подробное разъяснение.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525455
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sheriffuaспасибо за подробное разъяснение.

Но я советую:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
d1.reg_id in (
              select  regexp_substr(opv.text_value,'[^,]+',1,level)
                from  dual
                connect by level <= length(
                                           regexp_replace(
                                                          opv.text_value || ',',
                                                          '[^,]'
                                                         )
                                          )
             )



SY.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525558
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYSheriffuaспасибо за подробное разъяснение.

Но я советую:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
d1.reg_id in (
              select  regexp_substr(opv.text_value,'[^,]+',1,level)
                from  dual
                connect by level <= length(
                                           regexp_replace(
                                                          opv.text_value || ',',
                                                          '[^,]'
                                                         )
                                          )
             )



SY.

Спасибо за совет с применением регулярных выражений.
Если несложно, то в двух словах, чем он лучше LIKE? , который ты привел в своем первом сообщении?
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525768
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SheriffuaЕсли несложно, то в двух словах, чем он лучше LIKE? , который ты привел в своем первом сообщении?

Я уже обьяснял: d1.reg_id может быть проиндексирован.


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
SQL> explain plan for
  2  select  *
  3    from  emp
  4    where ',' || '7566,7654,7698' || ',' like '%,' || empno || ',%'
  5  /

Explained.

SQL> select  *
  2    from  table(dbms_xplan.display)
  3  /

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------

Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    38 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     1 |    38 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(',7566,7654,7698,' LIKE '%,'||TO_CHAR("EMPNO")||',%')

13 rows selected.

SQL> explain plan for
  2  select  *
  3    from  emp
  4    where empno in (
  5                    select  regexp_substr('7566,7654,7698','[^,]+',1,level)
  6                      from  dual
  7                      connect by level <= length(regexp_replace('7566,7654,7698'  || ',','[^,]'))
  8                   )
  9  /

Explained.

SQL> select  *
  2    from  table(dbms_xplan.display)
  3  /

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------

Plan hash value: 1513497066

------------------------------------------------------------------------------------------------------
| Id  | Operation                                 | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                          |          |     1 |    68 |     4  (25)| 00:00:01 |
|   1 |  NESTED LOOPS                             |          |     1 |    68 |     4  (25)| 00:00:01 |
|   2 |   NESTED LOOPS                            |          |     1 |    68 |     4  (25)| 00:00:01 |
|   3 |    VIEW                                   | VW_NSO_1 |     1 |    30 |     3  (34)| 00:00:01 |
|   4 |     HASH UNIQUE                           |          |     1 |       |     3  (34)| 00:00:01 |
|*  5 |      CONNECT BY WITHOUT FILTERING (UNIQUE)|          |       |       |            |          |
|   6 |       FAST DUAL                           |          |     1 |       |     2   (0)| 00:00:01 |
|*  7 |    INDEX UNIQUE SCAN                      | PK_EMP   |     1 |       |     0   (0)| 00:00:01 |
|   8 |   TABLE ACCESS BY INDEX ROWID             | EMP      |     1 |    38 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - filter(LEVEL<=3)
   7 - access("EMPNO"=TO_NUMBER("REGEXP_SUBSTR('7566,7654,7698','[^,]+',1,LEVEL)"))

Note
-----
   - this is an adaptive plan

25 rows selected.

SQL>



И если даже если индекса нет, то он может понадобиться позже когда, например, обьем данных возрастет и TABLE ACCESS FULL станет слишком медленным. В случае с LIKE придется переписывать код а с IN все прозрачно и он подхватит созданный индекс.

SY.
...
Рейтинг: 0 / 0
Ошибка при разборе getStringVal
    #39525845
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Теперь все понятно. Спасибо еще раз за подробное объясение, тему можно закрывать.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Ошибка при разборе getStringVal
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]