PostgreSQL АнтипатСрни: ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π½Π°Π±ΠΎΡ€ΠΈ ΠΈ сСлСкции Π² SQL

ΠŸΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π½ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° Π½ΡƒΠΆΠ΄Π° Π΄Π° ΠΏΡ€Π΅Π΄Π°Π΄Π΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ ΠΈΠ»ΠΈ Π΄ΠΎΡ€ΠΈ цяла ΠΈΠ·Π²Π°Π΄ΠΊΠ° Π½Π° 'Π²Ρ…ΠΎΠ΄Π°'. Понякога сС срСщат ΠΌΠ½ΠΎΠ³ΠΎ странни Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π° Ρ‚Π°Π·ΠΈ Π·Π°Π΄Π°Ρ‡Π°.
PostgreSQL АнтипатСрни: ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π½Π°Π±ΠΎΡ€ΠΈ ΠΈ сСлСкции Π² SQL
НСка Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ 'ΠΎΡ‚ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ' ΠΈ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊΠ²ΠΎ Π½Π΅ трябва Π΄Π° сС ΠΏΡ€Π°Π²ΠΈ, Π·Π°Ρ‰ΠΎ ΠΈ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅.

ΠŸΡ€ΡΠΊΠ° 'Π²Ρ€Π΅Π·ΠΊΠ°' Π½Π° стойности Π² тялото Π½Π° заявката

ОбикновСно ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»Π½ΠΎ Ρ‚Π°ΠΊΠ°:

query = "SELECT * FROM tbl WHERE id = " + value

... ΠΈΠ»ΠΈ Ρ‚Π°ΠΊΠ°:

query = "SELECT * FROM tbl WHERE id = :param".format(param=value)

Π—Π° Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΅ ΠΊΠ°Π·Π°Π½ΠΎ, написано ΠΈ Π΄ΠΎΡ€ΠΈ нарисувано Π² Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΈ количСства:

PostgreSQL АнтипатСрни: ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π½Π°Π±ΠΎΡ€ΠΈ ΠΈ сСлСкции Π² SQL

ΠŸΠΎΡ‡Ρ‚ΠΈ Π²ΠΈΠ½Π°Π³ΠΈ Ρ‚ΠΎΠ²Π° Π΅β€” пряк ΠΏΡŠΡ‚ към SQL ΠΈΠ½ΠΆΠ΅ΠΊΡ†ΠΈΠΈ ΠΈ излишно Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅ Π½Π° бизнСс Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π°, която Π΅ ΠΏΡ€ΠΈΠ½ΡƒΠ΄Π΅Π½Π° Π΄Π° 'Π·Π°Π»Π΅ΠΏΠ²Π°' стринга Π½Π° Π²Π°ΡˆΠ°Ρ‚Π° заявка.

Частично ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС само Π² случай Π½Π° нСобходимост ΠΎΡ‚ сСкциониранС Π² вСрсии PostgreSQL 10 ΠΈ ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ Π·Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° ΠΏΠΎ-Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π΅Π½ ΠΏΠ»Π°Π½. Π’ Ρ‚Π΅Π·ΠΈ вСрсии ΡΠΏΠΈΡΡŠΠΊΡŠΡ‚ Π½Π° сканиранитС сСкции сС опрСдСля Π±Π΅Π· Π΄Π° сС Π²Π·ΠΈΠΌΠ°Ρ‚ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄ ΠΏΡ€Π΅Π΄Π°Π²Π°Π½ΠΈΡ‚Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ, само Π½Π° Π±Π°Π·Π°Ρ‚Π° Π½Π° тялото Π½Π° заявката.

$n-Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ

ИзползванС плСйсхолдСри ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ β€” Ρ‚ΠΎΠ²Π° Π΅ Π΄ΠΎΠ±Ρ€ΠΎ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ позволява Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ PREPARED STATEMENTS, намалявайки Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅Ρ‚ΠΎ ΠΊΠ°ΠΊΡ‚ΠΎ Π½Π° бизнСс Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° (стринг заявката сС Ρ„ΠΎΡ€ΠΌΠΈΡ€Π° ΠΈ ΠΏΡ€Π΅Π΄Π°Π²Π° само Π΅Π΄ΠΈΠ½ ΠΏΡŠΡ‚), Ρ‚Π°ΠΊΠ° ΠΈ Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π° Π½Π° Π‘Π” (Π½Π΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ ΠΈ ΠΏΠ»Π°Π½ΠΈΡ€Π°Π½Π΅ Π·Π° всСки СкзСмпляр Π½Π° заявката).

ΠŸΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΎ количСство Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ Ρ‰Π΅ Π½ΠΈ ΠΎΡ‡Π°ΠΊΠ²Π°Ρ‚, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΏΠΎΠΆΠ΅Π»Π°Π΅ΠΌ Π΄Π° ΠΏΡ€Π΅Π΄Π°Π΄Π΅ΠΌ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ нСизвСстно количСство Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ:

... id IN ($1, $2, $3, ...) -- $1 : 2, $2 : 3, $3 : 5, ...

Ако оставим заявката Π² Ρ‚ΠΎΠ·ΠΈ Π²ΠΈΠ΄, тя Ρ‰Π΅ Π½ΠΈ ΠΏΡ€Π΅Π΄ΠΏΠ°Π·ΠΈ ΠΎΡ‚ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π½ΠΈ ΠΈΠ½ΠΆΠ΅ΠΊΡ†ΠΈΠΈ, Π½ΠΎ всС ΠΏΠ°ΠΊ Ρ‰Π΅ Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ нСобходимост ΠΎΡ‚ Π·Π°Π»Π΅ΠΏΠ²Π°Π½Π΅/Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π½Π° заявката Π·Π° всСки Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΎΡ‚ броя Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅.Π’Π΅Ρ‡Π΅ Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅, ΠΎΡ‚ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ Π΄Π° ΠΏΡ€Π°Π²ΠΈΠΌ Ρ‚ΠΎΠ²Π° всСки ΠΏΡŠΡ‚, Π½ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° сС справим ΠΈ Π±Π΅Π· Ρ‚ΠΎΠ²Π°.

Π”ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Π΅ Π΄Π° ΠΏΡ€Π΅Π΄Π°Π΄Π΅ΠΌ само Π΅Π΄ΠΈΠ½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ сСриализирано прСдставянС Π½Π° масив:

... id = ANY($1::integer[]) -- $1 : '{2,3,5,8,13}'

ЕдинствСната Ρ€Π°Π·Π»ΠΈΠΊΠ° Π΅ нСобходимостта явно Π΄Π° ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°ΠΌΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π² нуТния Ρ‚ΠΈΠΏ масив. Но Ρ‚ΠΎΠ²Π° Π½Π΅ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ²Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ Π·Π½Π°Π΅ΠΌ къдС адрСсирамС.

ΠŸΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΈΠ·Π²Π°Π΄ΠΊΠ° (ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°)

ОбикновСно Ρ‚ΠΎΠ²Π° са всякакви Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΈ Π·Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π½Π°Π±ΠΎΡ€ΠΈ ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ Π·Π° вмъкванС Π² Π±Π°Π·Π°Ρ‚Π° 'с Π΅Π΄ΠΈΠ½ Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅':

INSERT INTO tbl(k, v) VALUES($1,$2),($3,$4),...

Π‘ΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ°, освСн описанитС ΠΏΠΎ-Π³ΠΎΡ€Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ с 'ΠΏΠ΅Ρ€Π΅ΠΊΠ»Π΅ΠΉΠΊΠ°Ρ‚Π°' Π½Π° заявката, Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π½ΠΈ Π΄ΠΎΠ²Π΅Π΄Π΅ ΠΈ Π΄ΠΎ out of memory ΠΈ ΠΏΠ°Π΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π°. ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π΅ проста β€” ΠΏΠΎΠ΄ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ PG Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½Π° ΠΏΠ°ΠΌΠ΅Ρ‚, Π° броят Π½Π° записитС Π² Π½Π°Π±ΠΎΡ€Π° Π΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ само ΠΎΡ‚ бизнСс Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ. Π’ особСно ΠΊΠ»ΠΈΠ½ΠΈΡ‡Π½ΠΈ случаи сС Π΅ Π½Π°Π»Π°Π³Π°Π»ΠΎ Π΄Π° сС Π²ΠΈΠ΄ΠΈ Β«Π½ΠΎΠΌΠ΅Ρ€Π½ΠΈΒ» Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ Π½Π°Π΄ 9000 Π»Π². β€” Π½Π΅ трябва Ρ‚Π°ΠΊΠ°.

Π”Π° ΠΏΡ€Π΅Π½Π°ΠΏΠΈΡˆΠ΅ΠΌ заявката, ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° Β«Π΄Π²ΡƒΡƒΡ€ΠΎΠ²Π½Π°Β» сСриализация:

INSERT INTO tbl
SELECT
  unnest[1]::text k
, unnest[2]::integer v
FROM (
  SELECT
    unnest($1::text[])::text[] -- $1 : '{"{a,1}","{b,2}","{c,3}","{d,4}"}'
) T;

Π”Π°, Π² случая с «слоТни» стойности Π² масива, Ρ‚Π΅ трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΠΎΠ±Π³Ρ€Π°Π΄Π΅Π½ΠΈ с ΠΊΠ°Π²ΠΈΡ‡ΠΊΠΈ.
Ясно Π΅, Ρ‡Π΅ с Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Β«Ρ€Π°Π·Π²ΠΈΠ΅Β» ΠΈΠ·Π±ΠΎΡ€Π° с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π΅Π½ Π±Ρ€ΠΎΠΉ ΠΏΠΎΠ»Π΅Ρ‚Π°.

unnest, unnest, …

ΠŸΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π½ΠΎ сС срСщат Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΈ Π½Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ вмСсто «массив ΠΎΡ‚ массиви» няколко «массиви ΠΎΡ‚ ΠΊΠΎΠ»ΠΎΠ½ΠΈΒ», Π·Π° ΠΊΠΎΠΈΡ‚ΠΎ спомСнах. Π² ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π° статия:

SELECT
  unnest($1::text[]) k
, unnest($2::integer[]) v;

ΠŸΡ€ΠΈ Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΊΠ°Ρ‚ΠΎ ΡΠ³Ρ€Π΅ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΡΠΏΠΈΡΡŠΡ†ΠΈ ΠΎΡ‚ стойности Π·Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΊΠΎΠ»ΠΎΠ½ΠΈ, Π΅ ΠΌΠ½ΠΎΠ³ΠΎ лСсно Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ напълно Π½Π΅ΠΎΡ‡Π°ΠΊΠ²Π°Π½ΠΈ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈ, зависСщи ΠΈ ΠΎΡ‚ вСрсията Π½Π° ΡΡŠΡ€Π²ΡŠΡ€Π°:

-- $1 : '{a,b,c}', $2 : '{1,2}'
-- PostgreSQL 9.4
k | v
-----
a | 1
b | 2
c | 1
a | 2
b | 1
c | 2
-- PostgreSQL 11
k | v
-----
a | 1
b | 2
c |

JSON

Π—Π°ΠΏΠΎΡ‡Π²Π°ΠΉΠΊΠΈ с вСрсия 9.3 Π² PostgreSQL, сС появиха ΠΏΡŠΠ»Π½ΠΎΡ†Π΅Π½Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ρ‚ΠΈΠΏΠ° json. Π—Π°Ρ‚ΠΎΠ²Π°, Π°ΠΊΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π²Ρ…ΠΎΠ΄Π½ΠΈΡ‚Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Π² Π±Ρ€Π°ΡƒΠ·ΡŠΡ€Π°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΏΡ€Π°Π²ΠΎ Ρ‚Π°ΠΌ Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ json-ΠΎΠ±Π΅ΠΊΡ‚ Π·Π° SQL-заявка:

SELECT
  key k
, value v
FROM
  json_each($1::json); -- '{"a":1,"b":2,"c":3,"d":4}'

Π—Π° ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈ вСрсии ΡΡŠΡ‰ΠΈΡΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° each(hstore), Π½ΠΎ ΠΊΠΎΡ€Π΅ΠΊΡ‚Π½Π°Ρ‚Π° «свСртка» с Π΅ΠΊΠ·Π΅ΠΊΠ΅Ρ‚ΠΈΡ€Π°Π½Π΅ Π½Π° слоТни ΠΎΠ±Π΅ΠΊΡ‚ΠΈ Π² hstore ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ.

json_populate_recordset

Ако ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ Π·Π½Π°Π΅Ρ‚Π΅, Ρ‡Π΅ Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΎΡ‚ «входния» json-масив Ρ‰Π΅ ΠΎΡ‚ΠΈΠ΄Π°Ρ‚ Π·Π° запълванС Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° спСститС ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈ Β«Ρ€Π°Π·ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π΅Ρ‚ΠΎΒ» Π½Π° ΠΏΠΎΠ»Π΅Ρ‚Π°Ρ‚Π° ΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΈΠΌ към Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ Ρ‚ΠΈΠΏΠΎΠ²Π΅, ΠΊΠ°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ функцията json_populate_recordset:

SELECT
  *
FROM
  json_populate_recordset(
    NULL::pg_class
  , $1::json -- $1 : '[{"relname":"pg_class","oid":1262},{"relname":"pg_namespace","oid":2615}]'
  );

json_to_recordset

А Ρ‚Π°Π·ΠΈ функция просто Β«Ρ€Π°Π·Π²ΠΈΠ²Π°Β» прСдадСния масив ΠΎΡ‚ ΠΎΠ±Π΅ΠΊΡ‚ΠΈ Π² ΠΈΠ·Π±ΠΎΡ€Π°, Π±Π΅Π· Π΄Π° сС ΠΎΠΏΠΈΡ€Π° Π½Π° Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ‚Π°:

SELECT
  *
FROM
  json_to_recordset($1::json) T(k text, v integer);
-- $1 : '[{"k":"a","v":1},{"k":"b","v":2}]'
k | v
-----
a | 1
b | 2

Π’Π Π•ΠœΠ•ΠΠΠ Π’ΠΠ‘Π›Π˜Π¦Π

Но Π°ΠΊΠΎ ΠΎΠ±Π΅ΠΌΡŠΡ‚ Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π² ΠΏΡ€Π΅Π΄Π°Π΄Π΅Π½Π°Ρ‚Π° ΠΈΠ·Π²Π°Π΄ΠΊΠ° Π΅ ΠΌΠ½ΠΎΠ³ΠΎ голямо, Ρ‚ΠΎ Π΄Π° Π³ΠΎ поставитС Π² Π΅Π΄ΠΈΠ½ сСриализиран ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€ β€” Π΅ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ, Π° понякога ΠΈ нСвъзмоТно, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ изисква Π΅Π΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ Π·Π°Π΄Π΅Π»Π΅Π½ΠΎ голямо количСство ΠΏΠ°ΠΌΠ΅Ρ‚. НапримСр, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ дълго Π΄Π° ΡΡŠΠ±ΠΈΡ€Π°Ρ‚Π΅ голям ΠΏΠ°ΠΊΠ΅Ρ‚ Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ външна систСма ΠΈ слСд Ρ‚ΠΎΠ²Π° искатС Π΄Π° Π³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΈΡ‚Π΅ навСднъТ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

Π’ Ρ‚Π°ΠΊΡŠΠ² случай Π½Π°ΠΉ-Π΄ΠΎΠ±Ρ€ΠΎΡ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ:

CREATE TEMPORARY TABLE tbl(k text, v integer);
...
INSERT INTO tbl(k, v) VALUES($1, $2); -- ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Ρ‚Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡŠΡ‚ΠΈ
...
-- Ρ‚ΡƒΠΊ ΠΏΡ€Π°Π²ΠΈΠΌ Π½Π΅Ρ‰ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ с цялата Ρ‚Π°Π±Π»ΠΈΡ†Π°

Π’ΠΎΠ·ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΅ Π΄ΠΎΠ±ΡŠΡ€ ΠΈΠΌΠ΅Π½Π½ΠΎ Π·Π° рядко ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈ ΠΎΠ±Π΅ΠΌΠΈ Π΄Π°Π½Π½ΠΈ.
ΠžΡ‚ Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° описаниСто Π½Π° структурата Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ си, Π²Ρ€Π΅ΠΌΠ΅Π²Π°Ρ‚Π° Ρ‚Π°Π±Π»ΠΈΡ†Π° сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π° ΠΎΡ‚ 'ΠΎΠ±ΠΈΡ‡Π°ΠΉΠ½Π°Ρ‚Π°' само ΠΏΠΎ Π΅Π΄ΠΈΠ½ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ Π² систСмната Ρ‚Π°Π±Π»ΠΈΡ†Π° pg_class, Π° Π² pg_type, pg_depend, pg_attribute, pg_attrdef, ... β€” ΠΏΠΎ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎ Π½Π΅ сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π°.

Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΎ, Π² ΡƒΠ΅Π± систСми с ΠΌΠ½ΠΎΠ³ΠΎ ΠΊΡ€Π°Ρ‚ΠΊΠΎΡ‚Ρ€Π°ΠΉΠ½ΠΈ Π²Ρ€ΡŠΠ·ΠΊΠΈ Π·Π° всяка ΠΎΡ‚ тях Ρ‚Π°ΠΊΠ°Π²Π° Ρ‚Π°Π±Π»ΠΈΡ†Π° Ρ‰Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° Π½ΠΎΠ²ΠΈ систСмни записи всСки ΠΏΡŠΡ‚, ΠΊΠΎΠΈΡ‚ΠΎ сС ΠΈΠ·Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ ΠΏΡ€ΠΈ затварянСто Π½Π° Π²Ρ€ΡŠΠ·ΠΊΠ°Ρ‚Π° с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ. Π’ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° Ρ‚ΠΎΠ²Π°, Π½Π΅ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° TEMP TABLE Π²ΠΎΠ΄ΠΈ Π΄ΠΎ β€žΡ€Π°Π·ΡˆΠΈΡ€ΡΠ²Π°Π½Π΅β€œ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†ΠΈΡ‚Π΅ Π² pg_catalog ΠΈ забавянС Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π³ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚.
Π Π°Π·Π±ΠΈΡ€Π° сС, с Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π±ΠΎΡ€ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ΠΈΡ‡Π΅Π½ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ VACUUM FULL ΠΏΡ€Π΅Π· Ρ‚Π°Π±Π»ΠΈΡ†ΠΈΡ‚Π΅ Π½Π° систСмния ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³.

БСсийни ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ

Π”Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ случай Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ слоТна Π·Π° Π΅Π΄ΠΈΠ½ SQL Π·Π°ΠΏΠΈΡ‚, Π½ΠΎ искамС Π΄Π° я ΠΏΡ€Π°Π²ΠΈΠΌ доста чСсто. ВоСст, искамС Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π² DO Π±Π»ΠΎΠΊΠ°, Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΏΡ€Π΅Π· Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ Ρ‰Π΅ бъдС Ρ‚Π²ΡŠΡ€Π΄Π΅ скъпо.

НС ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ $n Π·Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π² анонимния Π±Π»ΠΎΠΊ. Π Π΅ΡˆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ сСсийнитС ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ ΠΈ функцията current_setting.

Π”ΠΎ вСрсия 9.2 бСшС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° сС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π° спСциално пространство ΠΎΡ‚ ΠΈΠΌΠ΅Π½Π° custom_variable_classes Π·Π° β€žΡΠΎΠ±ΡΡ‚Π²Π΅Π½ΠΈβ€œ сСсийни ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ. Π’ Π°ΠΊΡ‚ΡƒΠ°Π»Π½ΠΈΡ‚Π΅ вСрсии ΠΎΠ±Π°Ρ‡Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Π½Π΅Ρ‰ΠΎ Ρ‚Π°ΠΊΠΎΠ²Π°:

SET my.val = '{1,2,3}';
DO $$
DECLARE
  id integer;
BEGIN
  FOR id IN (SELECT unnest(current_setting('my.val')::integer[])) LOOP
    RAISE NOTICE 'id : %', id;
  END LOOP;
END;
$$ LANGUAGE plpgsql;
-- NOTICE:  id : 1
-- NOTICE:  id : 2
-- NOTICE:  id : 3

Π’ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½ΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π½ΠΈ Π΅Π·ΠΈΡ†ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ.

Π—Π½Π°Π΅Ρ‚Π΅ Π»ΠΈ ΠΎΡ‰Π΅ Π½Π°Ρ‡ΠΈΠ½ΠΈ? Π‘ΠΏΠΎΠ΄Π΅Π»Π΅Ρ‚Π΅ Π² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅!

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster