powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / xml modify insert добавить идентификатор
6 сообщений из 6, страница 1 из 1
xml modify insert добавить идентификатор
    #39595830
alol55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, помогите, пожалуйста, разобраться с задачей.
Есть вот такой xml:

Код: sql
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.
DECLARE @x xml; 
SET @x = 
'<СТАЖ> 
                <Работник> 
                        <ФИО> 
                                <Фамилия>ИВАНОВ</Фамилия> 
                                <Имя>ИВАН</Имя> 
                                <Отчество>ИВАНОВИЧ</Отчество> 
                        </ФИО>                 
                        <Работа> 
                                <Период> 
                                        <С>2017-01-01</С> 
                                        <По>2017-09-10</По> 
                                </Период> 
                        </Работа> 
                        <Работа> 
                                <Период> 
                                        <С>2017-09-11</С> 
                                        <По>2017-10-08</По> 
                                </Период> 
                        </Работа> 
                </Работник> 
                <Работник> 
                        <ФИО> 
                                <Фамилия>ИВАНОВА</Фамилия> 
                                <Имя>МАРИЯ</Имя> 
                                <Отчество>СЕРГЕЕВНА</Отчество> 
                        </ФИО> 
                        <Работа> 
                                <Период> 
                                        <С>2017-01-01</С> 
                                        <По>2017-08-06</По> 
                                </Период> 
                        </Работа> 
                        <Работа> 
                                <Период> 
                                        <С>2017-08-07</С> 
                                        <По>2017-08-20</По> 
                                </Период> 
                        </Работа> 
                </Работник> 
</СТАЖ> 
'; 



Нужно добавить нумерацию в ноды с работниками и в ноды с периодами работы. Я делаю так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
declare @p int = 1, @c int; 
declare @str xml 

select @c = @x.query('count(//СТАЖ/Работник)').value('.', 'int'); 
while @p <= @c 
 begin 
   select @str='<Номер>'+cast(@p as varchar(2))+'</Номер>' 

  set @x.modify('insert sql:variable("@str") as first into (((//СТАЖ/Работник)[position() = sql:variable("@p")])[1])'); 
  select @p += 1; 
 end; 

select @x;



Идентификатор добавляется правильно. Теперь тот же метод применяю к периодам работы, но мне надо, чтобы для каждого работника нумерация периодов начиналась с 1. При таком коде она получается сквозной, то есть неправильной. Подскажите, плиз, как код исправить.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
set @p=1 
select @c = @x.query('count(//СТАЖ/Работник/Работа)').value('.', 'int'); 
while @p <= @c 
 begin 
   select @str='<Номер>'+cast(@p as varchar(2))+'</Номер>' 

  set @x.modify('insert sql:variable("@str") as first into (((//СТАЖ/Работник/Работа)[position() = sql:variable("@p")])[1])'); 
  select @p += 1; 
 end; 


select @x;



И заодно еще один вопрос: можно ли такую модификацию выполнить без циклов? На маленьких xml это работает быстро, но на больших (200-300 тыс. записей), боюсь, будет тормозить.
...
Рейтинг: 0 / 0
xml modify insert добавить идентификатор
    #39595908
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alol55,

Код: sql
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.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
DECLARE @x xml; 
SET @x = 
'<СТАЖ> 
                <Работник> 
                        <ФИО> 
                                <Фамилия>ИВАНОВ</Фамилия> 
                                <Имя>ИВАН</Имя> 
                                <Отчество>ИВАНОВИЧ</Отчество> 
                        </ФИО>                 
                        <Работа> 
                                <Период> 
                                        <С>2017-01-01</С> 
                                        <По>2017-09-10</По> 
                                </Период> 
                        </Работа> 
                        <Работа> 
                                <Период> 
                                        <С>2017-09-11</С> 
                                        <По>2017-10-08</По> 
                                </Период> 
                        </Работа> 
                </Работник> 
                <Работник> 
                        <ФИО> 
                                <Фамилия>ИВАНОВА</Фамилия> 
                                <Имя>МАРИЯ</Имя> 
                                <Отчество>СЕРГЕЕВНА</Отчество> 
                        </ФИО> 
                        <Работа> 
                                <Период> 
                                        <С>2017-01-01</С> 
                                        <По>2017-08-06</По> 
                                </Период> 
                        </Работа> 
                        <Работа> 
                                <Период> 
                                        <С>2017-08-07</С> 
                                        <По>2017-08-20</По> 
                                </Период> 
                        </Работа> 
                </Работник> 
</СТАЖ> 
'; 

declare @t table (
      employee_id int,
      job_id int,
      employee_data xml,
      job_data xml
);

declare @t2 table (edata xml, jdata xml);

with Employees as (
    select row_number() over (order by (select 1)) as id,
           T.c.query('.') as xdata
    from @x.nodes('/СТАЖ/Работник') T(c)
),
Jobs as (
    select
          e.id as employee_id,
          row_number() over (partition by e.id order by (select 1)) as id,
          e.xdata as x,
          T.c.query('.') as xdata
    from Employees e
        cross apply e.xdata.nodes('/Работник/Работа') T(c)
)
insert into @t
select * from Jobs


update @t
   set job_data.modify('insert <Номер>{sql:column("job_id")}</Номер> as first into (/Работа)[1]'),
       employee_data.modify('insert <Номер>{sql:column("employee_id")}</Номер> as first into (/Работник)[1]')

update @t
   set employee_data.modify('delete (/Работник/Работа)')

;with x as (
    select row_number() over (partition by employee_id order by employee_id) as e_id,
           employee_id,
           employee_data
    from @t
)
, y as (
select x.employee_data as employee_data,
       tx.x as x
from x 
      cross apply (select job_data.query('.') from @t t where t.employee_id = x.employee_id for xml path(''), type) tx(x)
where e_id = 1
)
insert into @t2
select employee_data, x
from y

update @t2
   set edata.modify('insert sql:column("jdata") into (Работник)[1]')

select edata.query('.') from @t2 for xml path(''), root('СТАЖ')



Думаю можно и попроще если сконвертировать с реляционный вид и потом в обратную собрать результирующую xml. Но в пятницу сильно напрягаться не хочется, уж извиняйте
...
Рейтинг: 0 / 0
xml modify insert добавить идентификатор
    #39595983
alol55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff,

с ума сойти, это работает)
Спасибо вам огромное!!
...
Рейтинг: 0 / 0
xml modify insert добавить идентификатор
    #39596006
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alol55,

Как и писал felix_ff , можно гораздо проще и без modify:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select
 row_number() over (order by (select 1)) as [Номер],
 t.n.query('ФИО'),
 j.x as [*]
from
 @x.nodes('/СТАЖ/Работник') t(n) cross apply
 (
  select
   row_number() over (order by (select 1)) as [Номер],
   a.n.query('*')
  from
   t.n.nodes('Работа') a(n)
  for xml path('Работа'), type
 ) j(x)
for xml path('Работник'), root('СТАЖ'), type;
...
Рейтинг: 0 / 0
xml modify insert добавить идентификатор
    #39596127
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alol55,

вариант предложенный invm сильно лучше моего берите его за основу.
...
Рейтинг: 0 / 0
xml modify insert добавить идентификатор
    #39596381
alol55
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,

вам тоже спасибо огромное)
Буду пробовать оба варианта на больших xml, какой сработает быстрее, тот и возьму
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / xml modify insert добавить идентификатор
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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