29 paź 2009

Nie używać wielkich liter w nazwach funkcji/procedur składowanych PostgresQL!

Postanowiłem napisać swoją pierwszą procedurę składowaną w PostgreSQL.

Utworzyłem ją za pomocą kreatora w pgAdmin, ale za nic w świecie nie mogłem jej uruchomić.

Każda próba wywołania, kończyła się komunikatem:
No function matches the given name and argument types. You might need to add explicit type casts.

Sprawdziłem, że wywołuję ją w tym samym schemacie (public), w którym jest ona zdefiniowana.

Uprościłem treść procedury do minimum (usunąłem wszystkie parametry) i oto co mi zostało:

CREATE OR REPLACE FUNCTION "InsertEvent"()
  RETURNS integer AS
$BODY$
BEGIN

    RETURN 1;

END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;

A wołam ją tak:
select InsertEvent() AS ret

Nadal ten sam komunikat: nie może znaleźć wołanej procedury!

Minęła godzinka prób... ale zaraz, zaraz... nieco dziwnie to wygląda w definicji:
FUNCTION "InsertEvent"()

czasem pgAdmin wstawia mi cudzysłowia w identyfikatorach - nigdy nie zagłębiałem się dlaczego to robi. Zmieniłem wywołanie na:
select "InsertEvent"() AS ret

Hurrra! Działa!

Gdybym od początku nazwał procedurę nie używając konwencji CamelCase, np. insert_event, to cudzysłowia nie byłyby potrzebne i wszystko by się wykonało za pierwszym razem.

Szczegółowe wyjaśnienie co się stało:
Gdy użyłem nazwy procedury: InsertEvent, pgAdmin utworzył tzw. Quoted identifier, który jest case sensitive.
Dla nazwy: insert_event pgAdmin utworzył zwykły identyfikator, który jest case insensitive.

Więcej o identufikatorach w PostgreSQL tutaj


Wniosek:
Na wszelki wypadek lepiej używać standardowej konwencji nazywania identyfikatorów postgres: wszystkie litery małe rozdzielone znakiem "_". Np. insert_event