|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Oracle 19.3.0.0.0 Приветствую, я в шоке, такого точно не было в Oracle 9. Это баг? Итак, Oracle 19.3.0.0.0 Есть таблица, в которой поле (IsDeleted) при выставлении его в "1" должно в том числе заставлять UNIQUE-индекс игнорировать данную строчку таблицы. Так вот, при INSERT новой строки в таблицу проверка работает, но при UPDATE проверка перестала в Oracle 19 работать, если индекс определён с использованием decode, но работает при использовании CASE Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
при UPDATE правильно работает при использовании CASE в описании индекса Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
при UPDATE неправильно работает при использовании DECODE в описании индекса Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
И вот что получаем: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:07 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Кроик Семёнdecode(IsDeleted, А теперь вопрос на засыпку: это IsDeleted из контекста NEW или OLD? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:16 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, разве индекс не для NEW? ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:18 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Кроик Семёнразве индекс не для NEW? Да, пожалуй. Походу, я его с CHECK CONSTRAINT перепутал. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:22 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Кроик Семён, Код: 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.
P.S. В рамках SR'а лет 8 назад поддержка рекомендовала отказываться от decode в пользу case (мол, "эти баги низкоприоритетные", "скоро decode на пенсию отправят"). Но вроде жив еще курилка. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:29 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Кроик Семён, а если? decode(IsDeleted, 1, cast(NULL as date) , trunc(AnyDate)) ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:32 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Stax , классно, decode()+CAST заработало. Спасибо Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:43 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Asmodeus Version 19.12.0.0.0 ... ORA-00001 Похоже, где-то в середине поправили таки баг был значит, спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 16:44 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Кроик Семён таки баг был значит, спасибо Да не баг это а твое не RTFM. Тип результата decode есть тип первого decoded expression - у тебя NULL. NULL не имеет типа. Oracle решил что в ситуациях когда необходим тип выражения а выражение NULL (не путать со значением выражения равным NULL) считать тип VARCHAR2. Посему: Код: plsql 1. 2. 3.
вернет TO_CHAR(trunc(AnyDate),<instance NLS_DATE_FORMAT>). Код: 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.
По идее Oracle должен бы выругаться и не дать создать NLS зависимый индекс. Возможно он инвалидирует индекс при изменении instance NLS_DATE_FORMAT, не пробовал. В любом случае - индекс завязанный на неявные преобразования рано или поздно выстрелит. Так-что CAST(NULL AS DATE) решает все эти проблемы. И это не зависит от DECODE/CASE. Тип результата case также есть тип первого case expression. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 20:21 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SYвернет TO_CHAR(trunc(AnyDate),<instance NLS_DATE_FORMAT>). Это не правда. Будет использован database NLS_DATE_FORMAT, что пример и продемонстрировал. SYВозможно он инвалидирует индекс при изменении instance NLS_DATE_FORMAT, не пробовал. Oracle так не будет делать. SYИ это не зависит от DECODE/CASE. Тип результата case также есть тип первого case expression. От DECODE и CASE зависит. CASE работает несколько иначе в определении типов данных и для приведенного примера тип данных CASE будет DATE. Код: 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.
Очевидно, случился выстрел в ногу. Это баг. Чтобы понять, что происходит, нужно посмотреть небольшой пример. Код: 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. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197.
Здесь наиболее интересен дамп индекса, который объясняет, почему Oracle пропустил update: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Пока все похоже на то, что без явного формата: 1. Oracle использует database NLS_DATE_FORMAT при построении индекса 2. при INSERT/UPDATE - использует NLS_DATE_FORMAT сессии. Например, можно закомментировать UPDATE и INSERT пройдет, что будет 2 строки и произойдет ситуация, которая никогда не должна происходить: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
3. при rebuild Oracle корректно определяет, что есть duplicate keys: Код: plsql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
05.01.2022, 22:39 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
классный разбор ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 01:02 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SeaGate Будет использован database NLS_DATE_FORMAT, что пример и продемонстрировал. Похоже берет из сессии: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Создаем таблицу с двумя записями где даты разнятся > 1 секунды и затем создаем уникальный индекс: Код: 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.
Как видим да, не instance как как instance NLS_DATE_FORMAT='mm/dd/yyyy hh24:mi:ss' т.е. до секунд. Теперь тоже самое но даты разнятся > 1 минуты: Код: 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.
Индекс создался - значит не database как как database NLS_DATE_FORMAT='DD-MON-RR' т.е. до дня. Так-что похоже мы оба промахнулись и используется session NLS_DATE_FORMAT. SeaGate От DECODE и CASE зависит. CASE работает несколько иначе в определении типов данных и для приведенного примера тип данных CASE будет DATE. Проверил, таки да. И тогда это либо баг в CASE либо баг в доке, ибо CASE Expressions глаголит: For both simple and searched CASE expressions, all of the return_exprs must either have the same data type (CHAR, VARCHAR2, NCHAR, or NVARCHAR2, NUMBER, BINARY_FLOAT, or BINARY_DOUBLE) or must all have a numeric data type. If all return expressions have a numeric data type, then Oracle determines the argument with the highest numeric precedence, implicitly converts the remaining arguments to that data type, and returns that data type. А поскольку NULL datatype есть VARCHAR2, то согласно доке Код: plsql 1. 2. 3. 4.
Oracle должен бы выругаться. Пример показывающий тип NULL: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Кстати у VARCHAR2 нет длины - похоже еще один баг :). SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 01:42 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Если я правильно понял то что вы написали, это сводится к такому тест кейсу test Код: 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.
output Код: 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. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109.
похоже на жука ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 02:15 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Все можно было проверить куда проще : Код: plsql 1. 2. 3. 4. 5. 6. 7.
Так-что: 1. мы оба промахнулись и используется session NLS_DATE_FORMAT. 2. при INSERT/UPDATE - использует NLS_DATE_FORMAT сессии - тоже нет, т.к. неявное преобразование использующее session NLS_DATE_FORMAT на момент создания индекса закрепляется в COLUMN_EXPRESSION и становится явным для всех последующих действий. Но все равно я бы предпочел чтобы Oracle ругнулся на создание FBI с неявным преобразованием. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 02:15 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Alexander Anokhin Если я правильно понял то что вы написали, это сводится к такому тест кейсу test Код: 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.
output Код: 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. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109.
похоже на жука немного короче Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 02:37 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SY я бы предпочел чтобы Oracle ругнулся на создание FBI с неявным преобразованием даже такие Код: 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.
По поводу "умного" case: можно уточнить, что тип берется из первого не-нуллового expression Код: plsql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 02:45 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Alexander Anokhin Alexander Anokhin Если я правильно понял то что вы написали, это сводится к такому тест кейсу test Код: 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.
output Код: 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. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109.
похоже на жука немного короче Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Забыл уточнить, что тест (выше) требует Код: plsql 1.
Без этого тест кейс мог быть такой Код: 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.
Посмотрю поглубже на днях и заведу багу, если это баг. Пока выглядит как баг. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 04:31 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Sayan Malakshinov По поводу "умного" case: можно уточнить, что тип берется из первого не-нуллового expression Это эмпирика не отраженная в доке посему IMHO либо баг в CASE либо баг в доке. И во избежание сюрпризов в следующих версиях я бы использовал CAST/TO_DATE/TO_NUMBER... т.е. никаких неявностей. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 14:13 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SYЭто эмпирика не отраженная в доке А не предписывается ли это ANSI стандартом?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 14:22 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SY Это эмпирика не отраженная в доке посему IMHO либо баг в CASE либо баг в доке. Код: plsql 1. 2. 3. 4. 5. 6.
Код: plsql 1. 2. 3. 4. 5. 6.
SY я бы использовал CAST/TO_DATE/TO_NUMBER... т.е. никаких неявностей. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 16:25 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SY А поскольку NULL datatype есть VARCHAR2 ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 18:54 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
SY Пример показывающий тип NULL SY эмпирика не отраженная в доке SY Кстати у VARCHAR2 нет длины - похоже еще один баг :). Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 19:02 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
Sayan Malakshinov то, что при `create view as select null x from dual` x определен как varchar2(0) не значит, что NULL имеет тип Null- значения в оракеле вполне себе типизованные. Неопределенность возникает лишь при выводе типа из null- литерала . Поскольку логически эта проблема неразрешима без разделения самих null-литералов на типы - в качестве default выбран относительно универсальный тип varchar2. Это надо просто помнить :) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.01.2022, 19:02 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
andrey_anonymous Null- значения в оракеле вполне себе типизованные. andrey_anonymous Неопределенность возникает лишь при выводе типа из null- литерала . andrey_anonymous Поскольку логически эта проблема неразрешима без разделения самих null-литералов на типы - в качестве default выбран относительно универсальный тип varchar2. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.01.2022, 20:06 |
|
Нарушение UNIQUE-индекса при decode() и соблюдение при CASE в описании индекса
|
|||
---|---|---|---|
#18+
andrey_anonymous Это надо просто помнить :) Нет в Oracle NULL литералов. Есть NULL expressions: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.01.2022, 20:18 |
|
|
start [/forum/topic.php?fid=52&msg=40125004&tid=1879617]: |
0ms |
get settings: |
17ms |
get forum list: |
5ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
49ms |
get topic data: |
3ms |
get forum data: |
1ms |
get page messages: |
422ms |
get tp. blocked users: |
0ms |
others: | 359ms |
total: | 858ms |
0 / 0 |