SQL 查询以替换扫描结果中的值并更新 Table 的字段

SQL Query to Substitute value in the scanned results and update that field of Table

我有一个一对多的组织:用户关系。 我想获取 Organization 的所有 User 模型的用户名,捕获该用户名的一部分并使用新值 append/substitute .

这是我的做法:

  1. 形成原始 SQL 以获取匹配的用户名并将其替换为新值。

raw = "SELECT REGEXP_REPLACE(::string[], '(^[a-z0-9]+)((\s[a-z0-9]+))*\@([a-z0-9]+)$', m.name[1] || '@' || ) FROM (SELECT REGEXP_MATCHES(::string[], '(^[a-z0-9]+)((\s[a-z0-9]+))*\@([a-z0-9]+)$') AS name) m"

  1. 获取匹配的用户名并将其替换为新值。 usernames:从 queryable
  2. 检索到的用户名列表

Repo.query(raw, [usernames, a_string])

  1. 我收到错误

    SELECT REGEXP_REPLACE($1::string[], '(^[a-z0-9]+)(( [a-z0-9]+))@([a-z0-9]+)$', m.name[1] || '@' || $2) FROM (SELECT REGEXP_MATCHES($1::string [], '(^[a-z0-9]+)(( [a-z0-9]+))@([a-z0-9]+)$') 作为名称) m [["tradeboox@trdbx18"], "trdbx17"] {:错误, %Postgrex.Error{connection_id: 7222, 消息: 无, postgres: %{code: :undefined_object, 文件: "parse_type.c", 行: "257", 消息:"type \"string[]\"不存在",pg_code:"42704", 位置:“137”,常规:"typenameType",严重性:"ERROR", 未知:"ERROR"}}}

仅供参考:User 模型的 username 字段的类型为 citext


  1. 获得替换值后,我想用
  2. 之类的内容更新 User

update([u], set: [username: new_values])

关于如何进行此操作的任何想法?

`

PostgreSQL 中没有 string 类型。

函数 regexp_matches 仅接受 text 作为第一个参数,并且不能是数组。所以你需要做的是首先将该类型更改为文本,然后 unnest(::text[]) 你的数组。使用这些正则表达式迭代结果行集。

raw = "SELECT REGEXP_REPLACE(m.item, '(^[a-z0-9]+)((\s[a-z0-9]+))*\@([a-z0-9]+)$', m.name[1] || '@' || )
         FROM (
               SELECT item, REGEXP_MATCHES(item, '(^[a-z0-9]+)((\s[a-z0-9]+))*\@([a-z0-9]+)$') AS name
                 FROM unnest(::text[]) AS items(item)
              ) m"

如果我理解正确,您正试图用一些不同的字符串替换 @ 之后的所有内容 - 如果是这种情况,那么您的正则表达式会将空格键之后的所有内容放入 matches 数组的第二个元素中。你会需要这个:((^[a-z0-9]+)(\s[a-z0-9]+)*).

如果以上是真的,那么你可以用这个更容易地做所有事情:

SELECT REGEXP_REPLACE(item, '((^[a-z0-9]+)(\s[a-z0-9]+)*)\@([a-z0-9]+)$', '' || ) AS name
  FROM unnest(::text[]) AS items(item)

然而,最佳做法是简单地在 UPDATE 语句中进行替换:

UPDATE "User" SET
  name = concat(split_part(name, '@', 1), '@', )
WHERE organization_id = 
  AND name ~* '^[a-z0-9]+(\s[a-z0-9]+)*\@[a-z0-9]+$'

它将名称拆分为 @,取第一部分,然后附加 @ 以及分配给 </code> 的任何内容(我猜是域名)。它只会更新 organization_id 与某些 ID 匹配且名称与您的正则表达式匹配的行(如果您想更改组织中的所有名称,则可以省略正则表达式)。确保 table 在实际命名的 <code>User 中区分大小写,或者删除双引号以具有不区分大小写的版本。

遗憾的是,我不知道如何在您的 ORM 中执行此操作。