存储过程名称到id转换

时间:2012-04-07 19:08:37

标签: sql postgresql stored-procedures plpgsql

我有一张providerid|provider_name|url 我还有另一张userid|name|provider_id

我想创建一个函数create_user(name,provider_name),用于检查是否存在具有该提供程序名称的任何提供程序。 if exists插入行并返回最后一行id。其他明智的回归0。我在provider_id - >上设置了外键完整性user.id。并且id个字段均为pkeyserial

insert into users
  (name, provider_id)
values($1, (
    select id from provider where name = $2
)) returning id

那可以吗?

2 个答案:

答案 0 :(得分:1)

您的陈述

INSERT INTO users (name, provider_id)
VALUES ($1, (SELECT id FROM provider WHERE name = $2))
RETURNING id;
如果您创建users.provider_id NOT NULL

将起作用。如果没有它,您将为不存在的provider_id输入NULL值。外键约束不会禁止这个!
(我假设你的意思是:provider_id -> provider.id,而不是-> user.id。)

您可能希望也可能不希望users.name UNIQUE禁止重复名称。

使用唯一名称,代理主键(user.id)在大多数情况下仍然有意义。处理整数比处理(更长)文本更快。特别是如果您有多个其他表引用user表的主键,通常就是这种情况。对外键和附带索引使用整数要快得多,并且在磁盘和RAM中需要的空间更少。稍后进行更改也更容易,例如将name拆分为firstnamesurname

答案 1 :(得分:0)

如果有多个具有该名称的用户行,则无效。如果用户之间的重复名称不可能,那就没关系。 (如果那真的是一个名字,假设没有重复是不明智的。)

当然,如果无法使用重复的用户名,则没有充分的理由在用户表上有一个id列;我强烈建议只将名称作为主键并且不要使用id列。 (它也可能被称为其他东西。)这将简化和加速此查询以及整个查询类。此架构设计还假设一个用户最多只能有一个提供程序(如果provider_id为null)或者只有一个提供程序(如果provider_id为NOT NULL)。