Обсуждение: Переменные в БД

Поиск
Список
Период
Сортировка

Переменные в БД

От
Serik
Дата:
Добрый день !
Можно в PostgreSQL объявлять свои переменные , типа client_encoding, timezone и т.д.,
чтобы их значения были видны только одному пользователю в пределах сессии ?

Спасибо.

Re: Переменные в

От
Oleg Bartunov
Дата:
On Sat, 18 Mar 2006, Serik wrote:

> Добрый день !
> Можно в PostgreSQL объявлять свои переменные , типа client_encoding, timezone и т.д.,
> чтобы их значения были видны только одному пользователю в пределах сессии ?

можно, set client_encoding = 'koi8=r';
А можно еще и документацию почитать.
http://www.postgresql.org/docs/8.1/static/sql-set.html

>
> Спасибо.
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
>               http://www.postgresql.org/docs/faq
>

     Regards,
         Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83

Re: Переме

От
"Alexander M. Pravking"
Дата:
On Sat, 2006-03-18 at 14:04 +0300, Oleg Bartunov wrote:
> On Sat, 18 Mar 2006, Serik wrote:
>
> >Добрый день !
> >Можно в PostgreSQL объявлять свои переменные , типа client_encoding,
> >timezone и т.д.,
> >чтобы их значения были видны только одному пользователю в пределах сессии ?
>
> можно, set client_encoding = 'koi8=r';
> А можно еще и документацию почитать.
> http://www.postgresql.org/docs/8.1/static/sql-set.html

Скорее всего, имелись в виду не PG'шные встроенные, а именно
user-defined переменные.

Мне интересна эта тема, поскольку я в своё время не нашёл положительного
ответа на подобный вопрос, однако нашёл другой способ - через создание
временной таблицы, у которой срок жизни - как раз сессия. Однако такой
подход делает нагрузку на системные таблицы (pg_class, pg_attribute),
что иногда заметно сказывается на производительности. Так что было бы
неплохо, если бы в PG появился более стандартный способ.

Привожу функции для управления такими "переменными":


CREATE OR REPLACE FUNCTION get_session_var(text) RETURNS text AS '
DECLARE
    _x    record;
BEGIN
    SELECT    1 INTO _x FROM pg_class
    WHERE    relname = ''session_vars''
    AND    relkind = ''r''
    AND    CASE WHEN has_schema_privilege(relnamespace,''USAGE'')
            THEN pg_table_is_visible(oid)
            ELSE false
        END;

    IF NOT FOUND THEN RETURN NULL; END IF;

    FOR _x IN EXECUTE ''SELECT value FROM session_vars WHERE var = '' || quote_literal($1)
    LOOP
        RETURN _x.value;
    END LOOP;
    RETURN    NULL;
END' LANGUAGE 'plPgSQL' STRICT;


CREATE OR REPLACE FUNCTION set_session_var(text, text) RETURNS text AS '
DECLARE
    _x    integer;
BEGIN
    SELECT    1 INTO _x FROM pg_class
    WHERE    relname = ''session_vars''
    AND    relkind = ''r''
    AND    CASE WHEN has_schema_privilege(relnamespace,''USAGE'')
            THEN pg_table_is_visible(oid)
            ELSE false
        END;

    IF NOT FOUND THEN
        EXECUTE ''CREATE TEMP TABLE session_vars (var text, value text) WITHOUT OIDS'';
    ELSE
        EXECUTE ''DELETE FROM session_vars WHERE var = ''||quote_literal($1);
    END IF;
    EXECUTE ''INSERT INTO session_vars VALUES ('' ||
        quote_literal($1) || '', '' || coalesce(quote_literal($2), ''NULL'') ||
        '')'';
    RETURN $2;
END' LANGUAGE 'plPgSQL';



Замечу также, что проверка pg_table_is_visible() без has_schema_privilege()
в функциях недостаточна, на этот счёт я уже писал в -hackers:

http://archives.postgresql.org/pgsql-hackers/2005-06/msg00319.php


--
Fduch M. Pravking

Re: Переме

От
Андрей Зевакин
Дата:
Alexander M. Pravking пишет:
On Sat, 2006-03-18 at 14:04 +0300, Oleg Bartunov wrote: 
On Sat, 18 Mar 2006, Serik wrote:
   
Добрый день !
Можно в PostgreSQL объявлять свои переменные , типа client_encoding, 
timezone и т.д.,
чтобы их значения были видны только одному пользователю в пределах сессии ?     
можно, set client_encoding = 'koi8=r';
А можно еще и документацию почитать.
http://www.postgresql.org/docs/8.1/static/sql-set.html   
Скорее всего, имелись в виду не PG'шные встроенные, а именно
user-defined переменные.

Мне интересна эта тема, поскольку я в своё время не нашёл положительного
ответа на подобный вопрос, однако нашёл другой способ - через создание
временной таблицы, у которой срок жизни - как раз сессия. Однако такой
подход делает нагрузку на системные таблицы (pg_class, pg_attribute),
что иногда заметно сказывается на производительности. Так что было бы
неплохо, если бы в PG появился более стандартный способ.

Привожу функции для управления такими "переменными":


CREATE OR REPLACE FUNCTION get_session_var(text) RETURNS text AS '
DECLARE_x	record;
BEGINSELECT	1 INTO _x FROM pg_classWHERE	relname = ''session_vars''AND	relkind = ''r''AND	CASE WHEN has_schema_privilege(relnamespace,''USAGE'')		THEN pg_table_is_visible(oid)		ELSE false	END;
IF NOT FOUND THEN RETURN NULL; END IF;
FOR _x IN EXECUTE ''SELECT value FROM session_vars WHERE var = '' || quote_literal($1)LOOP	RETURN _x.value;END LOOP;RETURN	NULL;
END' LANGUAGE 'plPgSQL' STRICT;


CREATE OR REPLACE FUNCTION set_session_var(text, text) RETURNS text AS '
DECLARE_x	integer;
BEGINSELECT	1 INTO _x FROM pg_classWHERE	relname = ''session_vars''AND	relkind = ''r''AND	CASE WHEN has_schema_privilege(relnamespace,''USAGE'')		THEN pg_table_is_visible(oid)		ELSE false	END;
IF NOT FOUND THEN	EXECUTE ''CREATE TEMP TABLE session_vars (var text, value text) WITHOUT OIDS'';ELSE	EXECUTE ''DELETE FROM session_vars WHERE var = ''||quote_literal($1);END IF;EXECUTE ''INSERT INTO session_vars VALUES ('' ||	quote_literal($1) || '', '' || coalesce(quote_literal($2), ''NULL'') ||	'')'';RETURN $2;
END' LANGUAGE 'plPgSQL';



Замечу также, что проверка pg_table_is_visible() без has_schema_privilege()
в функциях недостаточна, на этот счёт я уже писал в -hackers:

http://archives.postgresql.org/pgsql-hackers/2005-06/msg00319.php

 
чтобы не нагружать системные таблицы, можно сделать так:

CREATE TABLE session_vars
(
    username name NOT NULL DEFAULT current_user,
    var text NOT NULL,
    value text NOT NULL,
    PRIMARY KEY (username, var)
) WITHOUT OIDS;


CREATE OR REPLACE FUNCTION get_session_var(text) RETURNS text AS
'
    SELECT value FROM session_vars WHERE username = current_user AND var = $1;
'
LANGUAGE 'sql';


CREATE OR REPLACE FUNCTION set_session_var(text, text) RETURNS text AS
'
DECLARE
    _var ALIAS FOR $1;
    _value ALIAS FOR $2;
BEGIN
    IF get_session_var(_var) IS NULL THEN
        INSERT INTO session_vars VALUES (DEFAULT, _var, _value);
    ELSE
        UPDATE session_vars SET value = _value WHERE username = current_user AND var = _var;
    END IF;
    RETURN _value;
END;
'
  LANGUAGE 'plpgsql';

Re: Переме

От
Oleg Bartunov
Дата:
On Sun, 19 Mar 2006, Alexander M. Pravking wrote:

> On Sat, 2006-03-18 at 14:04 +0300, Oleg Bartunov wrote:
>> On Sat, 18 Mar 2006, Serik wrote:
>>
>>> Добрый день !
>>> Можно в PostgreSQL объявлять свои переменные , типа client_encoding,
>>> timezone и т.д.,
>>> чтобы их значения были видны только одному пользователю в пределах сессии ?
>>
>> можно, set client_encoding = 'koi8=r';
>> А можно еще и документацию почитать.
>> http://www.postgresql.org/docs/8.1/static/sql-set.html
>
> Скорее всего, имелись в виду не PG'шные встроенные, а именно
> user-defined переменные.

не уверен, но по твоей теме был тред

http://www.pgsql.ru/db/pgsearch/index.html?group=1&page=1&site=archives.postgresql.org%2F&tmpl=%F0%D2%C9%D7%C5%D4&q=session%20variables&ps=10
Там через view реализовано

>
> Мне интересна эта тема, поскольку я в своё время не нашёл положительного
> ответа на подобный вопрос, однако нашёл другой способ - через создание
> временной таблицы, у которой срок жизни - как раз сессия. Однако такой
> подход делает нагрузку на системные таблицы (pg_class, pg_attribute),
> что иногда заметно сказывается на производительности. Так что было бы
> неплохо, если бы в PG появился более стандартный способ.
>
> Привожу функции для управления такими "переменными":
>
>
> CREATE OR REPLACE FUNCTION get_session_var(text) RETURNS text AS '
> DECLARE
>     _x    record;
> BEGIN
>     SELECT    1 INTO _x FROM pg_class
>     WHERE    relname = ''session_vars''
>     AND    relkind = ''r''
>     AND    CASE WHEN has_schema_privilege(relnamespace,''USAGE'')
>             THEN pg_table_is_visible(oid)
>             ELSE false
>         END;
>
>     IF NOT FOUND THEN RETURN NULL; END IF;
>
>     FOR _x IN EXECUTE ''SELECT value FROM session_vars WHERE var = '' || quote_literal($1)
>     LOOP
>         RETURN _x.value;
>     END LOOP;
>     RETURN    NULL;
> END' LANGUAGE 'plPgSQL' STRICT;
>
>
> CREATE OR REPLACE FUNCTION set_session_var(text, text) RETURNS text AS '
> DECLARE
>     _x    integer;
> BEGIN
>     SELECT    1 INTO _x FROM pg_class
>     WHERE    relname = ''session_vars''
>     AND    relkind = ''r''
>     AND    CASE WHEN has_schema_privilege(relnamespace,''USAGE'')
>             THEN pg_table_is_visible(oid)
>             ELSE false
>         END;
>
>     IF NOT FOUND THEN
>         EXECUTE ''CREATE TEMP TABLE session_vars (var text, value text) WITHOUT OIDS'';
>     ELSE
>         EXECUTE ''DELETE FROM session_vars WHERE var = ''||quote_literal($1);
>     END IF;
>     EXECUTE ''INSERT INTO session_vars VALUES ('' ||
>         quote_literal($1) || '', '' || coalesce(quote_literal($2), ''NULL'') ||
>         '')'';
>     RETURN $2;
> END' LANGUAGE 'plPgSQL';
>
>
>
> Замечу также, что проверка pg_table_is_visible() без has_schema_privilege()
> в функциях недостаточна, на этот счёт я уже писал в -hackers:
>
> http://archives.postgresql.org/pgsql-hackers/2005-06/msg00319.php
>
>
>

     Regards,
         Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83