Kub*_*icz 2 postgresql sql-server cursors plpgsql functions
我在 SQL Server 中有程序可以打印给定国家/地区的所有玩家。我尝试将其转换为 plpgsql,但出现错误。
CREATE PROCEDURE kraj_pilkarze @kraj varchar(30)
AS
DECLARE @idkraj INT
DECLARE @nazwa_zespolu varchar(30)
SELECT @idkraj = id_kraj FROM kraj WHERE @kraj=nazwa
DECLARE kursor_pilk CURSOR
FOR SELECT imie,nazwisko, id_zespol, id_kraj FROM pilkarz
DECLARE @imie varchar(20), @nazwisko varchar(30), @zespol int, @d_kraj int
OPEN kursor_pilk
FETCH NEXT FROM kursor_pilk INTO @imie, @nazwisko,@zespol, @d_kraj
WHILE @@FETCH_STATUS=0
BEGIN
IF @d_kraj=@idkraj
BEGIN
SELECT @nazwa_zespolu = nazwa FROM zespol WHERE @zespol=id_zespol
PRINT @imie+' '+@nazwisko+', '+@nazwa_zespolu
FETCH NEXT FROM kursor_pilk INTO @imie, @nazwisko,@zespol,@d_kraj
END
ELSE
BEGIN
FETCH NEXT FROM kursor_pilk INTO @imie, @nazwisko,@zespol,@d_kraj
END
END
CLOSE kursor_pilk
DEALLOCATE kursor_pilk
Run Code Online (Sandbox Code Playgroud)
CREATE FUNCTION kraj_pilkarze(p_kraj varchar(30))
RETURNS VOID AS $$
BEGIN
DECLARE p_idkraj INT;
DECLARE p_nazwa_zespolu varchar(30);
DECLARE p_imie varchar(20), p_nazwisko varchar(30), p_zespol int, d_kraj int;
SELECT INTO p_idkraj id_kraj FROM kraj WHERE p_kraj=nazwa;
DECLARE kursor_pilk CURSOR FOR
SELECT imie,nazwisko, id_zespol, id_kraj FROM pilkarz;
OPEN kursor_pilk;
FETCH NEXT FROM kursor_pilk INTO p_imie, p_nazwisko,p_zespol, d_kraj;
WHILE (FOUND) LOOP
IF d_kraj=p_idkraj THEN
SELECT INTO p_nazwa_zespolu nazwa FROM zespol WHERE @zespol=id_zespol;
RAISE NOTICE '% %, %',p_imie,p_nazwisko,p_nazwa_zespolu;
FETCH NEXT FROM kursor_pilk INTO p_imie, p_nazwisko,p_zespol,d_kraj;
ELSE
FETCH NEXT FROM kursor_pilk INTO p_imie, p_nazwisko,p_zespol,d_kraj;
END IF;
END LOOP;
CLOSE kursor_pilk;
END;
$$ LANGUAGE PLPGSQL;
Run Code Online (Sandbox Code Playgroud)
在 plpgsql 中更容易:
CREATE FUNCTION kraj_pilkarze(p_kraj varchar(30)) RETURNS VOID AS $$
DECLARE
_r RECORD;
_id_kraj int;
_nazwa_zespolu text;
BEGIN
_id_kraj := id_kraj FROM kraj WHERE nazwa = $1;
FOR _r IN
SELECT imie, nazwisko, id_zespol, id_kraj FROM pilkarz
LOOP
IF r.id_kraj = _id_kraj THEN
_nazwa_zespolu := nazwa FROM zespol WHERE zespol = _r.id_zespol;
RAISE NOTICE '% %, %', _r.imie, _r.nazwisko, _nazwa_zespolu;
END IF;
END LOOP;
END;
$$ LANGUAGE PLPGSQL;
Run Code Online (Sandbox Code Playgroud)
但以下更简单的方法会做完全相同的事情:
CREATE FUNCTION kraj_pilkarze(p_kraj varchar(30)) RETURNS VOID AS $$
DECLARE
_r RECORD;
BEGIN
FOR _r IN
SELECT imie, nazwisko, id_zespol, id_kraj, (SELECT nazwa FROM zespol WHERE zespol = p.id_zespol) nazwa
FROM pilkarz p WHERE id_kraj = (id_kraj FROM kraj WHERE nazwa = $1)
LOOP
RAISE NOTICE '% %, %', _r.imie, _r.nazwisko, _r.nazwa;
END LOOP;
END;
$$ LANGUAGE PLPGSQL;
Run Code Online (Sandbox Code Playgroud)
你甚至可以在不创建函数的情况下直接实现同样的事情:
DO $$
DECLARE
_r RECORD;
BEGIN
FOR _r IN
SELECT imie, nazwisko, id_zespol, id_kraj, (SELECT nazwa FROM zespol WHERE zespol = p.id_zespol) nazwa
FROM pilkarz p WHERE id_kraj = (id_kraj FROM kraj WHERE nazwa = $1)
LOOP
RAISE NOTICE '% %, %', _r.imie, _r.nazwisko, _r.nazwa;
END LOOP;
END;
$$;
Run Code Online (Sandbox Code Playgroud)