sqlite - 如何模拟变量、循环和串联以在 SQLite 中协同工作?
问题描述
我被 SQLite 的局限性和它的一些表的设计所困。这是我想要实现的目标:
- 创建一个变量来跟踪循环的迭代次数。然后使用此变量在循环期间帮助创建唯一的表行。还将其作为文字计数值插入记录中。
- 将所述变量连接到现有字符串以创建可以多次引用的唯一 ID。
- 循环代码使用先前的变量来跟踪迭代,并将先前的串联作为 ID,用于为每个循环插入新行。255 个循环是一个任意数字,我怀疑在 99.9% 的情况下我需要 255 个循环,但希望在需要它们的情况下避免失败。我实际上正在查看最少 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 的限制,这不起作用。
是否有任何有效的解决方法?
我知道一个,但几乎不可行:省略循环、变量和连接,并手动复制和粘贴此代码块,每次手动更改相关字段。但是,对于我需要附加行的每个不同的 BUILDING_TYPE,这将需要 255 次复制和粘贴乘以大约 8 或 9 倍。如果有更快更有效的方法,我宁愿不这样做!
解决方案
您可以通过递归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;
请参阅演示。
推荐阅读
- reactjs - 来自 API 的 ReactJS 数据
- c - 在 C 中,如何从 UNIX 中的二进制文件中删除数据(结构)?
- r - 计算R中数据框中组内的比例
- azure - 缺少“交换操作系统磁盘”选项
- angular - 如何使用 Angular 前端、Spring REST 后端和 CAS (web.xml) 获取 UserPrincipal?
- python - 如何在下一个正则表达式模式匹配之前获取整个字符串?
- c# - 在 WinForm C# 应用程序上播放 WebRTC 流
- r - 删除默认 ggplot 图例并创建自定义图例
- angular - PolarArea 图表的 Apexchart 最大 y 轴值
- java - 需要帮助来使用数组对象显示数组的所有数据(不能使用数组列表)