powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
25 сообщений из 27, страница 1 из 2
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472482
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про "М" можно рассуждать долго и интересно... В Каше же, судя по всему, за последние несколько лет мало что поменялось. Нормально писать на нем можно,
- если досконально знаешь документацию и имеешь замечательную память, чтобы в нужный момент вспомнить, что в описании такого-то класса действительно есть приписка мелким шрифтом - "При перегреве издает неприятные запахи"
- если он куплен, оплачивается саппорт (замечательный на мой взгляд), и самое главное - используешь только очень простые решения, и достаточно проверенные решения. Шаг в сторону карается закапыванием в огромной яме с дерьмом документации и отладки.

Есть огромный ангар с инструментами и материалами, но когда нужно сколотить табуретку, выясняется, что или молоток оказался пластилиновым, или доски - фарфоровые...

Я прилагаю неимоверные усилия, чтобы не использовать непроверенные инструменты (и другим не давать), но вот вчера "вступил"...

В расчетном свойстве экземпляра одного из классов нужно было собрать набор значений расчетных свойств экземпляров других классов.

А оно - то собирается, то нет... Там с этими расчетными свойствами вообще-то песня и неприятностей много (не программу пишешь, а по болоту по кочкам прыгаешь), но тут уж совсем все плохо стало - все перепробовал... в тех объектах, откуда собираем, свойства есть, а в том, куда собираем, нет... падла.

Сделал примерчик для саппорта - "по мотивам"... но отправлять не буду - лучше НЕ БУДУ использовать разрекламированный ими же ("пользуйте!", "быстрее!", "активно развивается!"... бл*),
%ResultSet.SQL в расчетных полях...

Примерчик такой:
Код: 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.
65.
66.
67.
68.
69.
70.
71.
Class a.test Extends %Persistent
{

Property p As %String;

Property Desc As %String [ Calculated, SqlComputeCode = {
		s desc = ""
		s var =  2  // Меняем на  1  для получения "наслаждения"
		s sql = "SELECT p,ID,Desc"_var_" FROM a.test WHERE ID = "_{ID}
		// Для продолжения можно последовательно убирать из строки "p" и "ID"
		w "sql: "_sql,!
		s result = ##class(%ResultSet.SQL).%Prepare(.sql,.err,"")
		if '$ISOBJECT(err) {
			while result.%Next() {
				w "data: ",result.%Get("Desc"_var),!
				s desc = desc_$s(desc="":"",1:"; ")_result.%Get("Desc"_var) 
			}
		}
		s {Desc}=desc
		
	}, SqlComputed ];

Property Desc1 As %String [ Calculated, SqlComputeCode = {
		s desc1 = ""
		s sql1 = "SELECT p FROM a.test WHERE ID = "_{ID}
		w "sql1: "_sql1,!
		s result1 = ##class(%ResultSet.SQL).%Prepare(.sql1,.err1,"")
		if '$ISOBJECT(err1) {
			while result1.%Next() {
				w "data1: ",result1.%Get("p"),!
				s desc1 = desc1_$s(desc1="":"", 1 :"; ")_result1.%Get("p")
			}
		}
		s {Desc1}=desc1
	}, SqlComputed ];

Property Desc2 As %String [ Calculated, SqlComputeCode = {
		s desc2 = ""
		s sql2 = "SELECT p FROM a.test WHERE ID = "_{ID}
		w "sql2: "_sql2,!
		s result2=##class(%ResultSet).%New("%DynamicQuery:SQL")
		s sc=result2.Prepare(sql2)
		s sc=result2.Execute()
		if $$$ISOK(sc) {
			while result2.Next(.sc) {
				w "data2: ",result2.%Get("p"),!
				s desc2 = desc2_$s(desc2="":"", 1 :"; ")_result2.%Get("p")
			}
		}
		s {Desc2}=desc2
	}, SqlComputed ];

ClassMethod test()
{
	// d ##class(a.test).test()
	try {
		s a = ##class(a.test).%OpenId( 1 )
		if '$ISOBJECT(a) {
			s a = ##class(a.test).%New()
			s a.p = "asdf"
			d a.%Save()
		}
		w a.Desc,!
	} catch {
	}
	w $system.OBJ.DisplayError(%objlasterror),!
	k
	q
}

}

В каком-то из вариантов можно получить ошибку "<UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1"
От жеж спасибо! Что бы я делал, не увидь эту ашипку... ума не приложу...

В общем, "не ходите дети, в Африку гулять..."
Неправ-то м.б. и я - пропустил что-то в документации опять... Но такие моменты очень разочаровывают в Каше.

Cache for Windows (x86-32) 2009.1.2 (Build 602) Tue Oct 20 2009 10:02:03 EDT
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472547
Блок А.Н.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можете интерпретировать то что просходит?
А то пока навскидку непонятно, разбираться голова после рабочего дня пухлая.
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472606
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesov,
Я по-прежнему люблю (можно сказать обожаю) Каше! Код должен выглядеть красиво, и надо иметь возможность его тестировать. Метод класса, спрятанный в параметрах свойства выглядит некрасиво и работает также.
Попробуйте так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 ClassMethod GetDesc(ID) as %String {
   s desc = "", var =  2  // Меняем на  1  для получения "наслаждения"
   s sql = "SELECT p,ID,Desc"_var_" FROM a.test WHERE ID = "_ID
   // Для продолжения можно последовательно убирать из строки "p" и "ID"
   w "sql: "_sql,!
   s result = ##class(%ResultSet.SQL).%Prepare(.sql,.err,"") Q:$ISOBJECT(err)
   while result.%Next() {
	w "data: ",result.%Get("Desc"_var),!
	s desc = desc_$s(desc="":"", 1 :"; ")_result.%Get("Desc"_var) 
   }
   Q desc     
 }
 
 Property Desc As %String [ Calculated, SqlComputeCode = {s {Desc}=..GetDesc({ID})}, SqlComputed ];


Теперь имеем возможность писать тесты на метод GetDesc(), да и выглядит получше ;)
P.S.: Любите Кашу, она вкусная и полезная! :)
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472665
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блок А.Н.Можете интерпретировать то что просходит?
А то пока навскидку непонятно, разбираться голова после рабочего дня пухлая.

При попытке из расчетного свойства, использующего %ResultSet.SQL, считать некое расчетное свойство, также использующее в своем расчете %ResultSet.SQL происходит зацикливание (или ошибка, зависит от того, выбирается ли что-то еще кроме расчетного свойства в первом запросе)

Лечится заменой %ResultSet.SQL(нерабочее свойство Desc1) на %DynamicQuery:SQL (вполне себе рабочее Desc2).
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472689
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
doublefint Код должен выглядеть красиво, и надо иметь возможность его тестировать. Метод класса, спрятанный в параметрах свойства выглядит некрасиво и работает также.

Вот на мой взгляд обойтись без метода в данном случае - вполне красиво... аскетично как-то ;)

Кроме того, как показал опыт, со временем между свойством и его расчетом может быть что-то вставлено (другой метод или другое свойство или много их), что испортит читабельность... Если в коде расчета 5-10 строк, мне удобнее и симпатишнее так ;) в смысле, было удобнее...

Но похоже, придется делать так, как Вы и сказали... иначе неприятности ;)
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472785
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesov,
5-10 строк это, вообще-то, рекомендуемый размер кода метода. К тому же, Вы используете внутри сложный объект, каждый вызов которого может вызвать ошибку. Да и по смыслу там спрятан метод класса - обработка множества экземпляров класса. Надо выносить в метод, иначе выйдет боком.

"вполне красиво... аскетично как-то" будет потом выглядеть так:
Код: plaintext
1.
2.
3.
4.
 Property Desc As %String [Calculated,SqlComputeCode={s {Desc}=..GetDesc({ID})}, SqlComputed];
 Property Desc1 As %String [Calculated,SqlComputeCode={s {Desc1}=..GetDesc({ID}, 1 )},SqlComputed];
 Property Desc2 As %String [Calculated, SqlComputeCode={s Desc2}=..GetDesc({ID}, 2 )},SqlComputed]; 
 ClassMethod GetDesc(ID as %String,номерПоля as %String) as %String { ... } ; 5 - 10  строк

"со временем между свойством и его расчетом может быть что-то вставлено (другой метод или другое свойство или много их), что испортит читабельность..." - не может быть! Поменяем реализацию метода :)

Так не только "красивше" и компактней, но и соответствует некоторым принципам кодирования, например: "однажды и только однажды","test first"
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472813
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если будет время, перечитайте начало топика и улыбнитесь. Хотя, как я иногда Вас понимаю :)
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36472842
Фотография DAiMor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да тут еще читабельность кода с вычисиляемыми полями улучшается если заменить
s {Desc}= val
на
s {*}= val
эти команды для поля Desc равнозначны но во втором случае удобнее, видно сразу что этому полю идет присваивание такого то значения, а в перовм случае можно и ошибиться с названием поля
и обращение к методам класса по-моему лучше заменить на ##class({%%CLASSNAME})
потому как объекта там все равно нету, этот код используется для SQL а там не используются объекты
_________________________________
Cache for Windows NT (AMD64) 5.0.21 (Build 6408) Tue Jan 3 2006 13:37:41 EST
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36473113
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DAiMor,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 s {*}= val ;похоже на "присвоить всем полям"

 ;и правда, объекта нет, зато есть #classcontext
 ;и это вызов метода класса, т.е без создания экземпляра
 s {Desc}=..GetDesc(ID) 
 s {*}=##class({%%CLASSNAME}) ;конечно, ИМХО, но строчка выше выглядит лучше
 ;такими сочетаниями символов можно запугать какого-нибудь программиста на C# до смерти
 ;"заклинание третьего уровня" :)

...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36473382
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А весь код внутри описания поля специально сделан ? Ничего хорошего из этого не выйдет...

Нужно вызывать метод класса и передовать туда параметры.

А так галиматся какая то кто объявляет и следить за переменными непонятно. Понадобиться код изменить - придется перекомпилировать ВСЕ классы и программы где есть SQL с выборкой этих полей.

Плюс у вас Execute() отсутствует насколько мне видно
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36473399
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesovВот на мой взгляд обойтись без метода в данном случае - вполне красиво... аскетично как-то ;)

Потом возьмите любой другой класс или программу - и вставьте туда
Код: plaintext
1.
&SQL(SELECT TOP  1  Desc INTO :desc FROM a.test)
Скопилируйте и гляньте генерируемый код - сразу разонравиться "красота"
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36473480
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Плюс у вас Execute() отсутствует насколько мне видно"
А там %ResultSet.SQL, ему не надо
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36473954
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PtnПонадобиться код изменить - придется перекомпилировать ВСЕ классы и программы где есть SQL с выборкой этих полей.

Видимо, это и происходит - время от времени в компиляцию какого-то малозначительного класса "цепляется" компиляция тучи, с виду несвязанных с ним, классов.

В общем-то, коллеги, вы меня убедили...

Однако отношения к Каше не поменялось - формально я ничего не нарушал. В документации нет условия, что Каше работает, только если код "красивый".

Программирование для меня - работа, а не хобби. И относиться к нему как к фэн-шую (с соответствующими затратами времени), ой как неохота. Лучше больше внимания уделять семье, друзьям... пиву, в конце концов ;) Работа должна быть на втором месте... И не мешать жить. Я так думаю.

Всем спасибо - много нового узнал и понял. Серьезно.
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36474016
Ptn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesovОднако отношения к Каше не поменялось - формально я ничего не нарушал. В документации нет условия, что Каше работает, только если код "красивый".

А условия что Каше легко и просто обязуется выполнять и компилировать любой код были ?

В SqlComputeCode вообще всё не очень просто - в ранних версиях там было что то вроде ограничения на объем кода. Лично у меня не получалось написать длинное выражение.

doublefintА там %ResultSet.SQL, ему не надо

Хм... видать какой то новый класс - обладает какой либо фишкой ?

А то лично я не вижу смысла смешивать похожие классы с разным набором методов - тут %ResultSet.SQL за ним сразу обычный %ResultSet
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36474330
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PtnХм... видать какой то новый класс - обладает какой либо фишкой ?
А то лично я не вижу смысла смешивать похожие классы с разным набором методов - тут %ResultSet.SQL за ним сразу обычный %ResultSet

IS развивают объектную прослойку. Сам удивился, когда не нашел Execute. Просто %ResultSet-а в документации Cache2k9 нет, а этот %ResultSet.SQL - c кэшированием, берет SQL и проверяет его наличие в кэше. Старый код работает по-прежнему
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 s sql="Select ....."
 s rs=##class(%ResultSet).%New("%DynamicQuery:SQL")
 s sc=rs.Prepare(sql) Q:'sc sc s sc=rs.Execute(sql) Q:'sc sc
 while rs.Next(){
  ;do something
 }
 d rs.Close(), rs.%Close()
Исправить шаблон для Студии, что-ли... :)

kolesovИ относиться к нему как к фэн-шую (с соответствующими затратами времени), ой как неохота.
Ну это как ООП, или переход с реляционных СУБД на Сache - просто смена способа мышления. Сначала тяжело, потом не понимаешь как можно по другому.
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36474460
Alexey Maslov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
doublefintПросто %ResultSet-а в документации Cache2k9 нетРади интереса гляньте в Cache2k9: [Documentation] > [Development Guides] > [Using Caché SQL] > [Using Dynamic SQL]
Налицо параллельное описание обоих ResultSet'ов. Вот новички удивятся, читая такое... при том, что внятного описания различий сходу не найти (только из анализа Documatic'а что-то немного проясняется).
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36476540
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
doublefint Код должен выглядеть красиво, и надо иметь возможность его тестировать. Метод класса, спрятанный в параметрах свойства выглядит некрасиво и работает также.
Попробуйте так:
...
Теперь имеем возможность писать тесты на метод GetDesc(), да и выглядит получше ;)
P.S.: Любите Кашу, она вкусная и полезная! :)
Код: 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.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
Class a.test Extends %Persistent
{

Property p As %String;

Property Desc As %String [ Calculated, SqlComputeCode = {
		s {Desc}=##class({%%CLASSNAME}).GetDesc({ID})
	}, SqlComputed ];

ClassMethod GetDesc(id As %String) As %String
{
	s desc = ""
	s var =  1 
	s sql = "SELECT Desc"_var_" FROM a.test WHERE ID = "_id
	w "sql: "_sql,!
	s result = ##class(%ResultSet.SQL).%Prepare(.sql,.err,"")
	if '$ISOBJECT(err) {
		while result.%Next() {
			w "data: ",result.%Get("Desc"_var),!
			s desc = desc_$s(desc="":"",1:"; ")_result.%Get("Desc"_var) 
		}
	}
	q desc
}

Property Desc1 As %String [ Calculated, SqlComputeCode = {
		s {Desc1}=##class({%%CLASSNAME}).GetDesc1({ID})
	}, SqlComputed ];

ClassMethod GetDesc1(id As %String) As %String
{
	s desc1 = ""
	s sql1 = "SELECT p FROM a.test WHERE ID = "_id
	w "sql1: "_sql1,!
	s result1 = ##class(%ResultSet.SQL).%Prepare(.sql1,.err1,"")
	if '$ISOBJECT(err1) {
		while result1.%Next() {
			w "data1: ",result1.%Get("p"),!
			s desc1 = desc1_$s(desc1="":"", 1 :"; ")_result1.%Get("p")
		}
	}
	q desc1
}

Property Desc2 As %String [ Calculated, SqlComputeCode = {
		s {Desc2}=##class({%%CLASSNAME}).GetDesc2({ID})
	}, SqlComputed ];

ClassMethod GetDesc2(id As %String) As %String
{
	s desc2 = ""
	s sql2 = "SELECT p FROM a.test WHERE ID = "_id
	w "sql2: "_sql2,!
	s result2=##class(%ResultSet).%New("%DynamicQuery:SQL")
	s sc=result2.Prepare(sql2)
	s sc=result2.Execute()
	if $$$ISOK(sc) {
		while result2.Next(.sc) {
			w "data2: ",result2.%Get("p"),!
			s desc2 = desc2_$s(desc2="":"", 1 :"; ")_result2.%Get("p")
		}
	}
	q desc2
}

ClassMethod test()
{
	// d ##class(a.test).test()
	try {
		s a = ##class(a.test).%OpenId( 1 )
		if '$ISOBJECT(a) {
			s a = ##class(a.test).%New()
			s a.p = "asdf"
			d a.%Save()
		}
		w a.Desc,!
	} catch {
	}
	w:$g(%objlasterror)'="" $system.OBJ.DisplayError(%objlasterror),!
	k
	q
}

}

Переписал, запускаю в терминале:

>d ##class(a.test).test()
sql: SELECT Desc1 FROM a.test WHERE ID = 1
sql1: SELECT p FROM a.test WHERE ID = 1
data1: sdfsd


ОШИБКА #5540: SQLCODE: -400 Сообщение: Unexpected error occurred: <UNDEFINED>%0Afirst+6^RS.CacheSql190.1 *%objcsd(2,1)1

Если поменять s var = 2 , то все ок.

Мало того, что все-равно не работает... Обратите внимание, насколько стало лучше отлаживать (я про сообщение об ошибке ;)

И кстати, ..Get..({ID}) ведь и не работало никогда в SqlComputeCode... нужно все-таки класс указывать... а я Вам поверил - опять 20 минут развлечений с ошибкой <Метод или свойство 'GetDesc' не существует в данном классе>
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36476597
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Продолжим:
Код: 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.
Class a.test Extends %Persistent
{

Property p As %String;

ClassMethod test(id As %String) As %String
{
	// w ##class(a.test).test( 1 )
	// s a = ##class(a.test).%New()
	// s a.p = "testData"
	// d a.%Save()
	s desc = ""
	s sql = "SELECT Descr FROM a.test WHERE ID = "_id
	s result = ##class(%ResultSet.SQL).%Prepare(.sql,.err,"")
	if '$ISOBJECT(err) {
		w 0," rs: ",result,!
		while result.%Next() {
			w 1,!
			s desc = desc_$s(desc="":"",1:"; ")_result.%Get("Descr") 
		}
	}
	w:$g(%objlasterror)'="" $system.OBJ.DisplayError(%objlasterror),!
	q desc
}

Property Descr As %String [ Calculated, SqlComputeCode = {
		s {Descr}=##class({%%CLASSNAME}).GetDescr({ID})
	}, SqlComputed ];

ClassMethod GetDescr(id As %String) As %String
{
	s desc1 = ""
	s sql1 = "SELECT p FROM a.test WHERE ID = "_id
	s result1 = ##class(%ResultSet.SQL).%Prepare(.sql1,.err1,"")
	if '$ISOBJECT(err1) {
		w  2 ," rs: ",result1,!
		while result1.%Next() {
			w  3 ,!
			s desc1 = desc1_$s(desc1="":"", 1 :"; ")_result1.%Get("p")
		}
	}
	w  4 ," desc: ",desc1,!
	q desc1
}

}
>>w ##class(a.test).test(1)
0 rs: 1@RS.CacheSql266
2 rs: 2@RS.CacheSql267
3
4 desc: testData

ОШИБКА #5540: SQLCODE: -400 Сообщение: Unexpected error occurred: <UNDEFINED>%0Afirst+6^RS.CacheSql266.1 *%objcsd(11,1)1

Т.о. В шаг 1 мы не попали!

Хотя резалтсеты разные, очень похоже на то, что вызов метода %Next() второго как-то портит первый - это одной RS.CacheSql260.1 известно, но она - RS.CacheSql260.1 .OBJ !!! Со всеми проистекающими.

Вывод: В местах, где при использовании %ResultSet.SQL необходимо получить в него расчетное свойство, также использующее %ResultSet.SQL нас ждут неприятности.

Сравниваем с презентацией ИС (kudinov-perfomnace-management.ppt, адрес точно не помню, но с их сайта):

kudinov-perfomnace-management.pptСтарый класс – %Library.ResultSet.
Новый класс – %ResultSet.SQL
%ResultSet.SQL значительно быстрее %Library.ResultSet, сравнимо со встроенным SQL.
%ResultSet.SQL постоянно совершенствуется.

Ввели в заблуждение?
Я этот %ResultSet.SQL много где использовать успел...
в т.ч. во многих расчетных свойствах...
(далее текст отсутствует)
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36476605
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напишу-ка я все же в саппорт ;)
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36477435
doublefint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DAiMOR, kolesov,
Прошу прощения и посыпаю себе голову пеплом за
Код: plaintext
1.
 s {Desc}=..GetDesc({ID})
Правильно будет так
Код: plaintext
1.
 s {Desc}=##class({%%CLASSNAME}).GetDesc({ID})

kolesov,
я, измученный чувством вины, переписал Ваш пример так:
Код: 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.
 Class a.test Extends (%Persistent,%Populate) {
Property p As %String;
Property Desc As %String [ Calculated,SqlComputeCode={s {Desc}=##class({%%CLASSNAME}).GetDesc({ID})},SqlComputed];

///Возникает вопрос зачем вообще использовать ResultSet если есть четкое указание ID
///может лучше $zobjclassmethod ? 
ClassMethod GetDesc(id As %String,dnum as %String= 1 ) As %String {
	s desc = ""
	s field="Desc"_dnum
	s sql = "SELECT "_field_" FROM a.test WHERE ID = ?"
	s rs=##class(%ResultSet).%New("%DynamicQuery:SQL")
	s sc=rs.Prepare(sql),sc=rs.Execute(id)
	while rs.Next() {
		s value=$G(rs.Data(field))
		s desc = desc_$s(desc="":"", 1 :"; ")_value 
	}
	q desc
}

Property Desc1 As %String [ Calculated, SqlComputeCode={s {Desc1}=##class({%%CLASSNAME}).GetPList({ID})},SqlComputed];
///Здесь нет вычисляемого имени поля, можно использовать встроенный SQL
///но из-за прямого ID может лучше все таки $zobjclassmethod ? 
ClassMethod GetPList(id As %String) As %String {
	s desc1 = ""
	&sql(DECLARE rs CURSOR FOR
		SELECT p INTO :p From a.test Where ID=:id
	)
	&sql(OPEN rs) &sql(FETCH rs)
	while SQLCODE= 0  {  
		s desc1 = desc1_$s(desc1="":"", 1 :"; ")_p	 
		&sql(FETCH rs)
	}
	&sql(CLOSE rs)
	q desc1
}
Property Desc2 As %String [ Calculated, SqlComputeCode = {s {Desc2}=##class({%%CLASSNAME}).GetPList({ID})},SqlComputed];
ClassMethod test() {
        d ##class(a.test).%KillExtent()
        d ##class(a.test).Populate( 100 )
	s a = ..%OpenId( 1 ) 
	if '$ISOBJECT(a) { w "Не смогли открыть объект 1"	Q }
	w "a.Desc=",a.Desc
	s a =..%New(), a.p = "asdf", sc=a.%Save() 
	if 'sc d $system.OBJ.Dump(sc) Q
	w !,"Test OK" Q
}

}

...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36477492
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
doublefintПравильно будет так
Код: plaintext
1.
 s {Desc}=##class({%%CLASSNAME}).GetDesc({ID})


Как показал опыт, не всегда - если класс унаследован, и свойство считается для предка, вы получите не реальный расчет (для конкретного потомка), а расчет для предка - с его нулевой, или довольно скудной, логикой.

doublefint///Возникает вопрос зачем вообще использовать ResultSet если есть четкое указание ID
///может лучше $zobjclassmethod ?

"В реале" это было два класса - верхний перебирал несколько экземпляров нижних и собирал их описания. Здесь пример компактный просто - понятно, что он бестолковый... т.к. он - демонстрация баги

doublefint///Здесь нет вычисляемого имени поля, можно использовать встроенный SQL
///но из-за прямого ID может лучше все таки $zobjclassmethod ?

Т.о. есть 3 варианта - два из них я привел, вы добавили третий...
Я же не говорю, что нечто нельзя сделать - я говорю, что это нечто нельзя сделать с помощью разрекламированного %ResultSet.SQL.

Все, кроме него, проклятого, безусловно, будет работать ;)
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36477500
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и свойство считается для предка правильно читать "свойство считается в контексте предка"
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36478549
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если Вам подходит, можно воспользоваться LIST вместо цикла:
Код: plaintext
select replace(list(p),',','; ') as desc from a.test where ID=?

В версии 2010.1 появился новый класс %SQL.Statement для работы с динамическими запросами. Как пишут на англоязычном форуме - скорость до 3-ёх раз выше, чем у %ResultSet.

Во Владивосток по транссибу теперь можно совершить виртуальное путешествие.
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36479991
KSergio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Начиная, с 2010.1 рекомендация - использовать %SQL.Statement. Из документации по Dynamic SQL:
"%SQL.Statement methods are the preferred way to executes a Dynamic SQL query. You can also use the %ResultSet.SQL class or the %Library.ResultSet class to query the database."

%ResultSet.SQL быстрее %Library.ResultSet (особенно при переборе большого числа записей результата) начиная с версии 5.2.

Но абсолютных чудес не бывает, для всех динамических запросов при первом выполнении необходима компиляция запроса, т.е. накладные расходы. Поэтому стоит динамические запросы использовать только тогда, когда это необходимо, и не забывать про передачу параметров, чтобы для плодить серию запросов ...

Ошибок при выполнении кода в любом случае быть не должно, поэтому в случае нахождения какой-то проблемы стоит завести ее в WRC.

Также можно написать на support@intersystems.ru, support@intersystems.com. В этом случае просьба указывать название вашей организации в ключе (поле CustomerName) , т.к. не всегда по русскому названию очевидно ее написание латинскими буквами или привычное для вас наименование вашей организации может не совпадать с ее наименованием для InterSystems (холдинги, группы компаний... )

Но лучше сразу ввести в WRC, т.к. это официальный путь решения проблем заказчиков InterSystems, у вас есть возможность установить приоритет проблемы, нет вероятности, что письмо попадет в спам...

Если у вас нет WRC аккаунта, напишите заявку на support@intersystems.ru с указанием организации, фамилии и имени пользователя, контактного телефона.
...
Рейтинг: 0 / 0
Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
    #36480058
KSergio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибка уже исправлена - DevChange DLP2441 .

WRC - самый правильный и быстрый способ решения проблем. Пользуйтесь им.
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Кто там еще любит Каше? <UNDEFINED>%0AmBuncommitted+1^RS.CacheSql494.1 *%objcsd(2,11)1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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