Postgres SELECT WHERE是UUID或字符串

时间:2017-09-26 18:30:16

标签: postgresql

我在Postgres中使用了简化表:

  • 用户模型
    • id(UUID)
    • uid(varchar)
    • name(varchar)

我想要一个可以在其UUID id或其文字uid上找到用户的查询。

SELECT * FROM user
WHERE id = 'jsdfhiureeirh' or uid = 'jsdfhiureeirh';

我的查询会生成invalid input syntax for uuid,因为在这种情况下,我显然没有使用UUID。

如何优化此查询或检查该值是否为有效的UUID?

3 个答案:

答案 0 :(得分:24)

发现它!将UUID列转换为::text可以阻止错误。不确定性能是否打击,但是在大约5000行上我得到的效果不仅仅是足够的。

SELECT * FROM user
WHERE id::text = 'jsdfhiureeirh' OR uid = 'jsdfhiureeirh';

SELECT * FROM user
WHERE id::text = '33bb9554-c616-42e6-a9c6-88d3bba4221c' 
  OR uid = '33bb9554-c616-42e6-a9c6-88d3bba4221c';

答案 1 :(得分:5)

我原本误解了这个问题。如果你想安全地"尝试将字符串强制转换为UUID,您可以编写一个函数来捕获invalid_text_representation异常并返回nullmodified from an answer to a different question):

CREATE OR REPLACE FUNCTION uuid_or_null(str text)
RETURNS uuid AS $$
BEGIN
  RETURN str::uuid;
EXCEPTION WHEN invalid_text_representation THEN
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

SELECT uuid_or_null('INVALID') IS NULL将导致true

换句话说(鉴于(true or null) = true),

SELECT * FROM user
WHERE id = uuid_or_null('FOOBARBAZ') OR uid = 'FOOBARBAZ';

原始回答:

Postgres会自动将字符串转换为UUID,但您需要使用有效的UUID。 例如:

SELECT * FROM user
WHERE id = '5af75c52-cb8e-44fb-93c8-1d46da518ee6' or uid = 'jsdfhiureeirh';

您还可以使用DEFAULT功能uuid_generate_v4()使用uuid-ossp扩展名让Postgres为您生成UUID:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE user (  
   id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
   uid TEXT,
   name TEXT
);

答案 2 :(得分:0)

您可以使用正则表达式进行检查:

SELECT *
FROM user
WHERE ('jsdfhiureeirh' ~ E'^[[:xdigit:]]{8}-([[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$'
       AND id = 'jsdfhiureeirh')
      OR uid = 'jsdfhiureeirh';