PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

PostgreSQL - Писане на динамичен sql в съхранена процедура, която връща набор от резултати

Има място за подобрения:

CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
                                                   , ends_with   text = NULL)
  RETURNS SETOF lookups.countries AS
$func$
DECLARE
   sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
   IF ends_with IS NOT NULL THEN
      sql := sql || ' AND country_name <= $2';
   END IF;

   RETURN QUERY EXECUTE sql
   USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
-- the rest is default settings

Основни точки

  • PostgreSQL 8.4 въведе USING клауза за EXECUTE , което е полезно по няколко причини. Резюме в ръководството:

    Командният низ може да използва стойности на параметри, които са посочени в командата като $1, $2 и т.н. Тези символи се отнасят до стойности, предоставени в USING клауза. Този метод често е за предпочитане пред вмъкването на стойности на данни в командния низ като текст:той избягва излишните разходи по време на изпълнение за преобразуване на стойностите в текст и обратно и е много по-малко податлив на атаки с инжектиране на SQL, тъй като няма нужда от цитиране или избягване.

    IOW, това е по-безопасно и по-бързо от изграждането на низ на заявка с текстово представяне на параметрите, дори когато е дезинфекциран с quote_literal() .
    Обърнете внимание, че $1, $2 в низа на заявката се отнасят до предоставените стойности в USING клауза, не към параметрите на функцията.

  • Докато връщате SELECT * FROM lookups.countries , можете да опростите RETURN декларация, както е показано:

    RETURNS SETOF lookups.countries
    

    В PostgreSQL има съставен тип, дефиниран автоматично за всяка таблица. Използваи го. Ефектът е, че функцията зависи от типа и получавате съобщение за грешка, ако се опитате да промените таблицата. Пуснете и създайте отново функцията в такъв случай.

    Това може да е желателно или не - като цяло е така! Искате да сте наясно със страничните ефекти, ако промените таблиците. По начина, по който го имате, вашата функция ще се счупи безшумно и ще предизвика изключение при следващото си извикване.

  • Ако предоставите изрична настройка по подразбиране за втория параметър в декларацията, както е показано, можете (но не е необходимо) да опростите извикването, в случай че не искате да зададете горна граница с ends_with .

    SELECT * FROM report_get_countries_new('Zaire');
    

    вместо:

    SELECT * FROM report_get_countries_new('Zaire', NULL);
    

    Имайте предвид претоварването на функциите в този контекст.

  • Не цитирайте името на езика 'plpgsql' дори и това да се толерира (засега). Това е идентификатор.

  • Можете да зададете променлива по време на декларация. Спестява допълнителна стъпка.

  • Параметрите са наименувани в заглавката. Изхвърлете безсмислените редове:

     starts_with ALIAS FOR $1;
     ends_with ALIAS FOR $2;
    


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL 9.3:Динамична въртяща се таблица

  2. Как Sinh() работи в PostgreSQL

  3. Как да променя формата на датата в Postgres?

  4. Как работи Ceiling() в PostgreSQL

  5. КАСКАДНО ИЗТРИВАНЕ само веднъж