sql - Postgres:想要在用户存在时选择数据,否则插入用户
问题描述
仍然掌握 PostgreSQL 的窍门(使用 PostgreSQL-12,因此非常感谢任何建议。
我有一个允许用户保存和创建歌曲播放列表的应用程序。
我的表是:用户、播放列表、歌曲然后我有两个联结表: user_playlist、playlist_song
我有一个查询,当给定用户 ID 时,将返回该用户的第一个播放列表中的所有歌曲(应用程序默认为登录时的第一个播放列表),并且它目前按我想要的方式工作。
我要解决的下一个问题是,我现在想将该查询与第二个查询结合起来,如果它当前不存在,它将把用户 ID 添加到用户表中。
因此流程将是用户登录,然后在登录时将用户 ID 发送到我的数据库。在我的数据库中,我想检查该用户 ID 是否已经存在,如果存在,我希望执行返回歌曲的 SELECT 查询,但如果该用户 ID 不存在,我想将该用户 ID 插入到我的用户表中
我已经阅读了大约 10 个 StackOverflow 解决方案,试图调整它们为我工作,但没有任何运气。我不确定我是否应该发布我已经尝试过的所有东西。
$$ BEGIN
IF EXISTS (SELECT 1 FROM users WHERE userid = '1') THEN
SELECT
s.songid,
s.title,
s.artists,
s.album,
s.year,
s.duration,
s.url,
ps.songOrder
FROM
playlist_song ps
JOIN
songs s
ON
ps.songid = s.songid
JOIN
playlists p
ON
ps.playlistid = p.playlistid
WHERE
p.playlistid = (
SELECT
p.playlistid
FROM
user_playlist up
JOIN
playlists p
ON
up.playlistid = p.playlistid
JOIN
users u
ON
up.userid = u.userid
WHERE
u.userid = '1'
LIMIT 1
)
ORDER BY ps.songOrder;
ELSE
INSERT INTO users (userid, username) VALUES ('1', 'Haley')
ON CONFLICT DO NOTHING;
END IF;
END $$;
这是我在 PG admin 中测试它时当前给我的错误:
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function inline_code_block line 4 at SQL statement
SQL state: 42601
所以我然后将 RETURN 添加到我的 SELECT 中,错误更改为
LINE 5: RETURN (SELECT
^
SQL state: 42804
Character: 98
添加 RETURN QUERY 给出的错误是不能在非 setof 函数中使用返回查询
添加 RETURN SETOF 给出的错误是 RETURN 在返回 void 的函数中不能有参数
我已经坚持了一天半,在这一点上,我不想将它分解为对数据库的多次调用,除非这是不可能的(我的骄傲需要压扁这个臭虫)
我不能告诉你有多少你的帮助将不胜感激!提前致谢
编辑:这是我的桌子
CREATE TABLE IF NOT EXISTS users (
userid TEXT NOT NULL,
username TEXT NOT NULL,
CONSTRAINT u_id_pk PRIMARY KEY (userid)
);
CREATE TABLE IF NOT EXISTS playlists (
playlistid SERIAL NOT NULL,
playlistname TEXT NOT NULL,
CONSTRAINT p_id_pk PRIMARY KEY (playlistid)
);
CREATE TABLE IF NOT EXISTS songs (
songid SERIAL NOT NULL,
url TEXT,
href TEXT,
title TEXT,
artists TEXT,
album TEXT,
year integer,
duration integer,
CONSTRAINT s_pk PRIMARY KEY (songid)
);
CREATE TABLE IF NOT EXISTS user_playlist (
userid TEXT,
playlistid INTEGER,
CONSTRAINT u_up_fk FOREIGN KEY (userid) REFERENCES users(userid),
CONSTRAINT p_up_fk FOREIGN KEY (playlistid) REFERENCES playlists(playlistid)
);
CREATE TABLE IF NOT EXISTS playlist_song (
playlistid INTEGER,
songid INTEGER,
songOrder INTEGER,
CONSTRAINT p_ps_fk FOREIGN KEY (playlistid) REFERENCES playlists(playlistid),
CONSTRAINT s_ps_fk FOREIGN KEY (songid) REFERENCES songs(songid)
);
下一次尝试:
CREATE TYPE songs_type AS (
songid integer,
title character varying(25),
artists character varying(25),
album character varying(25),
year integer,
duration integer,
url character varying(25),
songOrder integer
);
CREATE OR REPLACE FUNCTION func() RETURNS songs_type AS
$$
DECLARE results_record songs_type;
BEGIN
IF EXISTS (SELECT 1 FROM auxium.users WHERE userid = '1') THEN
SELECT
s.songid,
s.title,
s.artists,
s.album,
s.year,
s.duration,
s.url,
ps.songOrder
INTO
results_record.songid,
results_record.title,
results_record.artists,
results_record.album,
results_record.year,
results_record.duration,
results_record.url,
results_record.songOrder
FROM
auxium.playlist_song ps
JOIN
auxium.songs s
ON
ps.songid = s.songid
JOIN
auxium.playlists p
ON
ps.playlistid = p.playlistid
WHERE
p.playlistid = (
SELECT
p.playlistid
FROM
auxium.user_playlist up
JOIN
auxium.playlists p
ON
up.playlistid = p.playlistid
JOIN
auxium.users u
ON
up.userid = u.userid
WHERE
u.userid = '1'
LIMIT 1
)
ORDER BY ps.songOrder;
ELSE
INSERT INTO auxium.users (userid, username) VALUES ('1', 'Haley')
ON CONFLICT DO NOTHING;
END IF;
return results_record;
END;
$$
LANGUAGE plpgsql;
解决方案
创建类型,然后返回它。
我创建了 users(userid,username) 表,然后创建了与我选择相同模式的类型。您必须将其更改为您正在选择的列(在创建 TYPE 时)。
它工作正常。
CREATE TYPE users_type AS (userid integer,username character varying(10));
CREATE OR REPLACE FUNCTION fun() RETURNS users_type AS
$$
DECLARE result_record users_type;
BEGIN
IF EXISTS (SELECT 1 FROM users WHERE userid = 1) THEN
SELECT userid,username into result_record.userid,result_record.username from users;
ELSE
INSERT INTO users (userid, username) VALUES (1, 'Haley');
END IF;
return result_record;
END;
$$
LANGUAGE plpgsql;
推荐阅读
- firebase - 是否可以在一个项目中创建多个 firebase 实时数据库实例(>20)
- javascript - Javascript匹配以字符集中的特定字符开头并使用正则表达式以相同字符结尾的字符串
- dtrace - 谓词中的 Dtrace 字符串比较不起作用
- reactjs - “是否可以仅在第二次单击后跟随 Lick 到 'some path url' ?”
- php - 来自 curl 响应的 SimpleXMLElement - @attributes 的问题
- java - 将嵌套的 JSON 键转换为大写
- asp.net-mvc-5 - 如何在控制器中使用多个排序顺序
- php - phpmyadmin 导出命名模板/变量
- javascript - date.getHours() 为浏览器和移动设备返回不同的值
- postgresql - Postgresql - 在选择查询中返回 json 数组而不是逗号分隔值