Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по синтаксису Update / 25 сообщений из 112, страница 1 из 5
30.12.2019, 09:22
    #39909728
Zulus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Доброе утро, коллеги!
Помогите пожалуйста развеять сомнения.

Есть такой прекрасный код

Код: 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.
use tempdb
go

if object_id('Repayments', 'U') is not null
 drop table Repayments;

create table dbo.Repayments
(
  AppCode       nvarchar(60) not null
, RepaymentDate	smalldatetime not null
, DocNumber     int not null
)
create clustered index cx_Repayments on dbo.Repayments(AppCode, RepaymentDate)
go

declare
  @Part		varchar(120)
, @DocNumber	int
	
set @Part = ''
set @DocNumber = 1

update t set
  @DocNumber = DocNumber = 
	case 
		when @Part <> AppCode then 1
		else @DocNumber + 1
	end
, @Part = AppCode
from dbo.Repayments t



1. Правильно ли я понимаю, что товарищ хочет получить последовательную нумерацию DocNum в пределах AppCode? Может ещё что-то?
2. Можно ли такую конструкцию считать безопасной для условий
- update без where
- один единственный кластерный индекс как указано в схеме
Или есть у такого синтаксиса "подводные камни"?

Код не мой, думаю "бодаться" с партнёрами из-за него или пусть остаётся..
...
Рейтинг: 0 / 0
30.12.2019, 09:49
    #39909737
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Zulus
Правильно ли я понимаю, что товарищ хочет получить последовательную нумерацию DocNum в пределах AppCode? Может ещё что-то?
Да.
Zulus
Можно ли такую конструкцию считать безопасной для условий
- update без where
- один единственный кластерный индекс как указано в схеме
Можно. На текущий момент.
Но никто не гарантирует, что будет можно после очередного SP, CU или в новой версии.

Мое имхо - лучше переписать.
...
Рейтинг: 0 / 0
30.12.2019, 10:41
    #39909746
Zulus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm
Мое имхо - лучше переписать.

Вот и моё мнение точно такое-же, но тяжеловато с аргументацией для этого конкретного примера :)
invm, спасибо!
...
Рейтинг: 0 / 0
30.12.2019, 10:57
    #39909750
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Zulus
тяжеловато с аргументацией для этого конкретного примера
Данный update предполагает сканирование кластерного индекса.

Сканирование может быть упорядоченное - в порядке ключей индеса, а может быть неупорядоченное - в порядке распределения страниц. Во втором случае, вместо последовательной нумерации может получиться каша.

Насколько я знаю, сейчас неупорядоченное сканирование к update неприменимо. Но будет ли так и далее - никто не знает.
...
Рейтинг: 0 / 0
30.12.2019, 11:15
    #39909754
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Zulus,

Создание таблицы

Код: sql
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE dbo.Repayments
             (AppCode       NVARCHAR(60) NOT NULL
            , RepaymentDate SMALLDATETIME NOT NULL
            , DocNumber     INT NOT NULL
             );
CREATE CLUSTERED INDEX cx_Repayments ON dbo.Repayments(AppCode, RepaymentDate);
GO



Наполнение данными
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
INSERT INTO dbo.Repayments(AppCode      
            , RepaymentDate 
            , DocNumber    )
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT 'a', GETDATE(), 0 UNION ALL 
SELECT 'b', GETDATE(), 0 UNION ALL 
SELECT 'c', GETDATE(), 0 UNION ALL 
SELECT 'd', GETDATE(), 0 UNION ALL 
SELECT 'e', GETDATE(), 0 UNION ALL 
SELECT 'f', GETDATE(), 0 



Обновление

Код: 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.
DECLARE @Part      VARCHAR(60) = '';

WITH a
     AS (
     SELECT 
            CASE
                WHEN AppCode = @Part THEN 1
                ELSE 0
            END+ROW_NUMBER() OVER(PARTITION BY CASE
                                                   WHEN AppCode = @Part THEN @Part
                                                   ELSE CONVERT(VARCHAR(36), NEWID())
                                               END ORDER BY
                                                           (
                                                            SELECT 
                                                                   1
                                                            )) AS rn
          , DocNumber
     FROM 
          dbo.Repayments)
     UPDATE a
       SET 
           DocNumber = rn;

SELECT 
       *
FROM 
     dbo.Repayments;
...
Рейтинг: 0 / 0
30.12.2019, 11:52
    #39909771
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
Обновление

Код: 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.
DECLARE @Part      VARCHAR(60) = '';

WITH a
     AS (
     SELECT 
            CASE
                WHEN AppCode = @Part THEN 1
                ELSE 0
            END+ROW_NUMBER() OVER(PARTITION BY CASE
                                                   WHEN AppCode = @Part THEN @Part
                                                   ELSE CONVERT(VARCHAR(36), NEWID())
                                               END ORDER BY
                                                           (
                                                            SELECT 
                                                                   1
                                                            )) AS rn
          , DocNumber
     FROM 
          dbo.Repayments)
     UPDATE a
       SET 
           DocNumber = rn;

SELECT 
       *
FROM 
     dbo.Repayments;

Это такое тонкое издевательство над сервером?
Все гораздо банальнее.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
with a as
(
 select
  DocNumber, row_number() over (partition by AppCode order by AppCode, RepaymentDate) as n
 from
  dbo.Repayments
)
update a
 set
  DocNumber = n;
...
Рейтинг: 0 / 0
30.12.2019, 12:08
    #39909775
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm,

авторВсе гораздо банальнее.

Все ещё гораздо более банальнее.

вот код автора

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
declare
  @Part		varchar(120)
, @DocNumber	int
	
set @Part = ''
set @DocNumber = 1

update t set
  @DocNumber = DocNumber = 
	case 
		when @Part <> AppCode then 1
		else @DocNumber + 1
	end
, @Part = AppCode
from dbo.Repayments t

SELECT * FROM dbo.Repayments



вот результат выполнения кода автора (и моего)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
AppCode                                                      RepaymentDate           DocNumber
------------------------------------------------------------ ----------------------- -----------
                                                             2019-12-30 11:58:00     2
                                                             2019-12-30 11:58:00     3
                                                             2019-12-30 11:58:00     4
                                                             2019-12-30 11:58:00     5
                                                             2019-12-30 11:58:00     6
                                                             2019-12-30 11:58:00     7
a                                                            2019-12-30 11:58:00     1
b                                                            2019-12-30 11:58:00     1
c                                                            2019-12-30 11:58:00     1
d                                                            2019-12-30 11:58:00     1
e                                                            2019-12-30 11:58:00     1
f                                                            2019-12-30 11:58:00     1



вот результат выполнения Вашего кода

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
AppCode                                                      RepaymentDate           DocNumber
------------------------------------------------------------ ----------------------- -----------
                                                             2019-12-30 11:58:00     1
                                                             2019-12-30 11:58:00     2
                                                             2019-12-30 11:58:00     3
                                                             2019-12-30 11:58:00     4
                                                             2019-12-30 11:58:00     5
                                                             2019-12-30 11:58:00     6
a                                                            2019-12-30 11:58:00     1
b                                                            2019-12-30 11:58:00     1
c                                                            2019-12-30 11:58:00     1
d                                                            2019-12-30 11:58:00     1
e                                                            2019-12-30 11:58:00     1
f                                                            2019-12-30 11:58:00     1
...
Рейтинг: 0 / 0
30.12.2019, 12:28
    #39909786
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
вот результат выполнения кода автора
Нет. Это результат выполнения кода автора на вашем примере и с вашими начальными значениями переменных.

А чтобы правильно готовить примеры, нужно понять как работает код автора. Тогда монстры, подобные вашему, не потребуются.
...
Рейтинг: 0 / 0
30.12.2019, 12:45
    #39909795
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm,

согласен
...
Рейтинг: 0 / 0
30.12.2019, 12:58
    #39909804
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm,

Правильно будет так

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
DECLARE @Part VARCHAR(60) = '';
WITH a
     AS (
     SELECT 
            CASE
                WHEN AppCode = @Part THEN 1
                ELSE 0
            END
            + ROW_NUMBER() OVER(PARTITION BY AppCode ORDER BY AppCode
                                                            , RepaymentDate) AS rn
          , DocNumber
     FROM 
          dbo.Repayments)
     UPDATE a
       SET 
           DocNumber = rn;



Но,

не могли бы Вы наполнить таблицу данными так, чтобы код автора и Ваш код при выполнении давали одинаковый результат ?
используя все возможные значения для поля AppCode ))) в том числе и '', никаких же ограничений на это поле, кроме NOT NULL - нет ?
...
Рейтинг: 0 / 0
30.12.2019, 13:06
    #39909812
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
не могли бы Вы наполнить таблицу данными так, чтобы код автора и Ваш код при выполнении давали одинаковый результат ?
Вы почему-то решили, что @Part нужно инициализировать первым значением из таблицы. Отсюда все проблемы.
Чтобы исходный код и мой давали одинаковый результат @Part нужно инициализировать значением, которого нет в таблице .
...
Рейтинг: 0 / 0
30.12.2019, 13:09
    #39909815
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm,

нет, это не я решил, вот код автора

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
create table dbo.Repayments
(
  AppCode       nvarchar(60) not null
, RepaymentDate	smalldatetime not null
, DocNumber     int not null
)
create clustered index cx_Repayments on dbo.Repayments(AppCode, RepaymentDate)
go

declare
  @Part		varchar(120)
, @DocNumber	int
	
set @Part = ''
set @DocNumber = 1




обратите внимание
авторset @Part = ''
и
авторAppCode nvarchar(60) not null позволяет хранить любые строковые значения отличные от NULL, или я не прав ?

авторЧтобы исходный код и мой давали одинаковый результат @Part нужно инициализировать значением, которого нет в таблице.
Это же не согласуется с определением таблицы и кодом автора ?
...
Рейтинг: 0 / 0
30.12.2019, 13:45
    #39909841
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
нет, это не я решил
Да нет, именно Вы.
Почему-то решили, что если set @Part = '', то и первая строка в таблице должна быть с AppCode = ''

Я же говорю - Вы не разобрались, как работает данный update.
...
Рейтинг: 0 / 0
30.12.2019, 14:26
    #39909860
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm,

Ну как не конструктивно, ну если есть у автора возможный изъян в логике (а может и предусмотренное поведение), почему не говорить о CHECK на поле AppCode, который не позволит вставить '', но сейчас-то в этих условиях я делаю все что позволяет приведённая структура

авторПочему-то решили, что если set @Part = '', то и первая строка в таблице должна быть с AppCode = ''

не я это решил, опять же структура данных, если я сделаю
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
INSERT INTO dbo.Repayments(AppCode      
            , RepaymentDate 
            , DocNumber    )
SELECT 'a', GETDATE(), 0 UNION ALL 
SELECT 'b', GETDATE(), 0 UNION ALL 
SELECT 'c', GETDATE(), 0 UNION ALL 
SELECT 'd', GETDATE(), 0 UNION ALL 
SELECT 'e', GETDATE(), 0 UNION ALL 
SELECT 'f', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 


то все равно строки со значением AppCode = '' будут первыми потому что
Код: sql
1.
create clustered index cx_Repayments on dbo.Repayments(AppCode, RepaymentDate)

(опять же структура)

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

Повторюсь, не конструктивно, хотите доказать свою точку зрения как минимум покажите такой же результат, что и до рефакторинга, с использованием среза данных, параметры которых описаны в структуре таблицы, а не ссылайтесь на условия, которых нет в постановке задачи.
...
Рейтинг: 0 / 0
30.12.2019, 14:31
    #39909867
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
все равно строки со значением AppCode = '' будут первым
C каких это пор кластерный индекс гарантирует порядок записей?
Только ORDER BY в запросе!
...
Рейтинг: 0 / 0
30.12.2019, 14:38
    #39909872
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
не я это решил, опять же структура данных, если я сделаю
Решили именно Вы.
У автора типичная задача - пронумеровать строки в разрезе определенного критерия и в определенном порядке.
А не ту, котору придумали Вы - "Записать в DocNumber последовательно возрастающее значение, начиная с 2 для всех AppCode = '', а для остальных AppCode - 1"
...
Рейтинг: 0 / 0
30.12.2019, 14:40
    #39909874
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
iap,

Код: 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.
CREATE TABLE dbo.Repayments
             (AppCode       NVARCHAR(60) NOT NULL
            , RepaymentDate SMALLDATETIME NOT NULL
            , DocNumber     INT NOT NULL
             );
CREATE CLUSTERED INDEX cx_Repayments ON dbo.Repayments(AppCode, RepaymentDate);
GO

INSERT INTO dbo.Repayments(AppCode      
            , RepaymentDate 
            , DocNumber    )
SELECT 'a', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT 'b', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT 'c', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT 'd', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT 'e', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 UNION ALL 
SELECT 'f', GETDATE(), 0 UNION ALL 
SELECT '',  GETDATE(), 0 

SELECT 
       AppCode
     , RepaymentDate
     , DocNumber
FROM 
     dbo.Repayments;



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
AppCode                                                      RepaymentDate           DocNumber
------------------------------------------------------------ ----------------------- -----------
                                                             2019-12-30 14:39:00     0
                                                             2019-12-30 14:39:00     0
                                                             2019-12-30 14:39:00     0
                                                             2019-12-30 14:39:00     0
                                                             2019-12-30 14:39:00     0
                                                             2019-12-30 14:39:00     0
a                                                            2019-12-30 14:39:00     0
b                                                            2019-12-30 14:39:00     0
c                                                            2019-12-30 14:39:00     0
d                                                            2019-12-30 14:39:00     0
e                                                            2019-12-30 14:39:00     0
f                                                            2019-12-30 14:39:00     0



Нет ?
...
Рейтинг: 0 / 0
30.12.2019, 14:44
    #39909879
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Результат, критерий истины только результат, код в студию

Может Вы диагноз неправильно поставили ?

invm
Zulus
Правильно ли я понимаю, что товарищ хочет получить последовательную нумерацию DocNum в пределах AppCode? Может ещё что-то?
Да.
Zulus
Можно ли такую конструкцию считать безопасной для условий
- update без where
- один единственный кластерный индекс как указано в схеме
Можно. На текущий момент.
Но никто не гарантирует, что будет можно после очередного SP, CU или в новой версии.

Мое имхо - лучше переписать.
...
Рейтинг: 0 / 0
30.12.2019, 15:30
    #39909914
Zulus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
iap, моё почтение!
Согласен с тем, что порядок записей гарантируется order by, но в данном случае других вариантов не вижу:
- кластерный индекс (один единственный)
- параллелизма нет (для текущей версии)

Коллеги, спасибо всем участникам :)
Код не мой - я как раз хочу его переделать, но 100% владелец будет вредничать и задавать много "почему"
...
Рейтинг: 0 / 0
30.12.2019, 15:37
    #39909917
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Всех с наступающим НГ !!!
Спасибо за обсуждение !!!
...
Рейтинг: 0 / 0
30.12.2019, 15:39
    #39909918
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
entrypoint
Может Вы диагноз неправильно поставили ?
Возможно. Но мой диагноз гораздо боле правдоподобен, чем Ваш.
entrypoint
Нет ?
В общем случае, нет.
Почему, объяснено тут - 22051347
...
Рейтинг: 0 / 0
30.12.2019, 16:05
    #39909937
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
invm,

Там добавление данных INSERT, а не UPDATE про который вы пишите.

Субъективные выводы, ссылки на самого же себя, а главное, полное игнорирование доводов, нет ни одного довода, который я бы не подкрепил кодом

invm
entrypoint
Может Вы диагноз неправильно поставили ?
Возможно. Но мой диагноз гораздо боле правдоподобен, чем Ваш.
entrypoint
Нет ?
В общем случае, нет.
Почему, объяснено тут - 22051347


как можно написать такое когда приведен довод в виде кода, который можно запустить, покрутить, попробовать.

Может, если у вас нет желания создать массив данных, с которыми бы отработал Ваш код, у Вас есть желание опровергнуть
Код: sql
1.
create clustered index cx_Repayments on dbo.Repayments(AppCode, RepaymentDate)

не на словах, а кодом ?
...
Рейтинг: 0 / 0
30.12.2019, 16:09
    #39909940
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
Zulus,

Да, порядок строк только ORDER BY, но в данном случае я говорю о том, что первой в таблице будет любая строка со значением AppCode=''.
...
Рейтинг: 0 / 0
30.12.2019, 16:20
    #39909945
nullin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
кстати дубли с AppCode != '' никто не отменял, так что почему нумеровать
в нелогичном случае нужно именно с двух тоже не понятно
...
Рейтинг: 0 / 0
30.12.2019, 16:46
    #39909961
entrypoint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по синтаксису Update
nullin,

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

Все доводы моего оппонента в лице invm, основаны на предположениях не подкрепленных ничем - "entrypoint не понимает", "entrypoint не разобрался", "entrypoint ошибается", я же в свою очередь следую только той информации, которая была представлена автором и свои доводы подкрепляю ссылками на структуру базы данных (представленную автором), примерами кода, результатами сравнения.

invm, утверждает что я не могу использовать значение '' для AppCode, но я вижу что структура таблицы мне это не запрещает, это одно из валидных значений этой колонки, я утверждаю что согласно опять же структуре таблицы первыми строками в таблице всегда будут строки со значением AppCode='' независимо от порядка вставки, и.т.д. и.т.п., в ответ я получаю бездоказательные возражения

Это некорректно, непрофессионально, с учетом того, что код представленный invm выдает результат отличный от результата автора.

Код, только код критерий истины
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по синтаксису Update / 25 сообщений из 112, страница 1 из 5
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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