Generating Random Number In Each Row

Случайное число в каждой строке выборки.
Проблемка с SQL Server, в каждой строке выборки одно и то же значение, у PostgreSQL, MySQL, Oracle, SQLite всё нормально.
Выкручиваемся создав представление и функцию.
create view m_vw_randView
as
select rand() as random_number
go

create function getRand()
returns float
as
begin
    declare @returnValue float
	select @returnValue = random_number from m_vw_randView
    return @returnValue
end
go

select rand() [rand], dbo.getRand() [getRand], * from (values(1),(2),(3))t(c1)

rand			getRand			c1
0,63453611784667	0,96496883196861	1
0,63453611784667	0,0616408952549143	2
0,63453611784667	0,280773494594934	3
PostgreSQL v12
select *, random() from generate_series(1,3) t1(c1);
| c1  | random              |
| --- | ------------------- |
| 1   | 0.28302426362094124 |
| 2   | 0.38171190130398003 |
| 3   | 0.35524341401745474 |
MySQL v8.0
with recursive t1(c1) AS
(
  select 1
  union all
  select c1 + 1 from t1 where c1 + 1 <= 3
)
select *, rand() from t1;
| c1  | rand()             |
| --- | ------------------ |
| 1   | 0.8239167740791261 |
| 2   | 0.6890084265628909 |
| 3   | 0.9732918413107208 |
Oracle Database 11g
select level c1, dbms_random.value(0,1) random from dual connect by level <= 3
C1	RANDOM
1	0,457075791676919
2	0,885762460182671
3	0,555152770728942

Recursive CTE Postgres vs MySQL(MariaDB)

Простая задача построение дерева с динамическим количеством уровней вложенности и возможностью настраиваемой сортировки ветвей и листьев

**Schema (PostgreSQL v12)**

create table catalog
    (id int, parent int, name text, ordered int);
    
insert into catalog (id, parent, name, ordered)
    VALUES
    (1, null, 'root10', 10),
    (2, null, 'root2', 8),
    (3, null, 'root1', 1),
    (4, 3, 'child1-root1', 1),
    (5, 3, 'child3-root1', 3),
    (6, 3, 'child2-root1', 2),
    (7, 1, 'child3-root10', 30),
    (8, 1, 'child2-root10', 20),
    (9, 1, 'child1-root10', 10),
    (7, 2, 'child3-root2', 30),
    (8, 2, 'child1-root2', 10),
    (9, 2, 'child2-root2', 20)
    ;
---

**Query #1**

    with recursive
    r as (
    select c1.*, 1 lvl, (row_number() over (partition by parent order by ordered))::text path from catalog c1 where c1.parent is null
      union all
    select c2.*, r.lvl + 1 lvl, concat(r.path, row_number() over (partition by c2.parent order by c2.ordered)) path  from catalog c2, r where c2.parent = r.id
    )
    select * from r
     order by path;

| id  | parent | name          | ordered | lvl | path |
| --- | ------ | ------------- | ------- | --- | ---- |
| 3   |        | root1         | 1       | 1   | 1    |
| 4   | 3      | child1-root1  | 1       | 2   | 11   |
| 6   | 3      | child2-root1  | 2       | 2   | 12   |
| 5   | 3      | child3-root1  | 3       | 2   | 13   |
| 2   |        | root2         | 8       | 1   | 2    |
| 8   | 2      | child1-root2  | 10      | 2   | 21   |
| 9   | 2      | child2-root2  | 20      | 2   | 22   |
| 7   | 2      | child3-root2  | 30      | 2   | 23   |
| 1   |        | root10        | 10      | 1   | 3    |
| 9   | 1      | child1-root10 | 10      | 2   | 31   |
| 8   | 1      | child2-root10 | 20      | 2   | 32   |
| 7   | 1      | child3-root10 | 30      | 2   | 33   |

С Postgres все ОК, в Oracle и MS SQL Server тоже все работает.

MySQL и MariaDB заявляют о поддержке рекурсивных обобщенных табличных выражений, но похоже не полностью.


with recursive
r as (
select c1.*, 1 lvl, convert(row_number() over (partition by parent order by ordered), char) path from catalog c1 where c1.parent is null
  union all
select c2.*, r.lvl + 1 lvl, concat(r.path, convert(row_number() over (partition by c2.parent order by c2.ordered), char)) path  from catalog c2, r where c2.parent = r.id
)
select * from r order by path

MySQL 8.0.12
Query Error: Error: UNKNOWN_CODE_PLEASE_REPORT: Recursive Common Table Expression 'r' can contain neither aggregation nor window functions in recursive query block
---
MariaDB 10.4.12-MariaDB
ER_NOT_STANDARD_COMPLIANT_RECURSIVE (conn=2466, no: 4008, SQLState: HY000) Restrictions imposed on recursive definitions are violated for table 'r' sql: with recursive r as ( select c1.*, 1 lvl, convert(row_number() over (partition by parent order by ordered), char) path from catalog c1 where c1.parent is null union all select c2.*, r.lvl + 1 lvl, concat(r.path, convert(row_number() over (partition by c2.parent order by c2.ordered), char)) path from catalog c2, r where c2.parent = r.id ) select * from r order by path - parameters:[]

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


**Schema (MySQL v8.0)**

    create table catalog
    (id int, parent int, name text, ordered int);
    
    insert into catalog
    (id, parent, name, ordered)
    VALUES
    (1, null, 'root10', 10),
    (2, null, 'root2', 8),
    (3, null, 'root1', 1),
    (4, 3, 'child1-root1', 1),
    (5, 3, 'child3-root1', 3),
    (6, 3, 'child2-root1', 2),
    (7, 1, 'child3-root10', 30),
    (8, 1, 'child2-root10', 20),
    (9, 1, 'child1-root10', 10),
    (10, 2, 'child3-root2', 30),
    (11, 2, 'child1-root2', 10),
    (12, 2, 'child2-root2', 20),
    (13, 8, 'child1-child2-root10', 2),
    (14, 8, 'child2-child2-root10', 3)
    ;    

---

**Query #1**

    with recursive
    r as (
    select c1.*, 1 lvl, convert(row_number() over (partition by parent order by ordered), char) path from catalog c1 where c1.parent is null
      union all
    select c2.*, r.lvl + 1 lvl, concat(r.path, convert(c2.ordered, char)) path  from catalog c2, r where c2.parent = r.id
    )
    select * from r
     order by path;

| id  | parent | name                 | ordered | lvl | path |
| --- | ------ | -------------------- | ------- | --- | ---- |
| 3   |        | root1                | 1       | 1   | 1    |
| 4   | 3      | child1-root1         | 1       | 2   | 11   |
| 6   | 3      | child2-root1         | 2       | 2   | 12   |
| 5   | 3      | child3-root1         | 3       | 2   | 13   |
| 2   |        | root2                | 8       | 1   | 2    |
| 11  | 2      | child1-root2         | 10      | 2   | 210  |
| 12  | 2      | child2-root2         | 20      | 2   | 220  |
| 10  | 2      | child3-root2         | 30      | 2   | 230  |
| 1   |        | root10               | 10      | 1   | 3    |
| 9   | 1      | child1-root10        | 10      | 2   | 310  |
| 8   | 1      | child2-root10        | 20      | 2   | 320  |
| 13  | 8      | child1-child2-root10 | 2       | 3   | 3202 |
| 14  | 8      | child2-child2-root10 | 3       | 3   | 3203 |
| 7   | 1      | child3-root10        | 30      | 2   | 330  |

UPDATE

Ан, нет, проглядел я, без использования оконной функции во втором подзапросе правильный «путь» не получить. В примере все хорошо, так как данные удачно легли.

А если, так, то беда


**Schema (MySQL v8.0)**

    create table catalog
    (id int, parent int, name text, ordered int);
    
    insert into catalog
    (id, parent, name, ordered)
    VALUES
    (1, null, 'root10', 10),
    (2, null, 'root2', 8),
    (3, null, 'root1', 1),
    (4, 3, 'child1-root1', 1),
    (5, 3, 'child3-root1', 10),
    (6, 3, 'child2-root1', 2),
    (7, 1, 'child3-root10', 30),
    (8, 1, 'child2-root10', 20),
    (9, 1, 'child1-root10', 10),
    (7, 2, 'child3-root2', 30),
    (8, 2, 'child1-root2', 10),
    (9, 2, 'child2-root2', 20)
    ;
    
    

---

**Query #1**

    with recursive
    r as (
    select c1.*, 1 lvl, convert(row_number() over (partition by parent order by ordered), char) path from catalog c1 where c1.parent is null  
      union all
    select c2.*, r.lvl + 1 lvl, concat(r.path, convert(c2.ordered, char)) path  from catalog c2, r where c2.parent = r.id
    )
    select * from r
     order by path;

| id  | parent | name          | ordered | lvl | path |
| --- | ------ | ------------- | ------- | --- | ---- |
| 3   |        | root1         | 1       | 1   | 1    |
| 4   | 3      | child1-root1  | 1       | 2   | 11   |
| 5   | 3      | child3-root1  | 10      | 2   | 110  |
| 6   | 3      | child2-root1  | 2       | 2   | 12   |
| 2   |        | root2         | 8       | 1   | 2    |
| 8   | 2      | child1-root2  | 10      | 2   | 210  |
| 9   | 2      | child2-root2  | 20      | 2   | 220  |
| 7   | 2      | child3-root2  | 30      | 2   | 230  |
| 1   |        | root10        | 10      | 1   | 3    |
| 9   | 1      | child1-root10 | 10      | 2   | 310  |
| 8   | 1      | child2-root10 | 20      | 2   | 320  |
| 7   | 1      | child3-root10 | 30      | 2   | 330  |

---

UPDATE 2

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


**Schema (MySQL v8.0)**

    create table catalog
    (id int, parent int, name text, ordered varchar(10));
    
    insert into catalog
    (id, parent, name, ordered)
    VALUES
    (1, null, 'root10', '10'),
    (2, null, 'root2', '08'),
    (3, null, 'root1', '01'),
    (4, 3, 'child1-root1', '01'),
    (5, 3, 'child3-root1', '10'),
    (6, 3, 'child2-root1', '02'),
    (7, 1, 'child3-root10', '30'),
    (8, 1, 'child2-root10', '20'),
    (9, 1, 'child1-root10', '10'),
    (7, 2, 'child3-root2', '30'),
    (8, 2, 'child1-root2', '10'),
    (9, 2, 'child2-root2', '20')
    ;
    
    

---

**Query #1**

    with recursive
    r as (
    select c1.*, 1 lvl, c1.ordered path from catalog c1 where c1.parent is null  
      union all
    select c2.*, r.lvl + 1 lvl, concat(r.path, c2.ordered) path  from catalog c2, r where c2.parent = r.id
    )
    select * from r
     order by path;

| id  | parent | name          | ordered | lvl | path |
| --- | ------ | ------------- | ------- | --- | ---- |
| 3   |        | root1         | 01      | 1   | 01   |
| 4   | 3      | child1-root1  | 01      | 2   | 0101 |
| 6   | 3      | child2-root1  | 02      | 2   | 0102 |
| 5   | 3      | child3-root1  | 10      | 2   | 0110 |
| 2   |        | root2         | 08      | 1   | 08   |
| 8   | 2      | child1-root2  | 10      | 2   | 0810 |
| 9   | 2      | child2-root2  | 20      | 2   | 0820 |
| 7   | 2      | child3-root2  | 30      | 2   | 0830 |
| 1   |        | root10        | 10      | 1   | 10   |
| 9   | 1      | child1-root10 | 10      | 2   | 1010 |
| 8   | 1      | child2-root10 | 20      | 2   | 1020 |
| 7   | 1      | child3-root10 | 30      | 2   | 1030 |

Drop default constraint on a column in TSQL


DECLARE @tableName VARCHAR(MAX) = 'm_PWT'
DECLARE @columnName VARCHAR(MAX) = 'countInDoc'
DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = Name 
FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID(@tableName) 
AND PARENT_COLUMN_ID = (
    SELECT column_id FROM sys.columns
    WHERE NAME = @columnName AND object_id = OBJECT_ID(@tableName))
IF @ConstraintName IS NOT NULL
    EXEC('ALTER TABLE '+@tableName+' DROP CONSTRAINT ' + @ConstraintName)

SQL data types from my query

Иногда нужно узнать типы возвращаемых запросом данных, например для объявления табличной переменной.
Начиная с 2012 SQL Server это легче легкого, для более ранних версий придется создавать временную таблицу из результата запроса, и затем в tempdb.sys.columns.
DECLARE @query nvarchar(max) = '
	select id, measEquiId, zipFlag, psId, dateSet, replaceId, pl1, pl2, pl3, phase, place, joinName, created, whoCreate, dateReplace from (
		select id, measEquiId, zipFlag, dateSet dateReplace, created, whoCreate from [MetrologDev].[dbo].m_eqPlaceParamsList ep
			where ep.deleted is null and ep.zipFlag = 35 and ep.psId = 0 and ep.replaceId=0 
			and not exists (select null from [MetrologDev].[dbo].m_eqPlaceParamsList ep2 where ep2.deleted is null and ep2.measEquiId = ep.measEquiId and ep2.psId <> 0 and ep2.replaceId=0 and ep2.id > ep.id)
			) inZip
		outer apply (
			select id id_r, psId, dateSet, replaceId, pl1, pl2, pl3, phase, place, joinName, created created_r, whoCreate whoCreate_r from (
				select row_number() over(order by id desc) rn, * from [MetrologDev].[dbo].m_eqPlaceParamsList ep
					where inZip.measEquiId=ep.measEquiId and ep.deleted is null and ep.zipFlag = 0 and ep.replaceId<>0)tt where rn=1) isRepl -- пока можно только менять, если снимать, то убираем условие ep.replaceId<>0
';
EXEC sp_describe_first_result_set @query, null, 0;

SELECT FROM stored procedure

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

declare @d1 datetime = convert(datetime, '{$p->dateFromQ}', 104), @d2 datetime = convert(datetime, eomonth(convert(datetime, '{$p->dateToQ}', 104))) + 1.0/1.000001;
exec {$this->db_our}perfReport @d1, @d2;
Стало

select * from 
openquery([LOOPBACK], '
declare @d1 datetime = convert(datetime, ''{$p->dateFromQ}'', 104), @d2 datetime = convert(datetime, eomonth(convert(datetime, ''{$p->dateToQ}'', 104))) + 1.0/1.000001;
exec {$this->db_our}perfReport @d1, @d2
with result sets (( 
	price decimal(25,3), selectedCnt int ,selectedSum decimal(38,3)
	,smoot1 int ,smoot2 int ,approvedInPmes int ,selected int, inOther int
	,id int ,h1_id int ,h2_id int ,h3_id int
	,h1_name varchar(128) ,h2_name varchar(128) ,h3_name varchar(128)
	,h3_extId int ,documentID int ,dName varchar(128)
	,entity varchar(255) ,createdD datetime ,createdDH varchar(30) ,docDateH varchar(30)
	,TIName varchar(4000) ,vr float ,cnt int ,measEquiId int
	,pfId int ,unitPriceId int ,intEntityType int ,hashedName varchar(128)
	,originalName varchar(256) ,moot int ,moot1 int ,moot2 int
	,etName varchar(128) ,ekName varchar(255)
	,ekId int ,serialNumber varchar(64)
	,workNameF varchar(258) ,priceN decimal(14,3)
	,kindId2 int ,isPriced int
))')
 where docDateH between convert(datetime, '{$p->dateFrom}', 104) and convert(datetime, '{$p->dateTo}', 104) + 1.0/1.000001

How remove Memory Optimized File

Моя история избавления от In-Memory OLTP, база на продакшене, так что просто грохнуть ее и забыть, никак.

А началось все с этого: «Msg 41385, Level 16, State 1, Procedure sp_cdc_enable_db, Line 31 [Batch Start Line 2] A database cannot be enabled for both Change Data Capture (CDC) and MEMORY_OPTIMIZED_DATA storage.»

В базе все таблицы в оптимизированные на использование памяти заменил на табличные переменные.
Попытался удалить группу, «The file ‘MOD’ cannot be removed because it is not empty».
Можно пытаться сделать файл пустым и тд и тп, но все будет безрезультатно, потому как читать нужно документацию, и вот что сказал майкрософт, » Once you create a memory-optimized filegroup, you can only remove it by dropping the database. SQL Server does not allow you to remove an In-Memory OLTP filegroup from the database even after you drop all memory-optimized tables.», в общем искоренить MEMORY_OPTIMIZED_DATA storage можно только одним способом дропнув БД.

В моем случае в базе присутствуют таблицы с ограничениями по внешним ключам, а так же таблицы содержащие null-ы при заданном значении по умолчанию для столбца, задействован полнотекстовый поиск.
Ну да ладно, приступим, воспользуемся SQL Server Management Studio (SSMS) и утилитой DTExecUI.exe

1) Создаем скрипт базы. Безымянный1 Безымянный2 Безымянный3 Безымянный4 Безымянный5 Безымянный6

2) Правим полученный файла, удаляем файловую группу, ну и все это во временную БД, для сверки. Безымянный7 Безымянный8
3) Импорт данных («Import data…», курсор на скрине не на том пункте), готовим пакет для импорта, указываем источник, назначение, выбираем таблицы, указываем на необходимость вставки идентификаторов, сохраняем пакет в файл, затем его подправим и отправим на выполнение. Безымянный9 Безымянный10 Безымянный11 Безымянный12 Безымянный13 Безымянный14 Безымянный15 Безымянный16 Безымянный17 Безымянный18
Отключаем контроль ограничений, иначе будет плохо. Безымянный19 Безымянный20
Вот так, плохо. Безымянный20_1
Меняем keepnulls на true, иначе нулы заменятся на значения по умолчанию. Безымянный21 Безымянный22
И отправляем пакет на выполнение. Безымянный23 Безымянный24 Безымянный25

Готово. По этим же шагам можно и понижение версии сделать.


MS SQL OFFSET FETCH

Воспользовавшись предложением offset fetch (аналог mysql-го limit-a) для пагинации, наткнулся на проблемку, при переходе между страницами запрос выдавал тот же результат. В запросе всегда присутствует сортировка по одному из столбцов.
select rr.[rank] r, * v.*, otfile
, try_convert(date, col12, 104) col12D, convert(varchar(10), try_convert(date, col12, 104), 104) col12DH, ceiling((count(*) over())/10.0) pagesTotal from m_dev v
 inner join (select * from (values('4370'),('4371'),('4372'),('4374'),('3461'),('3462'),('3464'),('3465'))t(code)) codes on (v.col10 like codes.code + '%')
 inner join containstable (m_dev, col99, '("трансформатор" or "трансформатор*") and ("тока" or "тока*") and ("италия" or "италия*")', language 1049) rr on (v.id = rr.[key])
 where v.deleted is null 
 order by r
 offset 20 rows fetch next 10 rows only
Грешил на использование полнотекстового поиска, и объединение с результатами функции CONTAINSTABLE, провел эксперименты над данными попроще.
select t1.id1 id1, t1.id2+t2.id2-10 id2 from 
(select * from (values(1,10),(1,20),(1,30),(1,40),(1,50),(1,60),(1,70),(1,80),(1,90)) t (id1, id2)) t1
 cross join (select * from (values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9)) t (id1, id2)) t2
 order by id1
 offset 0 rows fetch next 10 rows only
;

select t1.id1 id1, t1.id2+t2.id2-10 id2 from 
(select * from (values(1,10),(1,20),(1,30),(1,40),(1,50),(1,60),(1,70),(1,80),(1,90)) t (id1, id2)) t1
 cross join (select * from (values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9)) t (id1, id2)) t2
 order by id1
 offset 10 rows fetch next 10 rows only
;

select t1.id1+t2.id1-1 id1, t1.id2+t2.id2-10 id2 from 
(select * from (values(1,10),(1,20),(1,30),(1,40),(1,50),(1,60),(1,70),(1,80),(1,90)) t (id1, id2)) t1
 cross join (select * from (values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9)) t (id1, id2)) t2
 order by id1
 offset 0 rows fetch next 10 rows only
;

select t1.id1+t2.id1-1 id1, t1.id2+t2.id2-10 id2 from 
(select * from (values(1,10),(1,20),(1,30),(1,40),(1,50),(1,60),(1,70),(1,80),(1,90)) t (id1, id2)) t1
 cross join (select * from (values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9)) t (id1, id2)) t2
 order by id1
 offset 10 rows fetch next 10 rows only
;
Получил результаты, соответственно для каждого запроса, появились косяки.
id1	id2		id1	id2		id1	id2		id1	id2
1	1		1	12		1	12		1	12
1	2		1	13		1	11		1	11
1	3		1	14		1	9		1	9
1	4		1	15		1	8		1	8
1	5		1	16		1	7		1	7
1	6		1	17		1	6		1	6
1	7		1	18		1	5		1	5
1	8		1	19		1	4		1	4
1	9		1	21		1	3		1	3
1	11		1	22		1	2		1	2
В плане выполнения появилась сортировка. План выполнения Итого, решаем проблему всегда добавляя последней сортировку по уникальному столбцу. Если его нет, генерим, как в примере. Если есть, как в моем рабочем запросе, в нем я просто добавил
order by r, v.id
select t1.id1+t2.id1-1 id1, t1.id2+t2.id2-10 id2, row_number() over (order by (select 1)) rn from 
(select * from (values(1,10),(1,20),(1,30),(1,40),(1,50),(1,60),(1,70),(1,80),(1,90)) t (id1, id2)) t1
 cross join (select * from (values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9)) t (id1, id2)) t2
 order by id1, rn
 offset 0 rows fetch next 10 rows only
;

select t1.id1+t2.id1-1 id1, t1.id2+t2.id2-10 id2, row_number() over (order by (select 1)) rn from 
(select * from (values(1,10),(1,20),(1,30),(1,40),(1,50),(1,60),(1,70),(1,80),(1,90)) t (id1, id2)) t1
 cross join (select * from (values(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9)) t (id1, id2)) t2
 order by id1, rn
 offset 10 rows fetch next 10 rows only
;

id1	id2	rn		id1	id2	rn
1	1	1		1	12	11
1	2	2		1	13	12
1	3	3		1	14	13
1	4	4		1	15	14
1	5	5		1	16	15
1	6	6		1	17	16
1	7	7		1	18	17
1	8	8		1	19	18
1	9	9		1	21	19
1	11	10		1	22	20

UNPIVOT просто все столбцы в строчки

select * from
  (select * from (values(0,1,1,1,4), (5,6,6,6,9)) t (id1, id2, id3, id4, id5))t
   unpivot (value for columnName in (id1, id2, id3, id4, id5)) ttt
value	columnName
0	id1
1	id2
1	id3
1	id4
4	id5
5	id1
6	id2
6	id3
6	id4
9	id5

Update multiple nodes in SQL XML

Изменить в XML значения в нескольких узлах не получится,
The target of 'replace' must be at most one node, found 'attribute(selectedSum,xdt:untypedAtomic) *'
Выкручиваемся так, в цикле для каждой строки
declare @iCount int;
set @iCount = ( select xmlData.value('count(//*)', 'int') from [Metrolog].[dbo].[m_PWStatus] where deleted is null and pfId=12 and statusId=2 );

declare @i int;
set @i = 1;

declare @repl varchar(30) = '2890659.320';

while (@i <= @iCount)
 begin
 update [Metrolog].[dbo].[m_PWStatus]
  set xmlData.modify('declare namespace ttt="urn:metrolog.fsk-ees.ru"; replace value of (/rows/ttt:row[sql:variable("@i")]/@selectedSum)[1] with sql:variable("@repl")') where deleted is null and pfId=12 and statusId=2;
  update [Metrolog].[dbo].[m_PWStatus]
  set xmlData.modify('declare namespace ttt="urn:metrolog.fsk-ees.ru"; replace value of (/rows/ttt:row[sql:variable("@i")]/@selectedCnt)[1] with "250"') where deleted is null and pfId=12 and statusId=2;
  set @i = @i + 1;
 end

Век живи, век учись, вариант выделения дробной части

Задача, положить дробное число раздельно в два столбца, воспользуемся оператором взятия остатка от деления %, это Лёха подсказал
drop table #test17;

create table #test17(c1 int, c2 decimal(10,10) /*отдадим все 10 знаков на хранение дробной части*/);

insert into #test17
 select c,c from (select 12.34567 c) tt;
-- для MSSQL Arithmetic overflow error converting numeric to data type numeric.
-- The statement has been terminated.
-- или в MySQL Data truncation: Out of range value for column 'c2' at row 1

insert into #test17
 select c,c%1 from (select 12.34567 c) tt;

select * from #test17;

c1	c2
12	0.3456700000

для Оракла функция mod(c, d)