База данных Versioning SQL Server

Как отметил @FelixKling, наиболее вероятным сценарием является то, что узлы, которые вы ищете, еще не существуют.

Однако современные методы разработки часто могут манипулировать элементами документа за пределами дерева документов либо с DocumentFragments, либо просто отсоединением / повторным подключением текущих элементов напрямую. Такие методы могут использоваться как часть шаблонов JavaScript или для предотвращения чрезмерных операций перерисовки / переплавки, в то время как элементы, о которых идет речь, сильно изменяются.

Аналогично, новая функциональность «Теневой DOM» развертывается в современных браузерах позволяет элементам быть частью документа, но не обрабатываться запросом document.getElementById и всеми его методами sibling (querySelector и т. д.). Это делается для инкапсуляции функциональных возможностей и, в частности, скрыть его.

Опять же, скорее всего, элемент, который вы ищете, просто (пока) в документе, и вы должны сделать, как предлагает Феликс , Тем не менее, вы также должны знать, что это все чаще является не единственной причиной того, что элемент может быть необоснованным (временно или постоянно).

306
задан Brock Adams 31 May 2019 в 08:19
поделиться

23 ответа

Martin Fowler написал мою любимую статью о предмете, http://martinfowler.com/articles/evodb.html . Я принимаю решение не вставить дампы схемы при управлении версиями как , alumb и другие предлагают, потому что я хочу простой способ обновить мою производственную базу данных.

Для веб-приложения, где у меня будет единственный производственный экземпляр базы данных, я использую два метода:

Сценарии Обновления Базы данных

А упорядочивают сценарии обновления базы данных, которые содержат DDL, необходимый для перемещения схемы от версии N до N+1. (Они входят в Вашу систему управления версиями.) _version_history_ таблица, что-то как [1 111]

create table VersionHistory (
    Version int primary key,
    UpgradeStart datetime not null,
    UpgradeEnd datetime
    );

получает новую запись каждый раз, когда сценарий обновления работает, который соответствует новой версии.

Это гарантирует, что легко видеть, какая версия схемы базы данных существует и что сценарии обновления базы данных выполняются только однажды. Снова, это не дампы базы данных. Скорее каждый сценарий представляет изменения необходимый для перемещения от одной версии до следующего. Они - сценарий, что Вы обращаетесь к своей производственной базе данных для "обновления" его.

Синхронизация Песочницы Разработчика

  1. сценарий А для резервного копирования санируйте и уменьшите производственную базу данных. Выполните это после каждого обновления производственного DB.
  2. сценарий А для восстановления (и тонкая настройка, при необходимости) резервного копирования на рабочей станции разработчика. Каждый разработчик выполняет этот сценарий после каждого обновления производственного DB.

протест А: Мой автоматизированный тестовый прогон против корректной схемой, но пустой базы данных, таким образом, этот совет отлично не удовлетворит Вашим потребностям.

174
ответ дан ESV 23 November 2019 в 01:19
поделиться

Только что я нашел VB bas модулем, который использовал DMO, и VSS возражает для написания сценарий всего дб прочь и в VSS. Я превратил его в Сценарий VB и отправил его здесь . Вы могли легко вынуть вызовы VSS и использовать материал DMO, чтобы генерировать все сценарии, и затем назвать SVN от того же пакетного файла, который называет VBScript для регистрации их?

Dave J

5
ответ дан Dave Jackson 23 November 2019 в 01:19
поделиться

Мы только что начали использовать Сервер Основы Команды. Если Ваша база данных среднего размера, то Visual Studio имеет некоторую хорошую интеграцию проекта со встроенным, выдерживают сравнение, данные выдерживают сравнение, инструменты рефакторинга базы данных, среда тестирования базы данных, и даже инструменты поколения данных.

, Но, та модель не соответствует очень большим или сторонним базам данных (которые шифруют объекты), очень хорошо. Так, что мы сделали, должен хранить только наши специализированные объекты. Visual Studio / сервер основы Команды работает очень хорошо на это.

руководитель Базы данных TFS дуга. блог

MS сайт TFS

6
ответ дан TheEmirOfGroofunkistan 23 November 2019 в 01:19
поделиться

Стандартное решение должно вывести базу данных по мере необходимости и скопировать те файлы.

В зависимости от Вашей платформы разработки, могут быть доступные плагины с открытым исходным кодом. Прокрутка Вашего собственного кода, чтобы сделать это обычно довольно тривиальна.

Примечание: можно хотеть скопировать дамп базы данных вместо того, чтобы поместить его в управление версиями. Файлы могут стать огромными быстро в управлении версиями и заставить Вашу всю систему управления исходным кодом становиться медленной (я вспоминаю страшную историю CVS в данный момент).

6
ответ дан engtech 23 November 2019 в 01:19
поделиться

У нас была потребность присвоить версию нашей базе данных SQL после того, как мы мигрировали на x64 платформу, и наша старая версия порвала с миграцией. Мы записали приложение C#, которое использовало SQLDMO для планирования всех объектов SQL к папке:

                Root
                    ServerName
                       DatabaseName
                          Schema Objects
                             Database Triggers*
                                .ddltrigger.sql
                             Functions
                                ..function.sql
                             Security
                                Roles
                                   Application Roles
                                      .approle.sql
                                   Database Roles
                                      .role.sql
                                Schemas*
                                   .schema.sql
                                Users
                                   .user.sql
                             Storage
                                Full Text Catalogs*
                                   .fulltext.sql
                             Stored Procedures
                                ..proc.sql
                             Synonyms*
                                .synonym.sql
                             Tables
                                ..table.sql
                                Constraints
                                   ...chkconst.sql
                                   ...defconst.sql
                                Indexes
                                   ...index.sql
                                Keys
                                   ...fkey.sql
                                   ...pkey.sql
                                   ...ukey.sql
                                Triggers
                                   ...trigger.sql
                             Types
                                User-defined Data Types
                                   ..uddt.sql
                                XML Schema Collections*
                                   ..xmlschema.sql
                             Views
                                ..view.sql
                                Indexes
                                   ...index.sql
                                Triggers
                                   ...trigger.sql

приложение тогда сравнило бы недавно записанную версию с версией, сохраненной в SVN и если бы были различия, это обновило бы SVN. Мы решили, что, выполняя процесс, как только ночь была достаточна, так как мы не делаем это многими изменениями в SQL. Это позволяет нам отслеживать изменения во всех объектах, о которых мы заботимся плюс он, позволяет нам восстанавливать нашу полную схему в случае серьезной проблемы.

7
ответ дан Christopher Klein 23 November 2019 в 01:19
поделиться

Мы не храним схему базы данных, мы храним изменения в базе данных. То, что мы делаем, сохранить изменения схемы так, чтобы мы создали сценарий изменения для любой версии базы данных и применили его к базам данных нашего клиента. Я записал приложение утилиты базы данных, которое распределяется с нашим главным приложением, которое может прочитать тот сценарий и знать, какие обновления должны быть применены. Это также имеет достаточно ума для обновления представлений и хранимых процедур по мере необходимости.

7
ответ дан Chris Miller 23 November 2019 в 01:19
поделиться

Сделать дамп к системе управления исходным кодом, что немного быстрее, Вы видите, какие объекты изменились с прошлого раза при помощи информации о версии в sysobjects.

Установка: Составляют таблицу в каждой базе данных, которую Вы хотите проверить инкрементно для содержания информации о версии с прошлого раза, когда Вы проверили его (пустой на первом показе). Очистите эту таблицу, если Вы хотите повторно просканировать свою целую структуру данных.

IF ISNULL(OBJECT_ID('last_run_sysversions'), 0) <> 0 DROP TABLE last_run_sysversions
CREATE TABLE last_run_sysversions (
    name varchar(128), 
    id int, base_schema_ver int,
    schema_ver int,
    type char(2)
)

Нормальный рабочий режим: можно взять результаты этого sql и генерировать sql сценарии для просто тех, Вы интересуетесь и помещаете их в управление исходным кодом по Вашему выбору.

IF ISNULL(OBJECT_ID('tempdb.dbo.#tmp'), 0) <> 0 DROP TABLE #tmp
CREATE TABLE #tmp (
    name varchar(128), 
    id int, base_schema_ver int,
    schema_ver int,
    type char(2)
)

SET NOCOUNT ON

-- Insert the values from the end of the last run into #tmp
INSERT #tmp (name, id, base_schema_ver, schema_ver, type) 
SELECT name, id, base_schema_ver, schema_ver, type FROM last_run_sysversions

DELETE last_run_sysversions
INSERT last_run_sysversions (name, id, base_schema_ver, schema_ver, type)
SELECT name, id, base_schema_ver, schema_ver, type FROM sysobjects

-- This next bit lists all differences to scripts.
SET NOCOUNT OFF

--Renamed.
SELECT 'renamed' AS ChangeType, t.name, o.name AS extra_info, 1 AS Priority
FROM sysobjects o INNER JOIN #tmp t ON o.id = t.id
WHERE o.name <> t.name /*COLLATE*/
AND o.type IN ('TR', 'P' ,'U' ,'V')
UNION 

--Changed (using alter)
SELECT 'changed' AS ChangeType, o.name /*COLLATE*/, 
       'altered' AS extra_info, 2 AS Priority
FROM sysobjects o INNER JOIN #tmp t ON o.id = t.id 
WHERE (
   o.base_schema_ver <> t.base_schema_ver
OR o.schema_ver      <> t.schema_ver
)
AND  o.type IN ('TR', 'P' ,'U' ,'V')
AND  o.name NOT IN ( SELECT oi.name 
         FROM sysobjects oi INNER JOIN #tmp ti ON oi.id = ti.id
         WHERE oi.name <> ti.name /*COLLATE*/
         AND oi.type IN ('TR', 'P' ,'U' ,'V')) 
UNION

--Changed (actually dropped and recreated [but not renamed])
SELECT 'changed' AS ChangeType, t.name, 'dropped' AS extra_info, 2 AS Priority
FROM #tmp t
WHERE    t.name IN ( SELECT ti.name /*COLLATE*/ FROM #tmp ti
         WHERE NOT EXISTS (SELECT * FROM sysobjects oi
                           WHERE oi.id = ti.id))
AND  t.name IN ( SELECT oi.name /*COLLATE*/ FROM sysobjects oi
         WHERE NOT EXISTS (SELECT * FROM #tmp ti
                           WHERE oi.id = ti.id)
         AND   oi.type  IN ('TR', 'P' ,'U' ,'V'))
UNION

--Deleted
SELECT 'deleted' AS ChangeType, t.name, '' AS extra_info, 0 AS Priority
FROM #tmp t
WHERE NOT EXISTS (SELECT * FROM sysobjects o
                  WHERE o.id = t.id)
AND t.name NOT IN (  SELECT oi.name /*COLLATE*/ FROM sysobjects oi
         WHERE NOT EXISTS (SELECT * FROM #tmp ti
                           WHERE oi.id = ti.id)
         AND   oi.type  IN ('TR', 'P' ,'U' ,'V'))
UNION

--Added
SELECT 'added' AS ChangeType, o.name /*COLLATE*/, '' AS extra_info, 4 AS Priority
FROM sysobjects o
WHERE NOT EXISTS (SELECT * FROM #tmp t
                  WHERE o.id = t.id)
AND      o.type  IN ('TR', 'P' ,'U' ,'V')
AND  o.name NOT IN ( SELECT ti.name /*COLLATE*/ FROM #tmp ti
         WHERE NOT EXISTS (SELECT * FROM sysobjects oi
                           WHERE oi.id = ti.id))
ORDER BY Priority ASC

Примечание: при использовании нестандартного сопоставления в какой-либо из баз данных необходимо будет заменить /* COLLATE */ сопоставлением базы данных. т.е. COLLATE Latin1_General_CI_AI

8
ответ дан Jonathan 23 November 2019 в 01:19
поделиться

Поскольку наше приложение должно работать через несколько RDBMSs, мы храним наше определение схемы в управлении версиями с помощью нейтрального в отношении базы данных Крутящий момент формат (XML). Мы также управление версиями, которое справочные данные для нашей базы данных в XML форматируют следующим образом (где "Отношения" являются одной из таблиц ссылок):

  <Relationship RelationshipID="1" InternalName="Manager"/>
  <Relationship RelationshipID="2" InternalName="Delegate"/>
  etc.

Мы тогда используем инструменты собственной разработки для генерации обновления схемы и сценариев обновления справочных данных, которые требуются, чтобы идти от версии X базы данных к версии X + 1.

8
ответ дан Andrew Swan 23 November 2019 в 01:19
поделиться

SQL Красного Логического элемента Выдерживает сравнение, продукт не только позволяет Вам делать сравнения уровня объектов и генерировать сценарии изменения от этого, но это также позволяет Вам экспортировать свои объекты базы данных в иерархию папок, организованную типом объекта с одним [имя объекта] .sql сценарий создания на объект в этих каталогах. Иерархия типа объекта похожа на это:

процедуры \Functions
\Security
\Security\Roles
\Security\Schemas
\Security\Users
\Stored
\Tables

при дампе сценариев к тому же корневому каталогу после внесения изменений можно использовать это, чтобы обновить SVN repo и сохранить под управлением историю каждого объекта индивидуально.

45
ответ дан Montag451 23 November 2019 в 01:19
поделиться

Это - одна из "тяжелых проблем" окружающая разработка. Насколько я знаю, что нет никаких идеальных решений.

, Если только необходимо сохранить структуру базы данных а не данные, можно экспортировать базу данных как SQL-запросы. (в Руководителе предприятия: Щелкните правой кнопкой по базе данных->, Генерируют сценарий SQL. Я рекомендую установить, "создают один файл на объект" на вкладке опций), можно тогда фиксировать эти текстовые файлы svn и использовать разность svn и регистрирующиеся функции.

мне связали это вместе со Сценарием пакетной обработки, который берет пару параметров и настраивает базу данных. Я также добавил некоторые дополнительные запросы, которые вводят данные по умолчанию как пользовательские типы и администраторский пользователь. (Если Вы хотите больше информации об этом, отправляете что-то, и я могу поместить сценарий, где-нибудь доступный)

, Если необходимо сохранить все данные также, я рекомендую продолжить заднюю часть базы данных и использовать Redgate ( http://www.red-gate.com/ ) продукты, чтобы сделать сравнения. Они не обходятся дешево, но они стоят каждого пенса.

39
ответ дан alumb 23 November 2019 в 01:19
поделиться

Вы могли бы хотеть посмотреть на Liquibase ( http://www.liquibase.org/ ). Даже если Вы не используете сам инструмент, он обрабатывает понятие управления изменениями базы данных или осуществляющий рефакторинг вполне прилично.

21
ответ дан jeffjakub 23 November 2019 в 01:19
поделиться

Если у Вас есть маленькая база данных, и Вы хотите присвоить версию всей вещи, , этот сценарий пакетной обработки мог бы помочь. Это отсоединяет, сжимает и проверяет базу данных MSSQL файл MDF в к Подрывной деятельности.

, Если Вы главным образом хотите присвоить версию своей схеме и просто иметь небольшое количество справочных данных, можно возможно использовать Миграции SubSonic для обработки этого. Преимущество там - то, что можно легко мигрировать или вниз к любой определенной версии.

8
ответ дан Jon Galloway 23 November 2019 в 01:19
поделиться

+1 для всех, кто рекомендовал инструменты RedGate с дополнительной рекомендацией и протестом.

SqlCompare также имеет прилично зарегистрированный API: таким образом, можно, например, записать консольное приложение, которое синхронизирует управляемую папку сценариев источника с базой данных интеграционного тестирования CI по регистрации, так, чтобы, когда кто-то регистрируется в изменении в схеме от их папки сценариев, это было автоматически развернуто наряду с изменением кода приложения соответствия. Это помогает преодолеть разрыв с разработчиками, которые забывчивы о распространении изменений в их локальном дб до общего DB разработки (приблизительно половина из нас, я думаю:)).

протест А состоит в том, что с решением в виде сценария или иначе, инструменты RedGate являются достаточно гладкими, который легко забыть о фактах SQL, лежащих в основе абстракции. При переименовании всех столбцов в таблице SqlCompare не имеет никакого способа отобразить старые столбцы на новые столбцы и отбросит все данные в таблице. Это генерирует предупреждения, но я видел, что люди нажимают мимо этого. Существует общая точка, которую здесь стоит сделать, я думаю, что можно только автоматизировать управление версиями DB и обновить до сих пор - абстракции являются очень текучими.

18
ответ дан alexis.kennedy 23 November 2019 в 01:19
поделиться

Это - хороший подход для сохранения сценариев базы данных в управление версиями со сценариями изменения так, чтобы можно было обновить любую базу данных, которую Вы имеете. Также Вы могли бы хотеть сохранить схемы для различных версий так, чтобы можно было создать полную базу данных, не имея необходимость применять все сценарии изменения. Обработка сценариев должна быть автоматизирована так, чтобы Вы не делали физического труда.

я думаю, что ее важное имеет отдельную базу данных для каждого разработчика и не использует общую базу данных. Тем путем разработчики могут создать тестовые сценарии и этапы разработки независимо от других разработчиков.

инструмент автоматизации должен иметь средства для обработки метаданных базы данных, которые говорят, какие базы данных находятся в том, какое состояние разработки и какие таблицы содержат версию управляемые данные и так далее.

13
ответ дан Silvercode 23 November 2019 в 01:19
поделиться

Вы могли также посмотреть на решение для миграций. Они позволяют Вам определять свою схему базы данных в коде C# и прокручивать Вашу версию базы данных вверх и вниз по использованию MSBuild.

я в настоящее время использую DbUp, и он работал хорошо.

12
ответ дан Lance Fisher 23 November 2019 в 01:19
поделиться

Вы не упоминали специфических особенностей о своей целевой среде или ограничениях, таким образом, это не может быть совершенно применимо..., но если Вы ищете способ эффективно отследить развивающуюся схему DB и не являетесь неблагоприятными идее использовать Ruby, миграции ActiveRecord являются правильными Ваш переулок.

Миграции программно определяют преобразования базы данных с помощью DSL Ruby; каждое преобразование может быть применено или (обычно) откатываться, позволяя Вам перейти к различной версии Вашей схемы DB в любом данном моменте времени. Файл, определяющий эти преобразования, может быть проверен в управление версиями как любая другая часть исходного кода.

, поскольку миграции являются частью ActiveRecord, они обычно находят использование в приложениях для направляющих полного стека; однако, можно использовать ActiveRecord, независимый от направляющих с минимальным усилием. См. здесь для более подробной обработки использования миграций AR за пределами направляющих.

11
ответ дан Matt 23 November 2019 в 01:19
поделиться

Мы используем DBGhost для управления нашей базой данных SQL. Тогда Вы помещаете свои сценарии для создания новой базы данных в управлении версиями, и оно или создаст новую базу данных или обновит любую существующую базу данных до схемы в управлении версиями. Тем путем Вы не должны волноваться о создании сценариев изменения (хотя можно все еще сделать это, если, например, Вы хотите изменить тип данных столбца и должны преобразовать данные).

15
ответ дан Ray 23 November 2019 в 01:19
поделиться

Я также использую версию в базе данных, которая хранится через семейство процедур расширенных свойств базы данных. В моем приложении есть сценарии для каждого шага версии (т. Е. Перехода с 1.1 на 1.2). При развертывании он просматривает текущую версию, а затем запускает сценарии один за другим, пока не достигнет последней версии приложения. Не существует сценария с прямой «финальной» версией, даже при развертывании на чистой БД развертывание выполняется с помощью ряда этапов обновления.

Теперь я хотел бы добавить, что два дня назад я видел презентацию о кампус MS о новой и предстоящей редакции VS DB. Презентация была посвящена именно этой теме, и я был просто поражен. Вам обязательно стоит это проверить, новые возможности ориентированы на сохранение определения схемы в сценариях T-SQL (CREATE), механизм дельты времени выполнения для сравнения схемы развертывания с определенной схемой и выполнения дельта ALTER и интеграции с интеграцией исходного кода, вплоть до непрерывной интеграции MSBUILD для автоматического удаления сборки. Перетаскивание будет содержать новый тип файла, файлы .dbschema, которые можно перенести на сайт развертывания, а инструмент командной строки может выполнить фактические «дельты» и запустить развертывание. У меня есть запись в блоге по этой теме со ссылками на загрузки VSDE, вы должны проверить их: http://rusanu.com/2009/05/15/version-control-and-your-database/

5
ответ дан 23 November 2019 в 01:19
поделиться

Это просто.

  1. Когда базовый проект готов, вы должны создать полный сценарий базы данных. Этот скрипт привязан к SVN. Это первая версия.

  2. После этого все разработчики создают сценарии изменений (ALTER ..., новые таблицы, sprocs и т. Д.).

  3. Когда вам нужна текущая версия, вы должны выполнить все новые сценарии изменений.

  4. Когда После того, как приложение будет выпущено в производство, вы вернетесь к 1 (но, конечно, это будет следующая версия).

Nant поможет вам выполнить эти сценарии изменения. :)

И помните. Все отлично работает, когда есть дисциплина. Каждый раз, когда происходит изменение базы данных, также выполняются соответствующие функции в коде.

9
ответ дан 23 November 2019 в 01:19
поделиться

Каждая база данных должна находиться под контролем исходного кода. Чего не хватает, так это инструмента для автоматического создания сценария всех объектов базы данных - и «данных конфигурации» - в файле, который затем может быть добавлен в любую систему управления версиями. Если вы используете SQL Server, то мое решение здесь: http://dbsourcetools.codeplex.com/ . Радоваться, веселиться. - Натан.

10
ответ дан 23 November 2019 в 01:19
поделиться

По моему опыту, решение двоякое:

  1. Вам необходимо обрабатывать изменения в базе данных разработки, которые вносятся несколькими разработчиками во время разработки.

  2. Вам необходимо обрабатывать обновления базы данных у клиентов сайты.

Чтобы справиться с №1, вам понадобится надежный инструмент сравнения / слияния базы данных. Лучший инструмент должен уметь выполнять автоматическое слияние в максимально возможной степени, позволяя разрешать необработанные конфликты вручную.

Идеальный инструмент должен обрабатывать операции слияния с использованием трехстороннего алгоритма слияния, который учитывает изменения, внесенные в базу данных THEIRS и базу данных MINE по сравнению с базой данных BASE.

Я написал коммерческий инструмент который обеспечивает поддержку ручного слияния для баз данных SQLite, и в настоящее время я добавляю поддержку трехстороннего алгоритма слияния для SQLite. Проверьте это на http://www.sqlitecompare.com

Чтобы справиться с №2, вам понадобится инфраструктура обновления.

Основная идея состоит в том, чтобы разработать структуру автоматического обновления, которая знает, как выполнить обновление с существующей схемы SQL до новой схемы SQL, и может построить путь обновления для каждой существующей установки БД.

Прочтите мою статью на эту тему в http://www.codeproject.com/KB/database/sqlite_upgrade.aspx , чтобы получить общее представление о том, о чем я говорю.

Удачи

Лирон Леви

Основная идея состоит в том, чтобы разработать структуру автоматического обновления, которая знает, как выполнить обновление с существующей схемы SQL до новой схемы SQL, и может построить путь обновления для каждой существующей установки БД.

Прочтите мою статью на эту тему в http://www.codeproject.com/KB/database/sqlite_upgrade.aspx , чтобы получить общее представление о том, о чем я говорю.

Удачи

Лирон Леви

Основная идея состоит в том, чтобы разработать структуру автоматического обновления, которая знает, как выполнить обновление с существующей схемы SQL на новую схему SQL, и может построить путь обновления для каждой существующей установки БД.

Прочтите мою статью на эту тему в http://www.codeproject.com/KB/database/sqlite_upgrade.aspx , чтобы получить общее представление о том, о чем я говорю.

Удачи

Лирон Леви

3
ответ дан 23 November 2019 в 01:19
поделиться

Проверьте DBGhost http://www.innovartis.co.uk/ . Я использую в автоматическом режиме уже 2 года, и он отлично работает. Это позволяет нашей сборке БД происходить так же, как сборка Java или C, за исключением базы данных. Вы понимаете, о чем я.

3
ответ дан 23 November 2019 в 01:19
поделиться

Red Gate предлагает инструмент SQL Source Control , который использует технологию SQL Compare для связывания вашей базы данных с репозиторием TFS или SVN. Этот инструмент интегрируется в SSMS и позволяет вам работать как обычно, за исключением того, что теперь он позволяет фиксировать объекты.

Для подхода, основанного на миграции (более подходящего для автоматизированного развертывания), мы предлагаем SQL Change Automation (ранее называвшееся ReadyRoll), которое создает и управляет набором инкрементных скриптов в качестве проекта Visual Studio.

В SQL Source Control можно указывать статические таблицы данных. Они хранятся в системе управления версиями как операторы INSERT.

Если вы говорите о тестовых данных, мы рекомендуем вам либо сгенерировать тестовые данные с помощью инструмента, либо с помощью определенного вами сценария после развертывания, либо просто восстановить производственную резервную копию в среду разработки.

24
ответ дан 23 November 2019 в 01:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: