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


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

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';