web-dev-qa-db-ja.com

SQL SERVERプロシージャのPOSTGRESQLへの変換

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;
2
Kuba Ronkiewicz

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