powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / [игнор отключен] [закрыт для гостей] / RLS
14 сообщений из 14, страница 1 из 1
RLS
    #36719984
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возникла проблема с RLS вида "У пользователя недостаточно прав для на исполнение операции над базой данных". Исходная ситуация такая:

1. Самописная конфигурация.
2. Стандартная модель трехзвенной ИС (клиент 1С - сервер 1С - сервер СУБД).
3. Платформа 1С Предприятие 8.1.15.14.
4. Сервер СУБД - MS SQL 2005 EE SP3 x86.
5. Объектом, в отношении которого используются RLS, является документ "Договор". Задача - ограничить выборку договоров по подразделениям, разрешенным пользователю.
6. Для ограничения доступа используются справочник "Подразделения" с иерархией элементов, по которым собственно и ограничивается выборка договоров, и регистр сведений "ПраваДоступаПользователейКОбъектам", скопированный из типовых конфигураций 1С.
7. На прикладном уровне в регистре сведений по пользователю указывается филиал, по которому выборка договоров должна быть ограничена, а также уровень доступа, по которому производится ограничение - "Чтение", "Добавление", "Изменение". Т.е. пользователь должен видеть только те договора, в которых указанный филиал совпадает с филиалом, указанным в его настройках в регистре сведений. Пользователь должен также видеть все договора, в которых подразделения подчиняются по иерархии элементов филиалу.

Все эти средства ограничения доступа частично скопированы с типовых конфигураций 1С (УПП), а частично написаны самостоятельно.

Приведу конкретный пример ограничения RLS, установленного на право "Чтение" документа "Договор":

Код: plaintext
<Прочие поля>|ГДЕ ВладелецДоговора В(&ПодразделенияПользователяНаЧтение)

где:
ВладелецДоговора - СправочникСсылка.Подразделения.
&ПодразделенияПользователяНаЧтение - параметр сеанса, заполняемый фиксированным массивом подразделений. Массив разрешенных подразделений ПриНачалеРаботыСистемы() вычисляется своими запросома, плюс туда же добавляется само подразделение, указанное в РС.

После всех этих прелюдий - внимание, проблема!

Пользователю необходимо провести договор "задним числом". Но он не может этого сделать и обращается ко мне. Вот что накопал я в отладчике:
1. Если пользователь пытается ЗАПИСАТЬ или ПРОВЕСТИ новый документ с датой, меньшей, чем текущая, то платформа выдает сообщение "У пользователя недостаточно прав...".
2. Если пользователь пытается ЗАПИСАТЬ или ПРОВЕСТИ новый документ с датой, равной текущей, то все проходит нормально.
3. Если пользователь открывает документ, сохраненный в предыдущем пункте, и меняет текущую дату на дату "заднего числа", то документ записывается и проводится нормально.

Поэтому возник вопрос - причем тут дата? Расследование в отладчике показало, что сообщение "У пользователя..." платформа выдает еще до исполнения события формы ПередЗаписью(). И вот тут начинается самое интересное! Профайлером был отловлен запрос, который платформа выдает сиквелу еще до исполнения события формы ПередЗаписью().

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
USE ERD_Tkachev_Test
GO
SELECT TOP  1  -- оригинальный код
--SELECT -- тестовый код
_Document68._Date_Time AS f_2,
_Document68._IDRRef AS f_3,
CASE
	WHEN _Document68._Date_Time = _Document68._Date_Time OR _Document68._Date_Time IS NULL
	THEN CASE
			WHEN _Document68._Fld158RRef IN
				(0x80b5005056ba478d11ddb7ad21770184,
				 0x80b5005056ba478d11ddbb7fccf5cdcb,
				 0x86bd001a64d2aaa411dd84bd411085cf,
				 0x86bd001a64d2aaa411dd84bd4f124afa,
				 0x86bd001a64d2aaa411dd96c5f74fe645,
				 0x86bd001a64d2aaa411dd96c5f74fe646,
				 0x86bd001a64d2aaa411dd96c5f74fe647,
				 0x86bd001a64d2aaa411dd96c5f74fe648,
				 0x86bd001a64d2aaa411dd96c5f74fe649,
				 0x86bd001a64d2aaa411dd96c5f74fe64a,
				 0x86bd001a64d2aaa411dd96c5f74fe64b,
				 0x86bd001a64d2aaa411dd96c5f74fe64c,
				 0x86bd001a64d2aaa411dd96c5f74fe64d,
				 0x86bd001a64d2aaa411dd96c5f74fe64e,
				 0x86bd001a64d2aaa411dd96c5f74fe64f,
				 0x86bd001a64d2aaa411dd96c5f74fe650,
				 0x86bd001a64d2aaa411dd96c5f74fe651,
				 0x86bd001a64d2aaa411dd96c5f74fe652,
				 0x86bd001a64d2aaa411dd96c5f74fe653,
				 0x86bd001a64d2aaa411dd96c5f74fe654,
				 0x86bd001a64d2aaa411dd96c5f74fe655,
				 0x86bd001a64d2aaa411dd96c5f74fe656,
				 0x86bd001a64d2aaa411dd96c5f74fe657,
				 0x86bd001a64d2aaa411dd96c5f74fe658,
				 0x86bd001a64d2aaa411dd96c5f74fe659,
				 0x86bd001a64d2aaa411dd96c5f74fe65a,
				 0x86bd001a64d2aaa411ddab267bb46cc5,
				 0x892c16cebccad18f45f780a5f028816e,
				 0x97ef005056ba636711deeefda38490b2,
				 0x97ef005056ba636711deeefda38490b5,
				 0x97ef005056ba636711deeefda38490b6,
				 0x97ef005056ba636711deeefda38490c1,
				 0x97ef005056ba636711deeefda38490cc,
				 0xb7b6000d6055887311dd98e91c9f1485,
				 0xba70005056ba478d11dea10fdbd475b0)
			THEN  0 
			ELSE  2000000000  -- оригинальный код
			--ELSE 2000000000.0 -- тестовый код
			END
	+  2000000000  -- оригинальный код
	--+ 2000000000.0 -- тестовый код
	END AS _f_1
FROM
_Document68 WITH(NOLOCK)
WHERE
	(
	 _Document68._Date_Time > {ts '2010-06-04 00:00:00'}
  OR _Document68._Date_Time = {ts '2010-06-04 00:00:00'}
 AND _Document68._IDRRef > 0x00000000000000000000000000000000
	)
 AND _Document68._Date_Time <= {ts '2010-06-04 23:59:59'}
 AND _Document68._IDRRef <> 0x00000000000000000000000000000000
ORDER BY
_Document68._Date_Time DESC,
_Document68._IDRRef DESC
...
Рейтинг: 0 / 0
RLS
    #36720178
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большой список уникальных идентификаторов подразделений, перечисленный в запросе - это тот самый фиксированный массив разрешенных пользователю подразделений. При этом попытка выполнить этот запрос непосредственно на сиквеле вызывает такую ошибку:

Код: plaintext
1.
[color=red]Сообщение  8115 , уровень  16 , состояние  2 , строка  1 
Ошибка арифметического переполнения при преобразовании expression к типу данных int.[/color]

Насколько я понял, ошибка возникает в случае, когда сиквел во внутреннем
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
CASE
			WHEN _Document68._Fld158RRef IN
				(0x80b5005056ba478d11ddb7ad21770184,
				 0x80b5005056ba478d11ddbb7fccf5cdcb,
				 0x86bd001a64d2aaa411dd84bd411085cf,
				 0x86bd001a64d2aaa411dd84bd4f124afa,
				 0x86bd001a64d2aaa411dd96c5f74fe645,
				 0x86bd001a64d2aaa411dd96c5f74fe646,
				 0x86bd001a64d2aaa411dd96c5f74fe647,
				 0x86bd001a64d2aaa411dd96c5f74fe648,
				 0x86bd001a64d2aaa411dd96c5f74fe649,
				 0x86bd001a64d2aaa411dd96c5f74fe64a,
				 0x86bd001a64d2aaa411dd96c5f74fe64b,
				 0x86bd001a64d2aaa411dd96c5f74fe64c,
				 0x86bd001a64d2aaa411dd96c5f74fe64d,
				 0x86bd001a64d2aaa411dd96c5f74fe64e,
				 0x86bd001a64d2aaa411dd96c5f74fe64f,
				 0x86bd001a64d2aaa411dd96c5f74fe650,
				 0x86bd001a64d2aaa411dd96c5f74fe651,
				 0x86bd001a64d2aaa411dd96c5f74fe652,
				 0x86bd001a64d2aaa411dd96c5f74fe653,
				 0x86bd001a64d2aaa411dd96c5f74fe654,
				 0x86bd001a64d2aaa411dd96c5f74fe655,
				 0x86bd001a64d2aaa411dd96c5f74fe656,
				 0x86bd001a64d2aaa411dd96c5f74fe657,
				 0x86bd001a64d2aaa411dd96c5f74fe658,
				 0x86bd001a64d2aaa411dd96c5f74fe659,
				 0x86bd001a64d2aaa411dd96c5f74fe65a,
				 0x86bd001a64d2aaa411ddab267bb46cc5,
				 0x892c16cebccad18f45f780a5f028816e,
				 0x97ef005056ba636711deeefda38490b2,
				 0x97ef005056ba636711deeefda38490b5,
				 0x97ef005056ba636711deeefda38490b6,
				 0x97ef005056ba636711deeefda38490c1,
				 0x97ef005056ba636711deeefda38490cc,
				 0xb7b6000d6055887311dd98e91c9f1485,
				 0xba70005056ba478d11dea10fdbd475b0)
			THEN  0 
			ELSE  2000000000  -- оригинальный код
			--ELSE 2000000000.0 -- тестовый код
			END
попадает на ELSE и приравнивает результат к 2 млрд. Далее, выйдя из внутреннего CASE во внешний, он выполняет инструкцию
Код: plaintext
1.
	+  2000000000  -- оригинальный код
, и в результате у него получается 4 млрд. Однако, видимо по умолчанию он считает результат типа int, а int должен принимать значения от -2 млрд. до +2 млрд.

Для проверки этой теории я принудительно задал числовой тип с плавающей запятой, закомментировав строки с тегом "оригинальный код" и раскомментировав строки с "тестовый код". Результат выборки такой:

2010-06-04 15:31:51.000 0x90C1005056BA636711DF72D87102A470 4000000000.02010-06-04 15:31:50.000 0x90C1005056BA636711DF72D87102A46C 4000000000.02010-06-04 15:31:49.000 0x8D1D005056BA636711DF6FAEAA313EB1 4000000000.02010-06-04 14:39:22.000 0x8D1D005056BA636711DF6FAEAA313EA4 4000000000.02010-06-04 14:26:12.000 0x8D1D005056BA636711DF6FAEAA313E9E 4000000000.02010-06-04 14:24:10.000 0x8268005056BA1CA711DF6FB4C56972FA 4000000000.02010-06-04 14:23:06.000 0x8268005056BA1CA711DF6FB4C56972F8 4000000000.02010-06-04 14:21:46.000 0x8268005056BA1CA711DF6FB4C56972F6 4000000000.02010-06-04 14:20:02.000 0x8268005056BA1CA711DF6FB4C56972F4 4000000000.02010-06-04 14:18:26.000 0x8268005056BA1CA711DF6FB4C56972F2 4000000000.02010-06-04 12:05:46.000 0x8D1D005056BA636711DF6FAEAA313E9A 4000000000.02010-06-04 12:04:04.000 0x8D1D005056BA636711DF6FAEAA313E96 4000000000.02010-06-04 11:58:33.000 0x8D1D005056BA636711DF6FAEAA313E8D 4000000000.02010-06-04 11:56:22.000 0x8D1D005056BA636711DF6FAEAA313E89 4000000000.02010-06-04 11:27:40.000 0x8268005056BA1CA711DF6FAA199F5974 4000000000.02010-06-04 11:01:42.000 0x8268005056BA1CA711DF6FA7071384A8 2000000000.02010-06-04 10:41:12.000 0x8268005056BA1CA711DF6F9C5F665573 4000000000.02010-06-04 10:36:56.000 0x8268005056BA1CA711DF6F9C5F665571 4000000000.02010-06-04 10:32:39.000 0x8268005056BA1CA711DF6F9C5F66556F 4000000000.02010-06-04 10:24:29.000 0x8268005056BA1CA711DF6F9C5F66556B 4000000000.02010-06-04 10:23:56.000 0x8268005056BA1CA711DF6F9C5F66556A 4000000000.02010-06-04 10:23:27.000 0x8268005056BA1CA711DF6F9C5F665569 4000000000.02010-06-04 09:46:46.000 0x8268005056BA1CA711DF6F9C5F665565 4000000000.02010-06-04 09:46:14.000 0x8268005056BA1CA711DF6F9C5F665564 4000000000.02010-06-04 09:45:25.000 0x8268005056BA1CA711DF6F9C5F665563 4000000000.02010-06-04 00:00:00.000 0x8D1D005056BA636711DF6FAEAA313E91 4000000000.0

Представленный список - это выборка СУЩЕСТВУЮЩИХ перед вставкой нового документа в базу договоров. Причем только один из них был введен по разрешенному пользователю подразделению (_f_1 = 2000000000.0). Т.е. 25 из 26 полученных договоров вызовут арифметическое переполнение. Но вот что меня удивляет и чего я не понимаю:

1. Почему запрос RLS
Код: plaintext
<Прочие поля>|ГДЕ ВладелецДоговора В(&ПодразделенияПользователяНаЧтение)
выразился в конечном итоге во внутренний CASE с условием
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
WHEN _Document68._Fld158RRef IN
				(0x80b5005056ba478d11ddb7ad21770184,
				 0x80b5005056ba478d11ddbb7fccf5cdcb,
				 0x86bd001a64d2aaa411dd84bd411085cf,
				 0x86bd001a64d2aaa411dd84bd4f124afa,
				 0x86bd001a64d2aaa411dd96c5f74fe645,
				 0x86bd001a64d2aaa411dd96c5f74fe646,
				 0x86bd001a64d2aaa411dd96c5f74fe647,
				 0x86bd001a64d2aaa411dd96c5f74fe648,
				 0x86bd001a64d2aaa411dd96c5f74fe649,
				 0x86bd001a64d2aaa411dd96c5f74fe64a,
				 0x86bd001a64d2aaa411dd96c5f74fe64b,
				 0x86bd001a64d2aaa411dd96c5f74fe64c,
				 0x86bd001a64d2aaa411dd96c5f74fe64d,
				 0x86bd001a64d2aaa411dd96c5f74fe64e,
				 0x86bd001a64d2aaa411dd96c5f74fe64f,
				 0x86bd001a64d2aaa411dd96c5f74fe650,
				 0x86bd001a64d2aaa411dd96c5f74fe651,
				 0x86bd001a64d2aaa411dd96c5f74fe652,
				 0x86bd001a64d2aaa411dd96c5f74fe653,
				 0x86bd001a64d2aaa411dd96c5f74fe654,
				 0x86bd001a64d2aaa411dd96c5f74fe655,
				 0x86bd001a64d2aaa411dd96c5f74fe656,
				 0x86bd001a64d2aaa411dd96c5f74fe657,
				 0x86bd001a64d2aaa411dd96c5f74fe658,
				 0x86bd001a64d2aaa411dd96c5f74fe659,
				 0x86bd001a64d2aaa411dd96c5f74fe65a,
				 0x86bd001a64d2aaa411ddab267bb46cc5,
				 0x892c16cebccad18f45f780a5f028816e,
				 0x97ef005056ba636711deeefda38490b2,
				 0x97ef005056ba636711deeefda38490b5,
				 0x97ef005056ba636711deeefda38490b6,
				 0x97ef005056ba636711deeefda38490c1,
				 0x97ef005056ba636711deeefda38490cc,
				 0xb7b6000d6055887311dd98e91c9f1485,
				 0xba70005056ba478d11dea10fdbd475b0)
, а не в условие WHERE внешней части запроса (туда же, где и проверки на входимость в дату "заднего числа" документа)?
2. Как договора с неразрешенными подразделениями оказались в выборке? По моим расчетам, там должен был оказаться только один договор
2010-06-04 11:01:42.000 0x8268005056BA1CA711DF6FA7071384A8 2000000000.0
3. И почему платформа посылает этот запрос ДО записи в базу данных? Это точно, потому что я профайлером отлавливал все запросы, приходящие к СУБД от момента нажатия кнопки "Записать" в форме до момента исполнения обработчика события ПередЗаписью() формы документа?

Отлавливая все запросы при записи документа в текущей дате, все происходит нормальным образом (все обработчики обрабатывают успешно, отказов никто не дает, кроме того, неинтересные места пропущены), т.е.:
1. Выполняется обработчик события формы документа ПередЗаписью().
2. Выполняется обработчик события формы документа ПриЗаписи().
3. На сиквеле выполняется команда BEGIN TRANSACTION (платформа неявно начинает транзакцию, т.к. управление блокировками документа - автоматически).
4. Выполняется обработчик события модуля документа ПередЗаписью().
5. На сиквеле выполняется команда INSERT INTO _Document68 WITH(REPEATABLEREAD) и в таблицу документа заносятся все его данные.
6. Выполняется такой вот интересный запрос:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
SELECT
CAST(COUNT(*) AS NUMERIC( 10 , 0 )) AS f_3
FROM
_Document68 WITH(REPEATABLEREAD)
WHERE
	 _Document68._IDRRef IN (0xB8E9005056BA1CA711DF85CA4BEB8AAF)
 AND CASE
		WHEN _Document68._IDRRef IN (0xb8e9005056ba1ca711df85ca4beb8aaf)
		THEN
			CASE
				WHEN _Document68._Fld158RRef IN
					(0x80b5005056ba478d11ddb7ad21770184,
					 0x80b5005056ba478d11ddbb7fccf5cdcb,
					 0x86bd001a64d2aaa411dd84bd411085cf,
					 0x86bd001a64d2aaa411dd84bd4f124afa,
					 0x86bd001a64d2aaa411dd96c5f74fe645,
					 0x86bd001a64d2aaa411dd96c5f74fe646,
					 0x86bd001a64d2aaa411dd96c5f74fe647,
					 0x86bd001a64d2aaa411dd96c5f74fe648,
					 0x86bd001a64d2aaa411dd96c5f74fe649,
					 0x86bd001a64d2aaa411dd96c5f74fe64a,
					 0x86bd001a64d2aaa411dd96c5f74fe64b,
					 0x86bd001a64d2aaa411dd96c5f74fe64c,
					 0x86bd001a64d2aaa411dd96c5f74fe64d,
					 0x86bd001a64d2aaa411dd96c5f74fe64e,
					 0x86bd001a64d2aaa411dd96c5f74fe64f,
					 0x86bd001a64d2aaa411dd96c5f74fe650,
					 0x86bd001a64d2aaa411dd96c5f74fe651,
					 0x86bd001a64d2aaa411dd96c5f74fe652,
					 0x86bd001a64d2aaa411dd96c5f74fe653,
					 0x86bd001a64d2aaa411dd96c5f74fe654,
					 0x86bd001a64d2aaa411dd96c5f74fe655,
					 0x86bd001a64d2aaa411dd96c5f74fe656,
					 0x86bd001a64d2aaa411dd96c5f74fe657,
					 0x86bd001a64d2aaa411dd96c5f74fe658,
					 0x86bd001a64d2aaa411dd96c5f74fe659,
					 0x86bd001a64d2aaa411dd96c5f74fe65a,
					 0x86bd001a64d2aaa411ddab267bb46cc5,
					 0x892c16cebccad18f45f780a5f028816e,
					 0x97ef005056ba636711deeefda38490b2,
					 0x97ef005056ba636711deeefda38490b5,
					 0x97ef005056ba636711deeefda38490b6,
					 0x97ef005056ba636711deeefda38490c1,
					 0x97ef005056ba636711deeefda38490cc,
					 0xb7b6000d6055887311dd98e91c9f1485,
					 0xba70005056ba478d11dea10fdbd475b0)
				THEN  0 
				ELSE  2000000000 
				END +  2000000000 
		ELSE  0 
		END =  2000000000 
, где 0xB8E9005056BA1CA711DF85CA4BEB8AAF - идентификатор только что созданного документа.
Вот тут, как я понял, еще раз выполняется проверка RLS, наверное, на право добавить новый договор, и опять мы проверяем входимость подразделения договора в список разрешенных.
7. Выполняется обработчик ПриЗаписи().
8. На сиквеле выполняется команда COMMIT TRANSACTION.
...
Рейтинг: 0 / 0
RLS
    #36720207
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще маленькое дополнение к теме. Я читал в интернете, что RLS-ные запросы по-разному выполняются в зависимости от версии сиквела (2000 или 2005). Так вот, я решил проверить эту теорию. Таблицу _Document68 документа "Договор" я скопировал на MS SQL Server 2000 SP4, также имеющийся у нас, и выполнил там запрос RLS, который я приводил в начале темы. Результат одинаков - оба сиквела, и 2000, и 2005 выдают сообщение об арифметическом переполнении.

Вопросы у меня к Вам в дополнение к ранее заданным:
1. Почему платформа посылает запросы RLS еще до вставки нового документа в базу?!
2. И как (и можно ли вообще) обойти это желание платформы выполнить запрос RLS в базу по СУЩЕСТВУЮЩИМ!!! в базе документам в то время, когда записываемого договора еще в базе нет?! Он же в этот момент существует пока только в ОЗУ клиента как объект вида ДокументОбъект.Договор.
...
Рейтинг: 0 / 0
RLS
    #36720230
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
То, что сообщение сиквела
Код: plaintext
1.
"Сообщение 8115, уровень 16, состояние 2, строка 1
Ошибка арифметического переполнения при преобразовании expression к типу данных int."
трансформируется внутри платформы 1С:Предприятие 8.1 в сообщение платформы
Код: plaintext
"У пользователя недостаточно прав для на исполнение операции над базой данных"
у меня сомнений теперь не вызывает.

Но что за странные фокусы такие с 2 и 4 миллиардами?! Зачем принудительно вызывать переполнение на сиквеле?!

И еще не знаю, слух не слух... Мне сказали, что выбор сиквелом по умолчанию типа int обусловлен неверными настройками языка операционной системы - или сиквела, или клиента, или сервера 1С. Мол, при правильных языковых настройках он бы писал не 200000000000, а 200000000000.0, а это уже нормально обрабатывается движком сиквела (без арифметического переполнения). Это так? Кто-нибудь может подтвердить или опровергнуть эту теорию?
...
Рейтинг: 0 / 0
RLS
    #36720238
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще вопрос :) - может на преждевременное выполнение запроса RLS как-то влиять режим проведения документа (выключено, включено с разрешением оперативного проведения, включено с запретом оперативного проведения)?
...
Рейтинг: 0 / 0
RLS
    #36722874
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Up. Никто ничего не можетответить по возникшим проблемам?
...
Рейтинг: 0 / 0
RLS
    #36723708
Паля
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
отвечу на часть. сам не понял до конца в чём цимус.
GrayMagellan
Но что за странные фокусы такие с 2 и 4 миллиардами?! Зачем принудительно вызывать переполнение на сиквеле?!


Ну так действительно может выглядить проверка доступа на чтение к текущему документу.
Сделали SELECT TOP 1 если нет доступа то вываливается ошибка и всё откатывается. ну пускай.
0x000000000 это ссылка на текущий документ (пока он не записан).


И еще не знаю, слух не слух... Мне сказали, что выбор сиквелом по умолчанию типа int обусловлен неверными настройками языка операционной системы - или сиквела, или клиента, или сервера 1С. Мол, при правильных языковых настройках он бы писал не 200000000000, а 200000000000.0, а это уже нормально обрабатывается движком сиквела (без арифметического переполнения). Это так? Кто-нибудь может подтвердить или опровергнуть эту теорию?
это НЕ так. всегда будет переполнение.

WHERE
(
_Document68._Date_Time > {ts '2010-06-04 00:00:00'}
OR _Document68._Date_Time = {ts '2010-06-04 00:00:00'}
AND _Document68._IDRRef > 0x00000000000000000000000000000000
)
AND _Document68._Date_Time <= {ts '2010-06-04 23:59:59'}
AND _Document68._IDRRef <> 0x00000000000000000000000000000000
ORDER BY

У меня тоже возникает вопрос причём тут дата. у вас есть другие RLS на этом доке? во всех ролях пользователя?
Приведите их тут. Я так понимаю это проверка на наличие других документов в этот день.
Она из неоткуда чтоли взялась?
...
Рейтинг: 0 / 0
RLS
    #36725689
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет. Других RLS на этот документ нет. Он существует в единственном числе в том виде как я привел в начале темы. Проблема в том, что если я временно убираю TOP 1 и обманываю систему, меняя тип вычисляемого выражения с int на decimal, то получаю такую выборку, как я привел в примере. С тем упорядочиванием (по дате ввода в базу с убыванием), которое задает платформа, в этой выборке первым оказывается договор, введенный 2010-06-04 15:31:51.000 (последний введенный в течение суток 4 июня 2010 года), но подразделение, которое в нем указано, не входит в список, перечисленный во внутреннем CASE, поэтому переменная _f_1 приравнивается к 4 млрд.:

_f_2 _f_3 _f_1
2010-06-04 15:31:51.000 0x90C1005056BA636711DF72D87102A470 4000000000.0

Как я понимаю свою проблему, она заключается в том, что RLS запрос платформой упаковывается не в условие WHERE основного запроса, а идет как вычисляемое поле _f_1, и результат вычислений может быть либо 4000000000 (доступа нет), либо 2000000000 (доступ есть). Я думаю, что арифметическое переполнение у сиквела возникает уже в процессе вычисления первой же строчки результата.

При этом, насколько я понимаю, все RLS запросы оформляются системой в виде вычисляемого поля во внутреннем кейсе, поэтому я как прикладной программист, пишущий RLS-запрос в Конфигураторе, не могу повлиять на весь SQL-запрос, формируемый платформой. Но может быть можно, написав RLS-запрос по-другому, заставить платформу формировать SQL-запрос без этих дурацких вычислений 2/4 млрд и без арифметического переполнения?
...
Рейтинг: 0 / 0
RLS
    #36725933
Паля
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проблема в том, что если я временно убираю TOP 1 и обманываю систему, меняя тип вычисляемого выражения с int на decimal, то получаю такую выборку, как я привел в примере.
Да забейте на этот int уже. Считайте что всё правильно тут.

При этом, насколько я понимаю, все RLS запросы оформляются системой в виде вычисляемого поля во внутреннем кейсе, поэтому я как прикладной программист, пишущий RLS-запрос в Конфигураторе, не могу повлиять на весь SQL-запрос, формируемый платформой.
Не разбираюсь я в RLS к сожалению ))

Не похоже что это ваш запрос. дата то откуда здесь?
WHERE(
_Document68._Date_Time > {ts '2010-06-04 00:00:00'}
OR _Document68._Date_Time = {ts '2010-06-04 00:00:00'}
AND _Document68._IDRRef > 0x00000000000000000000000000000000
)
AND _Document68._Date_Time <= {ts '2010-06-04 23:59:59'}
AND _Document68._IDRRef <> 0x00000000000000000000000000000000

Это тупо проверка на поиск другого документа в этот день которая обламывается потому что нет доступа на чтение к полю Дата(СASE после даты). Откуда берётся проверка я не знаю.фильтр не добавляется в where потому что это встроенный запрос и в нём не указано что надо фильтровать только по разрешённым для пользователя (это можно так). в типовой запрет не стоит на системные поля типа ссылки даты и прочее. они открыты а прочие поля закрыты.
может в этом проблема.


Совет:
Выполните встроенный запрос во внешней обработке 1с "Выбрать ссылка,дата Из Договоры" под этим пользователем и посмотрите во что он оттранслируется.
далее для интереса : "Выбрать Разрешенные ссылка,дата Из Договоры".

если в первом случае будет такая же ошибка и такой же CASE, то вроде всё ясно.
...
Рейтинг: 0 / 0
RLS
    #36726016
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не похоже что это ваш запрос. дата то откуда здесь?
WHERE(
_Document68._Date_Time > {ts '2010-06-04 00:00:00'}
OR _Document68._Date_Time = {ts '2010-06-04 00:00:00'}
AND _Document68._IDRRef > 0x00000000000000000000000000000000
)
AND _Document68._Date_Time <= {ts '2010-06-04 23:59:59'}
AND _Document68._IDRRef <> 0x00000000000000000000000000000000

А дату, и вообще все это WHERE, платформа сама добавила. Я этого в запрос RLS не ставил. Запрос RLS в Конфигураторе вообще выглядит так:

Код: plaintext
Прочие поля| ГДЕ ВладелецДоговора В (&ПодразделенияПользователяНаЧтение)

Фишка в том, что по этому WHERE из базы поступает выборка из 26 договоров. Поля _f_2 и _f_3 - это столбцы таблицы документа. А вот поле _f_1 - вычисляемое. И вот она начинает каждую строчку из этих 26 проверять на условие входимости в список разрешенных подразделений. Если подразделение договора входит, то _f_1 принимает значение 2 000 000 000, а если не входит, то _f_1 принимает значение 4 000 000 000, и вот тут возникает ошибка арифметического переполнения. Как ее обойти? Как составить запрос RLS так, чтобы ее обойти?
...
Рейтинг: 0 / 0
RLS
    #36726047
GrayMagellan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще фишка в том, что в запросах RLS нельзя написать ни "ВЫБРАТЬ", ни "ВЫБРАТЬ РАЗРЕШЕННЫЕ".

А так-то я этот запрос RLS конечно в консоли запросов отлаживал. В консоли запросов он выглядит так:

Код: plaintext
1.
2.
3.
4.
5.
ВЫБРАТЬ РАЗРЕШЕННЫЕ 
	*
ИЗ
	Документ.Договор КАК Договор
ГДЕ
	Договор.ВладелецДоговора В (&ПодразделенияПользователяНаЧтение)

И он прекрасно работает. Я же не делаю там никаких кейсов. У меня в консоли запросов отбор договоров по вхождению разрешенных подразделений идет в конструкции ГДЕ (WHERE), поэтому в выборку приходят только те договора, которые удовлетворяют условию. А в запросе, трансформированном платформой, в условие WHERE идет не отбор договоров по списку, а отбор по суткам даты документа (2010-06-04 - это сутки даты документа, которая равна 04 июня 2010). А мое условие отбора идет как вычисляемое поле _f_3 во внутреннем кейсе.
...
Рейтинг: 0 / 0
RLS
    #36726309
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как то дремутно ...
...
Рейтинг: 0 / 0
RLS
    #36726608
Паля
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще фишка в том, что в запросах RLS нельзя написать ни "ВЫБРАТЬ", ни "ВЫБРАТЬ РАЗРЕШЕННЫЕ".
Нет ну я понимаю когда я вас читаю в полглаза, но вы то зачем так со мной ))
я ж пытаюсь помочь всё таки.
ознакомтесь с мануалом короче:
http://www.kb.mista.ru/article.php?id=33


Заданные ограничения добавляются системой к КАЖДОМУ запросу, даже тем, которые платформа генерирует самостоятельно для реализации пользовательского интерфейса или других функций.

Ограничения на доступ к данным работают в двух режимах:
• в режиме динамического списка производится простая фильтрация разрешенных записей, таким образом, пользователь просто не видит запрещенные данные.
• в режиме выборки – нарушение ограничения влечет за собой исключение, таким образом, запрос не будет выполнен вовсе, значит, практически все запросы конфигурации могут «налететь» на ограничение.
В язык запросов было введено новое ключевое слово «Разрешенные», которое пишется сразу после «Выбрать». Если оно указано, то запрос выбирает только разрешенные записи, а остальные «не видит».
и ещё себя процитирую
автор в типовой запрет не стоит на системные поля типа ссылки даты и прочее. они открыты а прочие поля закрыты.
...
Рейтинг: 0 / 0
RLS
    #36726621
Паля
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
RLS
прочие поля->ограничение

Выбрать * from Договор -> вылет
Выбрать Разрешенные from Договор -> ок.

Добавляем RLS поля ссылка, дата -> пустое ограничение

Выбрать Ссылка, Дата from Договор -> ок.

1с ки нету под рукой поэтому я исходя из того что написано выше делаю заключение и не претендую на истину.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / [игнор отключен] [закрыт для гостей] / RLS
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]