仍然掌握 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;