【问题标题】:How can I translate ms-access NZ to IFNULL MySQL or MariaDB functions?如何将 ms-access NZ 转换为 IFNULL MySQL 或 MariaDB 函数?
【发布时间】:2020-08-08 11:05:07
【问题描述】:

我正在使用 sed 编写基于正则表达式的 SQL 查询“转换器”,从 ms-access 到 MySQL 或 MariaDB SQL。

我的问题是nz函数,它有两种形式:

     access          MariaDB or MySQL
nz(expr1,expr2) --> ifnull(expr1,expr2)
nz(expr)        --> ifnull(expr,0)

我对每种情况都有这两个陈述,但不是两个都只有一个:

sed -E 's/nz\((.*),(.*)\)/ifnull\(\1,\2\)/gi'
sed -E 's/nz\((.*)\)/ifnull\(\1,0\)/gi'

您知道如何将两者合并到一个 sed 语句中吗?或者可能使用其他工具,如 tr、awk 或 perl?

更新

对于这个输入:

SELECT nz(column1),nz(column2,4),column3 FROM table;

想要的输出是:

SELECT ifnull(column1,0),ifnull(column2,4),column3 FROM table;

【问题讨论】:

  • 即使第一个语句本身看起来也不正确。您可能认为的expr2 可能包含逗号,然后您的模式中的第一个(.*) 将延伸到expr2 中的最后一个逗号。您将错误识别expr1expr2。这可以修复(第一个子表达式应该是([^,]*),但我确信还有许多其他陷阱。例如,expr2 可能是(或包含)对nz 的另一个调用。您是否正在编写一个可以处理的解决方案有那种嵌套调用?
  • 不幸的是,我糟糕的解决方案无法处理这样的嵌套调用。它实际上包含一系列加入的 sed 调用。感谢您的评论。

标签: mysql regex sed mariadb


【解决方案1】:

一种选择是使用具有 2 个捕获组的模式,其中第二组是可选的。然后您可以使用 perl 使用 defined 进行条件替换。

模式

nz\(([^,()]+)(,[^,()]+)?\)

说明

  • nz\(匹配nz(
  • ( 捕获第 1 组
  • )关闭第一组
  • ( 捕获第 2 组
    • ,[^,()]+ 匹配, 并匹配除, 之外的任何字符1+ 次@ ( )
  • )? 关闭第 2 组并将其设为可选
  • \)匹配)

Regex demo | Perl demo

示例代码

my $str = "SELECT nz(1), nz(2,3), column FROM table;";
$str =~ s/nz\(([^,()]+)(,[^,()]+)?\)/defined($2) ? "ifnull(" . $1.$2 . ")":"ifnull(" . $1 . ", 0)"/ge;
print $str
  • s/// 用于替换
  • /e 是评估修饰符
  • /g 是全局修饰符

输出

SELECT ifnull(1, 0), ifnull(2,3), column FROM table;

【讨论】:

  • 这个小脚本是一个好的开始,但不是解决方案。它仅将 nz 的出现替换为 ifnull (在单独的行中),但我希望其余文本保持不变。所以对于输入:SELECT nz(1), nz(2,3), column FROM table; 输出必须是:SELECT ifnull(1,0), ifnull(2,3), column FROM table;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多