|
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 |
|
|
start [/forum/topic.php?fid=54&msg=40099667&tid=2008325]: |
0ms |
get settings: |
15ms |
get forum list: |
6ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
46ms |
get topic data: |
5ms |
get forum data: |
1ms |
get page messages: |
431ms |
get tp. blocked users: |
1ms |
others: | 6ms |
total: | 513ms |
0 / 0 |