Как я могу имитировать переменные, циклы и объединения для совместной работы в SQLite? - PullRequest
0 голосов
/ 24 марта 2020

Я застрял с ограничениями как SQLite, так и дизайна некоторых его таблиц. Вот чего я хотел бы достичь:

  1. Создать переменную для отслеживания количества итераций al oop. Затем используйте эту переменную, чтобы помочь создать уникальные строки таблицы во время l oop. Также вставьте его как значение счетчика букв в записи.
  2. Объедините указанную переменную с существующими строками, чтобы создать уникальные идентификаторы, на которые можно ссылаться несколько раз.
  3. L oop код с использованием предыдущей переменной для отслеживания итераций и предыдущих объединений в качестве идентификаторов для вставки новых строк для каждого l oop. 255 циклов - это произвольное число, я сомневаюсь, что мне понадобится 255 циклов в 99,9% случаев, но я хочу избежать ошибок в тех случаях, когда они необходимы. Я реально смотрю на минимум 50 петель, с 100 как редкий максимум. 200, вероятно, будет ближе к истинному максимальному числу выбросов. 255 просто для безопасности.

Вот что я пытался сделать до сих пор:

DECLARE @cnt INT = 1;

WHILE @cnt < 256
BEGIN
    @seyield = 'BUILDING_STOCK_EXCHANGE_YIELD_' + @cnt;
    @secitizens = 'BUILDING_STOCK_EXCHANGE_CITIZENS_' + @cnt;
    @secount = 'COUNT_CITIZENS_' + @cnt;

    INSERT INTO
        BuildingModifiers (BuildingType, ModifierId)
    VALUES
        ('BUILDING_STOCK_EXCHANGE', @seyield);

    INSERT INTO
        Modifiers (ModifierId, ModifierType, RunOnce, Permanent, SubjectRequirementSetId)
    VALUES
        (@seyield, 'MODIFIER_BUILDING_YIELD_CHANGE', 0, 0, @secitizens);

    INSERT INTO
        ModifierArguments (ModifierID, Name, Value)
    VALUES
        (@seyield, 'BuildingType', 'BUILDING_STOCK_EXCHANGE'),
        (@seyield, 'Amount', '2'),
        (@seyield, 'YieldType', 'YIELD_GOLD');

    INSERT INTO
        RequirementSets(RequirementSetId, RequirementSetType)
    VALUES
        (@secitizens, 'REQUIREMENT_TEST_ALL');

    INSERT INTO
        RequirementSetRequirements(RequirementSetId, RequirementId)
    VALUES
        (@secitizens, @secount);

    INSERT INTO
        Requirements(RequirementId, RequirementType)
    VALUES
        (@secount, 'REQUIREMENT_COLLECTION_ATLEAST');

    INSERT INTO
        RequirementArguments(RequirementId, Name, Value)
    VALUES
        (@secount, 'CollectionType', 'COLLECTION_CITY_PLOT_YIELDS'),
        (@secount, 'Count', @cnt);

   SET @cnt = @cnt + 1;
END;

Конечно, это не работает из-за ограничений SQLite.

Существуют ли какие-либо допустимые обходные пути для этого?

Мне известен один из них, но он практически невозможен: не указывайте переменную l oop, переменную и конкатенации, а также вручную скопируйте и вставьте этот код blo c, вручную меняя соответствующие поля каждый раз. Однако для этого потребуется 255 копий и вставок, умноженных примерно на 8 или 9 раз для каждого отдельного BUILDING_TYPE, к которому мне нужно присоединить строки. Я бы предпочел не делать этого, если есть более быстрый и эффективный способ!

1 Ответ

1 голос
/ 24 марта 2020

Вы можете сделать это с помощью рекурсивного CTE и использования временной таблицы:

drop table if exists temp.temptable;
create temporary table temptable(cnt int, seyield text, secitizens text, secount text);

with
  recursive constants as (
    select 
      'BUILDING_STOCK_EXCHANGE_YIELD_' seyield,
      'BUILDING_STOCK_EXCHANGE_CITIZENS_' secitizens,
      'COUNT_CITIZENS_' secount  
  ),
  numbers as (
    select 1 cnt
    from constants
    union all
    select cnt + 1 from numbers
    where cnt < 255
  ),
  cte as (
    select
      n.cnt cnt,
      c.seyield || n.cnt seyield,
      c.secitizens || n.cnt secitizens,
      c.secount || n.cnt secount 
    from numbers n cross join constants c
  )  

insert into temptable
select * from cte;

INSERT INTO BuildingModifiers (BuildingType, ModifierId)
SELECT 'BUILDING_STOCK_EXCHANGE', seyield FROM temptable;

INSERT INTO Modifiers (ModifierId, ModifierType, RunOnce, Permanent, SubjectRequirementSetId)
SELECT seyield, 'MODIFIER_BUILDING_YIELD_CHANGE', 0, 0, secitizens FROM temptable;

INSERT INTO ModifierArguments (ModifierID, Name, Value)
SELECT seyield, 'BuildingType', 'BUILDING_STOCK_EXCHANGE' FROM temptable
UNION ALL
SELECT seyield, 'Amount', '2' FROM temptable
UNION ALL
SELECT seyield, 'YieldType', 'YIELD_GOLD' FROM temptable;

INSERT INTO RequirementSets(RequirementSetId, RequirementSetType)
SELECT secitizens, 'REQUIREMENT_TEST_ALL' FROM temptable;

INSERT INTO RequirementSetRequirements(RequirementSetId, RequirementId)
SELECT secitizens, secount FROM temptable;

INSERT INTO Requirements(RequirementId, RequirementType)
SELECT secount, 'REQUIREMENT_COLLECTION_ATLEAST' FROM temptable;

INSERT INTO RequirementArguments(RequirementId, Name, Value)
SELECT secount, 'CollectionType', 'COLLECTION_CITY_PLOT_YIELDS' FROM temptable
UNION ALL
SELECT secount, 'Count', cnt FROM temptable;

См. Демоверсию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...