I built an Oracle database (version 9.2, I know it is obsolete, but it is the version installed at my university and I do not have a choice) with a list of users and their immediate friends. I am working on a set of queries to list the "network" of a user, including his friends' friends, and to compute the degree of separation between the user in question and the other members.
I tested the three queries separately and I confirm they do work.
I would now like to create a PL/SQL procedure to combine the 3 queries, so as to be able to feed the ID of a player as a parameter, but also to launch the three queries with one Execute statement.
However, I am unable to run the procedure. I am not even able to convert the first query in a procedure (see my code below).
Could someone please explain what I am doing wrong?
Here are the queries (they are working):
INSERT INTO UserFriendsCopy
SELECT *
FROM UserFriends
WHERE PlayerID < FriendsWith;
INSERT INTO Degrees_Separation
SELECT PlayerID, FriendsWith, LEVEL AS Degree
FROM UserFriendsCopy
START WITH PlayerID = 1
CONNECT BY PRIOR FriendsWith = PlayerID;
SELECT FriendsWith, MIN(Degree)
FROM Degrees_Separation
GROUP BY FriendsWith;
Here is a procedure that I wrote to replace the first query. It is not working. Why?
CREATE OR REPLACE PROCEDURE procDegrees1
AS
DECLARE
CURSOR UserFriendsNoDupl IS SELECT * FROM UserFriends WHERE PlayerID < FriendsWith;
BEGIN
FOR record IN UserFriendsNoDupl
LOOP
EXIT WHEN UserFriendsNoDupl%NOTFOUND;
INSERT INTO UserFriendsCopy VALUES(record.PlayerID, record.FriendsWith);
END LOOP;
END;/
EXECUTE procDegrees1/
[UPDATE] I have re-written the procedure as follows, to take into account the comments received so far. Still, it does not work.
CREATE OR REPLACE PROCEDURE procDegrees1
AS
BEGIN
FOR record IN (SELECT * FROM UserFriends WHERE PlayerID < FriendsWith)
LOOP
INSERT INTO UserFriendsCopy(PlayerID,FriendsWith) VALUES(record.PlayerID, record.FriendsWith);
END LOOP;
END;/
By the way, here are the tables definitions, along with some dummy records:
DROP TABLE Degrees_Separation;
DROP TABLE UserFriends;
DROP TABLE UserFriendsCopy;
CREATE TABLE UserFriends (
PlayerID INT NOT NULL,
FriendsWith INT NOT NULL,
CONSTRAINT pkUserFriends
PRIMARY KEY (PlayerID, FriendsWith),
CONSTRAINT fkPlayerIDThird
FOREIGN KEY (PlayerID)
REFERENCES Player (PlayerID),
CONSTRAINT fkPlayerIDFourth
FOREIGN KEY (FriendsWith)
REFERENCES Player (PlayerID)
);
CREATE TABLE UserFriendsCopy (
PlayerID INT NOT NULL,
FriendsWith INT NOT NULL,
CONSTRAINT pkUserFriendsBis
PRIMARY KEY (PlayerID, FriendsWith)
);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (1, 2);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (2, 1);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (2, 3);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (3, 2);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (2, 4);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (4, 2);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (1, 4);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (4, 1);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (5, 6);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (6, 5);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (3, 8);
INSERT INTO UserFriends (PlayerID, FriendsWith)
VALUES (8, 3);
CREATE TABLE Degrees_Separation (
PlayerID INT NOT NULL,
FriendsWith INT NOT NULL,
Degree INT NOT NULL,
CONSTRAINT fkPlayerIDSeventh
FOREIGN KEY (PlayerID)
REFERENCES Player (PlayerID),
CONSTRAINT fkPlayerIDEighth
FOREIGN KEY (FriendsWith)
REFERENCES Player (PlayerID)
);
Thanks, LC