基于 https://stackoverflow.com/a/59666211/4250302,我创建了存储函数 get_enum_item
,以便将来处理 ENUM()
类型字段中的可能值列表。
它工作得很好,但是......但是如果分隔符本身是被拆分的字符串的一部分,我无法确定该怎么做。例如: (方括号是为了便于阅读)
mysql> set @q=",v1,',v2'" --empty string, "v1", "comma-v2";
mysql> select concat('[',get_enum_item(@q,',',0),']') as item;
+------+
| item |
+------+
| [] |
+------+
没问题
mysql> select concat('[',get_enum_item(@q,',',1),']') as item;
+------+
| item |
+------+
| [v1] |
+------+
还可以
mysql> select concat('[',get_enum_item(@q,',',2),']') as item;
+------+
| item |
+------+
| ['] |
+------+
不正常
@q
包含 3 个逗号,其中前两个是真正的分隔符,而最后一个是第三个可能值的部分:"comma-v-two"
。而且我不知道如何避免拆分功能的混淆。 “表单编辑器”模式下的 MySQL WorkBench 以某种方式解决了这个问题,但我如何用 MySQL 的代码解决这个问题?
嗯,我可以依赖这样一个事实,即 show_columns
之类的查询以“硬编码”方式显示枚举:
select column_name,column_type
from information_schema.columns
where data_type='enum' and table_name='assemblies';
+--------------+------------------------------------------------------------------+
| COLUMN_NAME | COLUMN_TYPE |
+--------------+------------------------------------------------------------------+
| AssetTagType | enum('','И/Н','Н/Н',',fgg') |
| PCTagType | enum('','И/Н','Н/Н') |
| MonTagType | enum('','И/Н','Н/Н') |
| UPSTagType | enum('','И/Н','Н/Н') |
| OtherTagType | enum('','И/Н','Н/Н') |
| state | enum('в работе','на списание','списано') |
+--------------+------------------------------------------------------------------+
因此我可以尝试使用 ','
作为分隔符,但是如果“逗号-撇号”组合是可能值的一部分,这不会使我免于这种情况...... :-(
我唯一能想象的是计算撇号,如果分隔逗号在偶数个 '
之后,那么它是分隔符,而如果它跟在奇数个 '
之后,它是值的一部分。
除了愚蠢地扫描循环内的输入字符串之外,我无法发明任何东西。但也许还有其他一些建议可以正确拆分值?
请不要建议使用 PHP、Python、AWK 等。查询将从 Pascal(Lazarus,CodeTyphoon)应用程序执行,调用外部处理器是非常不安全的。
作为最后的手段,我可以使用 Pascal 的代码处理 column_type
,但首先,我必须确保自己无法通过 MySQL 的功能解决该任务。
编辑:
select column_type from information_schema.columns
where column_name='assettagtype' and table_name='assemblies';
+------------------------------------------+
| COLUMN_TYPE |
+------------------------------------------+
| enum('','И/Н','Н/Н',''''',fgg','''') |
+------------------------------------------+
1 row in set (0.00 sec)
第四个字段:'',fgg
,第五个字段:'
答案 0 :(得分:1)
set @q="'в работе','на списание','списано'";
WITH RECURSIVE cte as (
select 1 as a union all
select a+1 from cte where a<35
)
select distinct regexp_substr(@q,'''[^,]*''',a) as E from cte;
35
的值过高会引发错误 ERROR 3686 (HY000): Index out of bounds in regular expression search.
。 (我为此创建了一个 bug)null
值...?输出:
E |
---|
'в работе' |
'на списание' |
'списано' |
空 |
编辑:通过一些努力,这也适用于更复杂的示例(不适用于每个“分阶段”示例!)
set @q="'в работе','на списание','списано',''',fgg'";
select @q;
WITH RECURSIVE cte as (
select 1 as a union all
select a+1 from cte where a<35
)
select distinct regexp_substr(@q,'(''([^,]|[^''][^''])*'')',a) E from cte;
输出:
E |
---|
'вработе' |
'на списание' |
'списано' |
''',fgg' |