Petla dla listy PostgreSQL

0

Witajcie, moze mi pomozecie, nie jestem obeznany w petlach w sql, mozecie dac mi wskazowke jak moge rozwiazac moj problem?

Mam zapytanie sql typu:

INSERT INTO user_notifications(user_id, category)
VALUES(
          (SELECT id FROM user WHERE key = 'x'),
          'ALL'
      );

gdzie 'x' to numer z listy.
W skrocie - mam liste z numerami i dla kazdego numeru musze wywolac ten skrypt.

Cos takiego: numery: 123,34,46,67,798,0,45,2,566,889
wynik:

INSERT INTO user_notifications(user_id, category)
VALUES(
          (SELECT id FROM user WHERE key = '123'),
          'ALL'
      );
INSERT INTO user_notifications(user_id, category)
VALUES(
          (SELECT id FROM user WHERE key = '34'),
          'ALL'
      );
INSERT INTO user_notifications(user_id, category)
VALUES(
          (SELECT id FROM user WHERE key = '46'),
          'ALL'
      );

Jak to zrobic w petli?

4

Można to zrobić w PL/pgSQL https://www.postgresql.org/docs/14/plpgsql-control-structures.html

BEGIN
    FOR r IN
        SELECT * FROM foo WHERE fooid > 0
    LOOP
        -- can do some processing here
        RETURN NEXT r; -- return current row of SELECT
    END LOOP;
    RETURN;
END;
0

SQL jest językiem deklaratywnym, nie ma w nim koncepcji pętli

(No dobra, w procedurach można .. ale nadal uważam, że myślenie "pętlą" nie prowadzi w dobrą stronę. Zdrowszym jest myślenie myślenie "foreach" z warunkiem lub bez).

https://www.postgresql.org/docs/9.4/dml-insert.html

2
INSERT INTO user_notifications SELECT id , 'ALL' FROM user;
1
Stang napisał(a):

Jak to zrobic w petli?

Dobra rada na przyszłość - SQL i pętla to zło.
SQL, z definicji, jest zorientowany na przetwarzanie zbiorów danych, a nie pojedynczych danych reprezentujący dany wiersz.

Praktycznie wszystko to co chcesz zrobić w pętli, w SQL da się zrobić bez niej.
Dla RDBMS jest to rozwiązanie znacznie lepsze ("bez-pętli") z każdego punktu widzenia (współbieżności, zasobów, wydajności, itd.).

0

Insert into select

1

Nie o to chodzi, potrzebuję możliwości wykonywania skryptu dla każdego elementu z podanej listy, to co napisałem to tylko przykład

Powiedz co to za skrypt

Jak chcesz ograniczyć ten insert do konkretnych numerów to możesz napisać:

INSERT INTO user_notifications SELECT id , 'ALL' FROM user WHERE id in (123,34,46,67,798,0,45,2,566,889)
2

Kilka sposobów:

select unnest(array[123,34,46,67,798,0,45,2,566,889]);

select unnest(string_to_array('123,34,46,67,798,0,45,2,566,889', ','));

select json_array_elements_text('[123,34,46,67,798,0,45,2,566,889]') ;

Dodatkowo jeśli jest to w funkcji, to możesz użyć VARIADIC ARRAYS :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1