Sql-Server

將 SQL SERVER 過程轉換為 POSTGRESQL

  • December 19, 2018

我在 SQL Server 中有程序來列印給定國家的所有玩家。我嘗試將其轉換為 plpgsql,但出現錯誤。

SQL Server 過程

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

在 PostgreSql 中不起作用

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;

在 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;

但是以下更簡單的方法會做同樣的事情:

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;

您甚至無需創建函式即可直接實現相同的目標:

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;
$$;

引用自:https://dba.stackexchange.com/questions/138563