|
Rename Column и View
|
|||
---|---|---|---|
#18+
Господа, никто не подскажет - можно ли временно заблокировать изменение представления при переименовании поля в таблице? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2021, 18:23 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Транзакцию начни и вообще все изменения заблокируются, максимум читать можно будет и то до определенного момента. Так блокировка в SQLite работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2021, 20:23 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, чтение тут абсолютно ни при чем. Мне нужен скрипт, который изменяет параметры поля (например, тип или длину). У SQLite нет конструкции Alter Table Modify, поэтому мне нужно переименовать старое поле, добавить новое, скопировать данные из старого в новое и затем старое удалить. Но в момент переименования старого поля оно переименовывается также и во вьюхе. Мне нужно как-то заблокировать изменение вьюхи. Транзакция тут совершенно не помогает. Некорректная операция все равно вызывает ошибку, независимо от того, в рамках транзакции оно происходит или нет ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2021, 21:38 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 01:59 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, спасибо, но, к сожалению, не то. Скрипт отрабатывает без ошибок, но представление меняется и после, естественно не работает ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 03:09 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
S_Gur Dima T, чтение тут абсолютно ни при чем. Мне нужен скрипт, который изменяет параметры поля (например, тип или длину). У SQLite нет конструкции Alter Table Modify, поэтому мне нужно переименовать старое поле, добавить новое, скопировать данные из старого в новое и затем старое удалить. Но в момент переименования старого поля оно переименовывается также и во вьюхе. Мне нужно как-то заблокировать изменение вьюхи. Транзакция тут совершенно не помогает. Некорректная операция все равно вызывает ошибку, независимо от того, в рамках транзакции оно происходит или нет Заблокировать изменение названия поля во вьюхе невозможно, т.к. нечего блокировать, в ней нет данных. Вьюха это запрос (select ...) который подставляется как подзапрос при выборке из нее. Синтаксический сахар. Например есть вьюха V1 Код: sql 1.
Если ты переименовал в MyTable поле F1 в F1_old и сделал Код: sql 1.
то тут не будет F1 т.к. в реале это разворачивается в такую конструкцию Код: sql 1.
Если тебе это мешает, значит в процессе переименования ты зачем-то обращаешься к представлению. Этого не надо делать. Обернув все изменения в общую транзакцию ты заставишь ждать остальных желающих обратиться к вью во время изменения таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 07:46 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, -- Отключаем использование внешних ключей PRAGMA foreign_keys = 0; -- Переименовываем имеющееся поле Alter Table `tbListVars` Rename Column `vcParentString` To `vcParentString_Old`; -- Добавляем поле Alter Table `tbListVars` Add `vcParentString` VarChar(1000) Default '…' Not Null; -- Копируем данные в новое поле Update `tbListVars` Set `vcParentString` = `vcParentString_Old`; -- Удаляем старое поле Alter Table `tbListVars` Drop Column `vcParentString_Old`; -- Включаем использование внешних ключей PRAGMA foreign_keys = 1; Вот мой скрипт. Где именно я тут обращаюсь к представлению? Изменение идет в конкретной таблице. Но в тот момент, когда я переименовываю поле в таблице, в представлении это поле тоже переименовывается. Вполне возможно, что вьюха вида "Select * From `tbListVars`" не пострадает. Но меня такие вьюхи не устраивают, в моих необходимые поля перечисляются конкретно ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 08:12 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, это до переименования поля в таблице ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 08:30 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, а это после ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 08:31 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
S_Gur Dima T, -- Отключаем использование внешних ключей PRAGMA foreign_keys = 0; -- Переименовываем имеющееся поле Alter Table `tbListVars` Rename Column `vcParentString` To `vcParentString_Old`; -- Добавляем поле Alter Table `tbListVars` Add `vcParentString` VarChar(1000) Default '…' Not Null; -- Копируем данные в новое поле Update `tbListVars` Set `vcParentString` = `vcParentString_Old`; -- Удаляем старое поле Alter Table `tbListVars` Drop Column `vcParentString_Old`; -- Включаем использование внешних ключей PRAGMA foreign_keys = 1; Вот мой скрипт. Где именно я тут обращаюсь к представлению? Изменение идет в конкретной таблице. Но в тот момент, когда я переименовываю поле в таблице, в представлении это поле тоже переименовывается. Вполне возможно, что вьюха вида "Select * From `tbListVars`" не пострадает. Но меня такие вьюхи не устраивают, в моих необходимые поля перечисляются конкретно Затестил, действительно меняет: Код: sql 1. 2. 3. 4. 5. 6. 7.
Результат Код: plaintext 1. 2. 3.
Тут только удалять вью и заново создавать ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 08:46 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, вот-вот. Причем сохранять скрипт вьюхи перед изменением таблицы, убивать ее, потом менять поле и только тогда создавать вьюху заново. Странно, что нет более простого способа. Жаль, конечно... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 08:54 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
S_Gur Dima T, вот-вот. Причем сохранять скрипт вьюхи перед изменением таблицы, убивать ее, потом менять поле и только тогда создавать вьюху заново. Странно, что нет более простого способа. Жаль, конечно... Есть подозрение что эта проблема не только с вьюхами, а также с индексами и триггерами. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 09:18 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, насчет триггеров не знаю, а с индексами проблем нет. Когда вьюхи на таблицу не существует, весь скрипт прекрасно выполняется. Индексы он обязан перестраивать при изменении таблицы ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 09:23 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Надо индекс удалять и создавать. Затестил: Код: sql 1. 2. 3. 4. 5.
Наличие индекса не дает удалить vcParentString_Old Код: sql 1.
Код: plaintext
Поэтому остаются оба поля с индексом по старому полю: Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 09:35 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Dima T, да, я, видимо, игрался с полями, по которым индексы не построены. В общем, сплошной гемор ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 09:39 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
но представление меняется и после, естественно не работает Да, попутал. Это только для имен таблиц работает, а не колонок (что собственно в названии и указано). Если вы хотите изменить тип на схожий, напр. VARCHAR(20) на CHAR(30), которые по факту хранятся просто как TEXT, или изменить ограничение, которое и так выполняется в таблице, то можно попробовать изменить это прямо в файле переписав DDL, в обход библиотеки SQLite. Формат файла не слишком сложный, недавно я его тут описал, и если длины DDL хватит, то даже ячейку переносить не придется. Это конечно так себе метод. Как вариант, попробовать спросить на форуме SQLite . Там то уж точно скажут возможно ли такое как то обойти или нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 14:28 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, что значит - для имен таблиц? Во многих инструкциях к таким операциям объясняют, что можно переименовать всю таблицу, создать новую с обновленной структурой, скопировать данные из старой в новую и убить старую. Вы имеете в виду, что при таком подходе не придется пересоздавать ни представления, ни индексы, ни триггеры? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 16:39 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
S_Gur little-brother, что значит - для имен таблиц? Во многих инструкциях к таким операциям объясняют, что можно переименовать всю таблицу, создать новую с обновленной структурой, скопировать данные из старой в новую и убить старую. Вы имеете в виду, что при таком подходе не придется пересоздавать ни представления, ни индексы, ни триггеры? В общем-то, я попробовал этот метод и вьюха осталась неповрежденной. Индексы, конечно, придется пересоздавать, но это уже легче... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 16:51 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
что значит - для имен таблиц То, что с колонками не прокатывает. Переименование колонки влечет её переименование во всех представлениях, индексах и триггерах. Для таблиц через указанную прагму такое поведение можно отменить. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 18:59 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, https://runebook.dev/ru/docs/sqlite/pragma#pragma_legacy_alter_table "PRAGMA legacy_alter_table; PRAGMA legacy_alter_table = логическое Эта прагма устанавливает или запрашивает значение флага legacy_alter_table. Когда этот флаг установлен, команда ALTER TABLE RENAME (для изменения имени таблицы) работает так же, как в SQLite 3.24.0 (2018-06-04) и ранее. Более конкретно, когда этот флаг установлен, команда ALTER TABLE RENAME перезаписывает только начальное вхождение имени таблицы в своем операторе CREATE TABLE и во всех связанных операторах CREATE INDEX и CREATE TRIGGER . Другие ссылки на таблицу без изменений, в том числе: Ссылки на таблицу в телах триггеров и представлений. Ссылки на таблицу в пределах ограничений CHECK в первоначальном заявлении CREATE TABLE. Ссылки на таблицу в разделах WHERE частичных индексов ." Триггера в блоке Create она все-таки ломает ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 19:24 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Да, пропустил, что на триггерах не отключается. Поэтому видимо с триггерами, да и с представлениями, проще дропнуть всё, переименовать как надо и создать заново. Это не индексы пересоздадутся быстро, но вот если что-то пойдет не так, то увы :( Помнится SQLite Administrator меня с этим радовал (тогда я был не в курсе, что там всего лишь эмуляция переименования). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 22:03 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, представления надо убивать, только если имя поля меняется. Иначе все прекрасно живет. А вот индексы надо дропать точно, потому как имена индексов - особенно автоматические, если создавать неименованный индекс - не привязаны к имени таблицы, соответственно вряд ли они изменятся от переименования таблицы. Отсюда вытекает два постулата: 1 - желательно делать именованные индексы; 2 - перед созданием индекса лучше всего делать Drop Index If Exists ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 22:19 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
имена индексов - особенно автоматические, если создавать неименованный индекс - не привязаны к имени таблицы Пример можно? В DDL для индекса что имя его самого, что имя таблицы обязательны. Как это индекс может быть не привязан к таблице? P.S. Вы свою задачу то решили? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2021, 23:36 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, извиняюсь, оказывается соврал. Неименованные индексы привязаны к имени таблицы и переименовываются при переименовании самой таблицы. Первичный ключ для таблицы `tbListVars` получает автоматом наименование sqlite_master_PK_tbListVars, при переименовании таблицы в `tbListVars_Old` он становится sqlite_master_PK_tbListVars_Old. Так что, все еще более упростилось (в том смысле, что убивать индексы не надо). Да, свою задачу я решил. Переименовываю нужную таблицу, создаю новую (для начала без индексов), переношу данные из старой в новую, удаляю старую (все старые индексы при этом убиваются сами) и снова создаю все индексы уже на новую таблицу. После pragma legacy_alter_table = 0; пробую прочитать данные из вьюхи - все работает (естественно, при условии, что у изменяемого поля не меняется наименование) Я говорил про имена индексов. В DDL для индекса что имя его самого, что имя таблицы обязательны, но можно написать: `iID` Integer Unsigned Default 0 Not Null Constraint `pkListVars_ID` Primary Key, `iParentID` Integer Unsigned Default 0 Not Null Constraint `fkListVars_ParentID` References `tbListVars`(`iID`) On Delete Cascade, а можно: `iID` Integer Unsigned Default 0 Not Null Primary Key, `iParentID` Integer Unsigned Default 0 Not Null References `tbListVars`(`iID`) On Delete Cascade, Во втором случае индексы получат наименование автоматически. Соответственно, можно при создании новой таблицы сразу создавать все индексы, предварительно убивая существующие. А можно сначала удалить старую таблицу, и только потом навесить индексы на новую. Видимо, в данном случае удобнее этот вариант ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2021, 07:11 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, экспериментальным путем выяснилось, что первичные и внешние ключи вообще плюют на задаваемое в конструкции Constraint имя и всегда именуются автоматически. Ошибки при этом не возникает, выражение Constraint [index_name] просто игнорируется ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2021, 11:06 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Ошибки при этом не возникает Возможно потому, что pragma foreign_keys --> 0. авторInteger Unsigned В Unsigned смысла нет. Более того при таком задании PK не будет использоваться как rowid (только при INTEGER PRIMARY KEY), что несколько медленнее. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 12:28 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother Ошибки при этом не возникает Возможно потому, что pragma foreign_keys --> 0. Прагма тут абсолютно ни при чем. Я использую эту прагму только при пересоздании таблицы и только в случае наличия в ней первичного или внешних ключей. В скрипте по созданию таблицы с нуля ее нет ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 13:08 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, я сейчас ищу информацию по Unsigned. C первичными ключами все понятно, но я никак не могу понять, стоит ли вообще использовать его в SQLite? Есть один официальный тип Unsigned Big Int, но действительно ли он Unsigned или это тоже эмуляция? Ничего конкретного пока найти не могу ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 16:33 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
У SQLite всего 5 типов: NULL, FLOAT (он же REAL), (signed) INTEGER (несколько штук: INT8, INT16, ...), TEXT и BLOB. Все остальные типы транслируются в эти. В скрипте по созданию таблицы с нуля ее нет По умолчанию значение этой прагмы 0, т.е. выполняя скрипт создания таблицы с настройками по умолчанию, SQLite не будет проверять внешние ключи. Возможно он не будет проверять и при включенной прагме, мне лень протестировать :) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 18:55 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, то есть, я могу с чистой совестью совсем избавиться от Unsigned в скриптах SQLite? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 19:08 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
Да. В SQLite эти типы скорее как подсказка, нежели как руководство к действию. Так в численное поле без проблем можно положить текст. Оно работает только при сохранении, напр. строка `111` может быть приведена к 111, а вот `111a` уже будет сохранено как текст в числовую колонку. В других базах вы получите ошибку. С версии 3.37 обещают специальный режим strict, когда значения обязаны следовать типу колонки. В любом случае, использование всяких VARCHAR, CHAR, UNSIGNED INT, NUMERIC - это просто для удобства, например при миграции с других баз. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 19:22 |
|
Rename Column и View
|
|||
---|---|---|---|
#18+
little-brother, вот образец моего скрипта для создания таблицы. Специально для чистоты эксперимента включил поддержку внешних ключей. Проверил на пустой базе. Ошибок нет. Разумеется, такой скрипт будет отрабатываться в пакете скриптов для создания базы с нуля. Для изменения существующих таблиц я в начале скрипта выключаю поддержку и включаю ее обратно в конце Код: sql 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2021, 19:23 |
|
|
start [/forum/topic.php?all=1&fid=54&tid=2008325]: |
0ms |
get settings: |
12ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
519ms |
get tp. blocked users: |
2ms |
others: | 406ms |
total: | 1016ms |
0 / 0 |