хранение/обработка/просмотр XML=Строковый атрибут

Обсуждение технических вопросов работы с системами управления базами данных (СУБД), работе с языком SQL и скриптовыми языками.
Ответить
Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

хранение/обработка/просмотр XML=Строковый атрибут

Сообщение Александр »

подводя небольшой итог нескольких тем
Zodiac финал - http://www.lplm.ru/phpBB2/viewtopic.php?f=18&t=615
Скрипт: v4.30 090113 RSS рассылки в Лоции ;-) забираем - http://www.lplm.ru/phpBB2/viewtopic.php?f=18&t=536
Мастер класс ;-) Классификаторы на XML - http://www.lplm.ru/phpBB2/viewtopic.php?f=18&t=538
Скрипт: Строковые массивы для Лоции на MSSQL (завершение) - http://www.lplm.ru/phpBB2/viewtopic.php?f=18&t=257
Предлагаю добавить формат/функции для работы с XML - http://www.lplm.ru/phpBB2/viewtopic.php?f=20&t=569
Юзер..... вышла замуж - http://www.lplm.ru/phpBB2/viewtopic.php?f=2&t=592
а как отловить актуальный курс ЦБ используя Workflow??? - http://www.lplm.ru/phpBB2/viewtopic.php ... &hilit=xml
и т.д.

использование строкового атрибута для работы с xml фрагментом длиной не более 2000 символов
для примера работа с таким фрагментом

Код: Выделить всё

строка='<Manager><Filial Name="РПК-Москва" id="0"><User Name="Некроенко Наталья Викторовна" id="23"><Type>Куратор</Type><Set>Проданный</Set><Add>20080211</Add><Del/></User><User Name="Бадерсков Вячеслав Михайлович" id="23"><Type>Менеджер</Type><Set>Проданный</Set><Add>20090711</Add><Del/></User><User Name="Терещенко Елена Игоревна" id="23"><Type>Менеджер</Type><Set>Проданный</Set><Add>20091002</Add><Del/></User></Filial><Filial Name="Академия САПР и ГИС-Москва" id="10"><User Name="Васильева Лидия Евгеньевна" id="100000000"><Type>Менеджер</Type><Set>Проданный</Set><Add>20080213</Add><Del/></User></Filial><Filial Name="Filial_New" id="1"/></Manager>'
или в другом виде

Код: Выделить всё

<Manager>
  <Filial Name="РПК-Москва" id="0">
    <User Name="Некроенко Наталья Викторовна" id="23">
      <Type>Куратор</Type>
      <Set>Проданный</Set>
      <Add>20080211</Add>
      <Del />
    </User>
    <User Name="Бадерсков Вячеслав Михайлович" id="23">
      <Type>Менеджер</Type>
      <Set>Проданный</Set>
      <Add>20090711</Add>
      <Del />
    </User>
    <User Name="Терещенко Елена Игоревна" id="23">
      <Type>Менеджер</Type>
      <Set>Проданный</Set>
      <Add>20091002</Add>
      <Del />
    </User>
  </Filial>
  <Filial Name="Академия САПР и ГИС-Москва" id="10">
    <User Name="Васильева Лидия Евгеньевна" id="100000000">
      <Type>Менеджер</Type>
      <Set>Проданный</Set>
      <Add>20080213</Add>
      <Del />
    </User>
  </Filial>
  <Filial Name="Filial_New" id="1" />
</Manager>
как видно - в строке упакованы разные типы данных однотипной информации
сохраняем строку в строковый атрибут
дальше скрипт как получить такую строку из Party из WorkFlow из файла - откуда угодно - прочитаем из Party (процедура SetManager())
Последний раз редактировалось Александр 02 апр 2010, 10:14, всего редактировалось 1 раз.

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: хранение/обработка/просмотр XML=Строковый атрибут

Сообщение Александр »

Код: Выделить всё

Dim cMngObj 'Текущие менеджеры объекта
Dim hMngObj 'История менеджеров объекта

Function Connect_xmlData(xmlDoc, xmlData)
'загрузить менеджеров
Set xmlDoc = CreateObject("Msxml.DOMDocument")
xmlDoc.async = False
xmlDoc.validateOnParse = False

If Not xmlDoc.loadxml(xmlData) = True Then
If xmlDoc.parseError.errorCode Then
MsgBox "Reason: " & xmlDoc.parseError.reason & vbCr & _
"ErrorCode: " & xmlDoc.parseError.errorCode & vbCr & _
"Filepos: " & xmlDoc.parseError.filepos & vbCr & _
"Line: " & xmlDoc.parseError.Line & vbCr & _
"Linepos: " & xmlDoc.parseError.linepos & vbCr & _
"SrcText: " & xmlDoc.parseError.srcText & vbCr & _
"Url: " & xmlDoc.parseError.URL, vbOKOnly vbInformation vbSystemModal, "Загрузка XML данных"
End If
Connect_xmlData = False
Else
Connect_xmlData = True
End If
End Function

Function Set_Filial(cMngObj, Filial_Name, Filial_id)
'вернуть филиал, если его (во всем документе) нет - создать
Dim Filial
Set Filial = cMngObj.selectSingleNode("//Filial[(@id='" Filial_id "')]")
' Set Filial = cMngObj.selectSingleNode("//Filial[(@Name='" Filial_Name "')]")
' Set Filial = cMngObj.selectSingleNode("//Filial[(@id='" Filial_id "') and (@Name='" Filial_Name "')]")
If Filial Is Nothing Then 'если филиала нет - добавить
Set Filial = cMngObj.documentElement.appendChild(cMngObj.createElement("Filial"))
Filial.setAttribute "Name", Filial_Name
Filial.setAttribute "id", Filial_id
End If
Set Set_Filial = Filial
End Function

Function Set_Manager(cMngObj, Filial, Manager_Name, Manager_id)
'вернуть менеджера, если его (во всем документе) нет - создать
Dim Manager, Node, md
' Set Manager = cMngObj.selectSingleNode("//User[(@id='" Manager_id "')]")
Set Manager = cMngObj.selectSingleNode("//User[(@Name='" Manager_Name "')]")
' Set Manager = cMngObj.selectSingleNode("//User[(@id='" Manager_id "') or (@Name='" Manager_Name "')]")
If Manager Is Nothing Then 'если менеджера нет - добавить
Set Manager = Filial.appendChild(cMngObj.createElement("User"))
Manager.setAttribute "Name", Manager_Name
Manager.setAttribute "id", Manager_id
Set Node = Manager.appendChild(cMngObj.createElement("Type"))
Node.Text = "Менеджер"
Set Node = Manager.appendChild(cMngObj.createElement("Set"))
Node.Text = "Текущий"
Set Node = Manager.appendChild(cMngObj.createElement("Add"))
'Node.Text = Format(Date, "yyyy-mm-dd")
md = FormatDateTime(Now(), 2)
Node.Text = Right("0000" CStr(Year(md)), 4) "-" Right("00" CStr(Month(md)), 2) "-" Right("00" CStr(Day(md)), 2)
Set Node = Manager.appendChild(cMngObj.createElement("Del"))
End If
Set Set_Manager = Manager
End Function

Function Set_Curator(cMngObj, Manager_Name)
'назначить существующего менеджера куратором
Set Curator = cMngObj.selectSingleNode("//User[Type='Куратор']")
If Curator Is Nothing Then
Set Curator = cMngObj.selectSingleNode("//User[(@Name='" Manager_Name "')]")
Curator.childNodes(0).Text = "Куратор"
Else
If Curator.getAttribute("Name") <> Manager_Name Then
Curator.childNodes(0).Text = "Менеджер"
Set Curator = cMngObj.selectSingleNode("//User[(@Name='" Manager_Name "')]")
Curator.childNodes(0).Text = "Куратор"
End If
End If
Set Set_Curator = Curator
End Function



Sub SetManager()
'добавить менеджера
Dim cMngAttr, hMngAttr

Filial_Name = "РПК-Москва" 'LsVars.GetVarValue("Filial_Name")
Filial_id = 0 'LsVars.GetVarValue("Filial_id")
Manager_Name = "Потапов Михаил Аркадьевич" 'LsVars.GetVarValue("Manager_Name")
Manager_id = 45 'LsVars.GetVarValue("Manager_id")

'загрузить текущих менеджеров
cMngAttr = ""
If Trim(cMngAttr) = "" Then cMngAttr = "<Manager></Manager>" '
'прочитать строку
If Connect_xmlData(cMngObj, cMngAttr) Then

'выбрать всех подключенных пользователей
Set nUsers = cMngObj.getElementsByTagName("User")
If nUsers.Length >= 10 Then
MsgBox "к Компании подключено 10 менеджеров - в случае необходимости удалите неактивных"
Exit Sub
Else
'Найти/Создать филиал
Set nFilial = Set_Filial(cMngObj, Filial_Name, Filial_id)
'Найти/Создать менеджера
Set nManager = Set_Manager(cMngObj, nFilial, Manager_Name, Manager_id)
'Set nManager = Set_Manager(cMngObj, Set_Filial(cMngObj, Filial_Name, Filial_id), Manager_Name, Manager_id)

'Найти/Установить (если нет) куратора
Set nCurator = cMngObj.selectSingleNode("//User[Type='Куратор']")
If nCurator Is Nothing Then Set nCurator = Set_Curator(cMngObj, Manager_Name)
End If

'сохраним строку
cMngAttr = cMngObj.XML
'отдать ее в действие
LsVars.SetVarValue "Manager_String", CStr(cMngAttr)
Set cMngObj = Nothing
Else
MsgBox "Значения атрибутов не загружены" & vbCr & "Попробуйте позже", vbOKOnly vbInformation vbSystemModal, "Куратор/Менеджер"
End If
End Sub
на мой взгляд всю обработку xml лучше производить в скрипте - все очень просто и понятно и в интернете тонны информации по этому поводу (в тексте есть ошибки - просто неохота править - смысл очевиден)
дальше просмотр в вычисляемых полях

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: хранение/обработка/просмотр XML=Строковый атрибут

Сообщение Александр »

с просмотром и начинается самое интересное :wink:
с одной стороны если нужен просмотр у одного объекта - можно скриптом вытащить - не торопясь
с другой стороны если на форме показать или в отчете - нужна скорость гибкость и виртуальность - да и скриптов нет поэтому смотрим на SQL

для просмотра используем xQuery MSSQL2005, причем прямой вызов данного объекта через f_ExecSQLSelect_3 не работает, через функцию не работает, через хп все ок
ps - может конечно и работает - но у меня не получилось

пишем хп

Код: Выделить всё

LTER procedure [LSDBO].[Ric_Get_pXmlToTable]
        (@xml	xml	    --Строка с данными размеченными как XML
         )
as 
Begin

 Set ARITHABORT ON
--или так (вернется таблица)
/* 
Select 
	     r.value('@Name[1]', 'varchar(255)') as mFIO
        ,r.value('@id[1]', 'int') as mId
        ,r.value('(Type/text())[1]', 'varchar(255)') as [mType]
        ,r.value('(Set/text())[1]', 'varchar(255)') as [mSet]
        ,r.value('(Add/text())[1]', 'datetime') as [mAdd]
        ,r.value('(Del/text())[1]', 'varchar(255)') as [mDel]
  from @xml.nodes('//User') as t(r)
*/
--или так (вернется строка)
select @xml.query('for $s in //User/@Name return concat(string($s), ",")').value('text()[1]', 'varchar(255)')
--или как угодно
  Set ARITHABORT OFF
--!!!! управление ARITHABORT обязательное условие 
End 
кстати именно из за ARITHABORT и в прямом запросе и через функцию (из за невозможности установить его в ON) ничего не получилось - Лоция - умирает без предупреждения

соответственно результатом данной процедуры будет или
таблица
Захват-90.gif
Захват-90.gif (6.9 КБ) 17800 просмотров
или строка

Код: Выделить всё

Некроенко Наталья Викторовна, Бадерсков Вячеслав Михайлович, Терещенко Елена Игоревна, Васильева Лидия Евгеньевна,
короче все что хотите и в любом виде
ps
хотя конечно - если кто подскажет как это сделать в функции - буду просто щастлив :wink:

и вызов на форме в вычисляемом поле

Код: Выделить всё

f_ExecSQLSelect_3 ( 'exec lsdbo.Ric_Get_pXmlToTable~'' + a_30 +'~'', '' , '' , '' , 10)
-----------------------------------------------------------------------------------------------------
в общем при поддержке http://www.sql.ru и опираясь на тему
Лоция устраивает нас уже на 80%!!!!!!!!!!!!!!!!!!! - http://www.lplm.ru/phpBB2/viewtopic.php?f=21&t=610
хочу поблагодарить всех участников нашего форума (неплохо кстати поработали) и...
...
связь - Осенью во вторник после 10го числа и желательно с утра! (http://www.lplm.ru/phpBB2/viewtopic.php?f=21&t=406) или по мылу...
уходим в самостоятельное плавание :wink: :wink: :wink: :wink: :wink: :wink:

ps
да кстати - про книгу по Лоции - я не забыл! :wink:
Надеюсь выйдет рано или поздно :wink:

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: хранение/обработка/просмотр XML=Строковый атрибут

Сообщение Александр »

кстати что интересно - запрос из вычисляемого поля на форме вида

Код: Выделить всё

f_ExecSQLSelect_3 ( 'SELECT convert(xml,~'<Manager><Filial Name="РПК-Москва" id="0"><User Name="Некроенко Наталья Викторовна" id="23"><Type>Куратор</Type><Set>Проданный</Set><Add>20080211</Add><Del/></User><User Name="Бадерсков Вячеслав Михайлович" id="23"><Type>Менеджер</Type><Set>Проданный</Set><Add>20090711</Add><Del/></User><User Name="Терещенко Елена Игоревна" id="23"><Type>Менеджер</Type><Set>Проданный</Set><Add>20091002</Add><Del/></User></Filial><Filial Name="Академия САПР и ГИС-Москва" id="10"><User Name="Васильева Лидия Евгеньевна" id="100000000"><Type>Менеджер</Type><Set>Проданный</Set><Add>20080213</Add><Del/></User></Filial><Filial Name="Filial_New" id="1"/></Manager>~').query(~'for $s in //User/@Name return concat(string($s), ",")~').value(~'text()[1]~', ~'varchar(255)~')', '' , '' , '' , 10)
прекрасно РАБОТАЕТ - но на ЧИСТОЙ базе Лоции!!!??? и никаких ARITHABORT
к сожалению отличий по сеансу к нашей базе и к чистой (v4.40 настройка CRM) не нашел (или не увидел) - так что вроде работает - но не совсем понятно как (ARITHABORT сброшен и там и там) :wink: так что наверно лучше в явном виде

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1652
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: хранение/обработка/просмотр XML=Строковый атрибут

Сообщение Александр »

еще момент - поскольку оказалось что MSSQL2005 поддерживает еще не все функции XQuery
http://msdn.microsoft.com/en-us/library ... 90%29.aspx
раздел - Non-Supported Features and Workarounds
в хп это можно обойти - скинув данные запроса XQuery в переменную SQL типа таблица и уже здесь использовать нужные функции но уже от другого поставщика - MSSQL
например из полного ФИО получить только Фамилию - в MSSQL2005-XQuery substring-before не поддерживается но прекрасно заменяется функцией MSSQL patindex и т.д.

Код: Выделить всё

 Set ARITHABORT ON
 Declare @tbl table (mFIO varchar(255),
					 mId float,
					 mType varchar(255),
                     mSet varchar(255),
                     mAdd datetime, 
                     mDel datetime)

 Insert Into @tbl 
   Select r.value('@Name[1]', 'varchar(255)') --as mFIO
		  ,r.value('@id[1]', 'float') --as mId
		  ,r.value('(Type/text())[1]', 'varchar(255)') --as [mType]
		  ,r.value('(Set/text())[1]', 'varchar(255)') --as [mSet]
		  ,r.value('(Add/text())[1]', 'datetime') --as [mAdd]
		  ,r.value('(Del/text())[1]', 'datetime') --as [mDel]
	 From @xml.nodes('//User') as t(r)

 if @Mode=0 
     Select * from @tbl   
 if @Mode=1 
     Select left(mFIO,patindex('% %',mFIO)) from @tbl   
  Set ARITHABORT OFF
остальную работу по формированию внешнего вида результата можно отдать Лоции f_ExecSQLSelect_3

Софт - RicCRM<<LotsiaPDM(4.40)<<MsSQL(5/8)
Уровень администрирования - Альтернативный

Ответить