Zapomniany operator przypisania " = "i pospolite": ="
Dokumentacja dla PL / pgSQL mówi, że deklaracja i przypisanie do zmiennych odbywa się za pomocą :=
.
Ale prosty, krótszy i bardziej nowoczesny (patrz przypis)=
wydaje się działać zgodnie z oczekiwaniami:
CREATE OR REPLACE FUNCTION foo() RETURNS int AS $$
DECLARE
i int;
BEGIN
i = 0;
WHILE NOT i = 25 LOOP
i = i + 1;
i = i * i;
END LOOP;
RETURN i;
END;
$$ LANGUAGE plpgsql;
> SELECT foo();
25
Należy pamiętać, że Pl / pgSQL może wyraźnie odróżnić przypisanie i porównanie, jak pokazano w linii
WHILE NOT i = 25 LOOP
Więc pytania są następujące:
- czy nie znalazłem jakiejś sekcji w dokumentach, które wspominają i / lub wyjaśniają to?
- czy są jakieś znane konsekwencje używając
=
zamiast:=
?
Edytuj / Przypis:
Proszę wziąć "bardziej nowoczesną" część z przymrużeniem oka, jak w krótka, niekompletna i w większości błędna Historia języków programowania : {11]}
1970-Niklaus Wirth tworzy Pascal, język proceduralny. Krytycy natychmiast wypowiedź Pascala, ponieważ używa składni "x: = X + y" zamiast bardziej znanego C-jak "x = x + y". Ta krytyka dzieje się pomimo faktu to C jeszcze nie zostało wynalezione. 1972-Dennis Ritchie wymyśla potężną broń, która strzela do przodu i do tyłu jednocześnie. Nie zadowolony z liczby zgonów i permanentne okaleczenia z tego wynalazku wymyśla C i Unix.
4 answers
W parserze PL / PgSQL operator przypisania jest zdefiniowany jako
assign_operator : '='
| COLON_EQUALS
;
Jest to funkcja dziedziczona, obecna w kodzie źródłowym od 1998 roku, kiedy została wprowadzona - jak widać w PostgreSQL Git repo .
Począwszy od wersji 9.4 jest to oficjalnie udokumentowane .
Ten idiosynkrazja-posiadania dwóch operatorów dla tego samego - został podniesiony na liście użytkowników pgsql, a niektórzy prosili o jego usunięcie, ale nadal jest trzymany w rdzeniu, ponieważ fair corpus of legacy code opiera się na nim.
Zobacz wiadomość od Toma Lane ' a (głównego programisty Pg) .
Więc odpowiadając na twoje pytania wprost:Czy nie znalazłem jakiejś sekcji w dokumentach, która wspomina i / lub wyjaśnia to?
Nie znalazłeś go, ponieważ był nieudokumentowany, co jest poprawione od wersji 9.4.
Czy są jakieś znane konsekwencje używania = zamiast:=.
Nie ma skutków ubocznych stosowania =, ale powinieneś użyć := do przypisania, aby Twój kod był bardziej czytelny i (jako efekt uboczny) bardziej kompatybilny z PL/SQL.
Aktualizacja: w rzadkich scenariuszach może być poboczna konsekwencja (zobacz odpowiedź Erwina)
Aktualizacja: odpowiedź zaktualizowana dzięki informacjom od Daniela, Sandy i innych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-29 09:21:00
Q1
To zostało w końcu dodane do oficjalnej dokumentacji z Postgres 9.4:
Przypisanie wartości do zmiennej PL / pgSQL jest zapisywane jako:
variable { := | = } expression;
[...] Equal (
=
) może być używany zamiast zgodnego z PL / SQL:=
.
Q2
Czy są jakieś znane konsekwencje używania
=
zamiast:=
?
Tak , miałem sprawę z ciężką consequences: wywołanie funkcji z nazwanymi parametrami - co jest powiązane, ale nie dokładnie to samo.
Ściśle mówiąc, rozróżnienie w tym przypadku dokonuje się w kodzie SQL . Ale to akademickie rozróżnienie od niczego nie podejrzewającego programisty.1
Rozważmy funkcję:
CREATE FUNCTION f_oracle(is_true boolean = TRUE) -- correct use of "="
RETURNS text AS
$func$
SELECT CASE $1
WHEN TRUE THEN 'That''s true.'
WHEN FALSE THEN 'That''s false.'
ELSE 'How should I know?'
END
$func$ LANGUAGE sql;
Na bok: zwróć uwagę na prawidłowe użycie =
w definicji funkcji. To część składni CREATE FUNCTION
- W Stylu SQL przypisanie.2
Wywołanie funkcji z nazwaną notacją :
SELECT * FROM f_oracle(is_true := TRUE);
Postgres identyfikuje :=
jako przypisanie parametrów i wszystko jest dobrze. jednakże :
SELECT * FROM f_oracle(is_true = TRUE);
Od =
jest operatorem równości SQL, Postgres interpretuje is_true = TRUE
jako wyrażenie SQL w kontekście wywołującej instrukcji i próbuje je ocenić przed przekazaniem wyniku jako nienazwany parametr pozycyjny . Poszukuje identyfikator is_true
w zakresie zewnętrznym. Jeśli tego nie można znaleźć:
ERROR: column "is_true" does not exist
To szczęśliwy przypadek i, na szczęście, również ten powszechny.
Kiedy is_true
Można {[66] } znaleźć w zewnętrznym zakresie (i typy danych są kompatybilne), is_true = TRUE
jest poprawnym wyrażeniem z wynikiem boolean
, który jest akceptowany przez funkcję. Nie występuje błąd. Oczywiście jest to intencja programisty używającego SQL Operator równości =
...
To SQL Fiddle demonstruje efekt.
Bardzo trudne do debugowania, jeśli nie jesteś świadomy różnicy między =
i :=
.
zawsze używaj właściwego operatora.
1 podczas używania notacji nazwanej w wywołaniach funkcji , tylko :=
jest prawidłowym operatorem przyporządkowania. Dotyczy to funkcji wszystkich języków, nie tylko PL / pgSQL, do pg 9.4 włącznie. Zobacz też poniżej.
2
Można użyć =
(or DEFAULT
), aby zdefiniować wartości domyślne dla parametrów funkcji. To w żaden sposób nie jest związane z problemem. Jest po prostu niezwykle blisko błędnego przypadku użycia.
:=
na =>
Standard SQL przypisywania do nazwanych parametrów funkcji to =>
(i Oracle PL / SQL używa go . Postgres nie mógł zrobić tego samego, ponieważ operator był wcześniej nieograniczony, używa więc zamiast niego operatora przypisania PL/pgSQL :=
. Wraz z wydaniem Postgres 9.0 użycie =>
do innych celów zostało wycofane. uwagi do wydania :
Przestarzałe użycie = > jako nazwy operatora (Robert Haas)
Przyszłe wersje PostgreSQL prawdopodobnie odrzucą tę nazwę operatora całkowicie, w celu obsługi standardowej notacji SQL dla nazwanych parametry funkcji. Na moment, jest to nadal dozwolone, ale ostrzeżenie jest emitowane, gdy taki operator jest zdefiniowany.
Jeśli powinieneś używać =>
do czegoś innego, przestań. Pęknie w przyszłości.
Postgres 9.5: użyj =>
teraz
Począwszy od tego wydania, standardowy operator SQL=>
jest używany. :=
jest nadal wspierana dla zgodności wstecznej. Ale użyj standardowego operatora w nowym kodzie, który nie musi działać na bardzo starym wersje.
- udokumentowane w podręczniku, rozdział używanie notacji nazwanej.
- oto commit z wyjaśnieniem w GIT.
Dotyczy to przypisania nazwanych parametrów w wywołaniach funkcji (zakres SQL), a nie operatora przypisania :=
w kodzie plpgsql, który pozostaje bez zmian.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-19 13:55:42
Częściowa odpowiedź na moje pytanie:
Sekcja PL/pgSQL uzyskanie statusu wyniku pokazuje dwa przykłady przy użyciu specjalnej składni:
GET DIAGNOSTICS variable = item [ , ... ];
GET DIAGNOSTICS integer_var = ROW_COUNT;
Próbowałem obu :=
i =
i działają oba.
Ale GET DIAGNOSTICS
jest specjalną składnią, więc można argumentować, że nie jest to również normalna operacja przypisania PL / pgSQL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-22 19:38:13
Czytanie dokumentacji Postgresql 9:
Ta strona wymienia "=" jako operator przypisania w tabeli o pierwszeństwie operatora.
Ale o dziwota strona (Dokumentacja operatora przydziału) o tym nie wspomina.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-22 19:00:11