Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Update через цикл While  [new]
Sadmann
Member

Откуда:
Сообщений: 8
Доброго вечера!
Подскажите пожалуйста где я тут не прав, заранее спасибо!

 set nocount on
   if isnull(object_id('tempdb..#t1'),0) <> 0
     drop table #t1

    create table #t1 (
                     ID          int identity(1,1)
                     FirstValue  varchar(20),
                     SecondValue varchar(20)
                     )

    insert into #t1 (FirstValue, SecondValue)
    select '', '1.1 Клиенты'  union all
    select '', 'Клиент 1'     union all
    select '', 'Клиент 2'     union all
    select '', 'Клиент 3'     union all
    select '', '1.2 Партнеры' union all
    select '', 'Партнер 1'    union all
    select '', 'Партнер 2'    union all
    select '', 'Партнер 3'    

    begin tran

    declare @ID          int,
            @SecondValue varchar(20)

    select @ID          = 0
           @SecondValue = ''

    while 1 = 1
    begin
    select @ID = min(ID)
      from #t1
     where ID > @ID
    if @ID is null break

    select @SecondValue = SecondValue
      from #t1
     where ID = @ID

    if isnull(@SecondValue,'') <> ''
    begin
      update #t1
      set FirstValue = (
                        select top 1 SecondValue
                          from #t1
                         where ID <= @ID
                           and SecondValue like '1.%'
                        order by ID desc
                       )
      where FirstValue = ''
    end
    end

    rollback


Получается:
https://i.stack.imgur.com/hr8u4.png

А нужно:
https://i.stack.imgur.com/CnyDf.png

Сообщение было отредактировано: 13 фев 20, 19:53
13 фев 20, 19:51    [22079555]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30427
Sadmann
Подскажите пожалуйста где я тут не прав, заранее спасибо!
Во первых, как вы отлаживаете, если у вас скрипт синтаксически неверный? Вы бы попробовали его выполнить, вы там пару запятых пропустили.

А не правы вы в том, что в UPDATE забыли добавить условие
and ID = @ID

и поэтому первый же апдэйт измкенил все записи в таблице, а остальные апдэйты в цикле не отрабатывали из за условия
FirstValue = ''
(которое на самом деле вообще не нужно)
13 фев 20, 20:18    [22079564]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
Sadmann
Member

Откуда:
Сообщений: 8
За ошибки извиняюсь, студия стоит там где нет интернета, и нельзя скопировать, набирал вручную в сообщении.
За разъяснения большое спасибо!)
13 фев 20, 20:33    [22079572]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
PsyMisha
Member

Откуда: другая столица
Сообщений: 698
Sadmann

набирал вручную в сообщении


... и табуляцию всю в строках?? Уважаю!! :)
14 фев 20, 10:13    [22079780]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
nullin
Member

Откуда: pullin
Сообщений: 112
А в чем смысл циклы городить?
Для случая, если упорядочение по ID допускает, что 1.0 может появиться после 1.1
Предполагаю, только данный факт мог сподвигнуть на такое.

with u(FirstValue, uFirstValue) as
(select t.FirstValue
      , stuff(max(iif(t.SecondValue like '1.%'
                    , concat(convert(char(10), t.ID), t.SecondValue)
                    , ''))
              over(order by t.ID)
            , 1
            , 10
            , '')
   from #t1 t)
   
update u
   set FirstValue = uFirstValue

А если нет, то достаточно
max(iif(t.SecondValue like '1.%', t.SecondValue, '')) over(order by t.ID) a
14 фев 20, 10:47    [22079804]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
nullin
Member

Откуда: pullin
Сообщений: 112
nullin, не convert(char(10), id) а str(id, 10)
14 фев 20, 11:07    [22079815]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
entrypoint
Member

Откуда:
Сообщений: 227
Sadmann,

WITH a (id, val) AS (
    SELECT  1, '1.1 Клиенты'  UNION ALL
    SELECT  2, 'Клиент 1'     UNION ALL
    SELECT  3, 'Клиент 2'     UNION ALL
    SELECT  4, 'Клиент 3'     UNION ALL
    SELECT  5, '1.2 Партнеры' UNION ALL
    SELECT  6, 'Партнер 1'    UNION ALL
    SELECT  7, 'Партнер 2'    UNION ALL
    SELECT  8, 'Партнер 3')
SELECT 
       a.id
     , z.a AS   FirstValue
     , a.val AS SecondValue
FROM 
     a
     CROSS APPLY
                (
                 SELECT TOP (1) 
                        b.val
                 FROM 
                      a AS b
                 WHERE b.id <= a.id
                       AND b.val LIKE '%[0-9].[0-9]%'
                        ORDER BY 
                                 b.id DESC
     ) AS z(a);
14 фев 20, 12:17    [22079879]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
nullin
Member

Откуда: pullin
Сообщений: 112
nullin, точнее без танцев с бубном немного не обошлось:
with u(FirstValue, uFirstValue) as
(select t.FirstValue
      , stuff(max(iif(t.SecondValue like '%.%' and t.SecondValue not like '[^.0-9]%'
                    , concat(str(t.ID, 10), t.SecondValue)
                    , ''))
               over(order by t.ID), 1, 10, '') uFirstValue

   from #t1 t)
   
update u
   set FirstValue = uFirstValue
 where uFirstValue like '1.%'

fiddle
14 фев 20, 12:23    [22079885]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30427
nullin
А в чем смысл циклы городить?
Очевидно, такое задание дал препод.
Вариант с одним запросом уже дали, в соседней теме ТС.
14 фев 20, 12:24    [22079887]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
entrypoint
Member

Откуда:
Сообщений: 227
Sadmann,

или так

WITH a (id, val) AS (
    SELECT  1, '1.1 Клиенты'  UNION ALL
    SELECT  2, 'Клиент 1'     UNION ALL
    SELECT  3, 'Клиент 2'     UNION ALL
    SELECT  4, 'Клиент 3'     UNION ALL
    SELECT  5, '1.2 Партнеры' UNION ALL
    SELECT  6, 'Партнер 1'    UNION ALL
    SELECT  7, 'Партнер 2'    UNION ALL
    SELECT  8, 'Партнер 3')
SELECT 
       a.id
     , z.a AS   FirstValue
     , a.val AS SecondValue
FROM 
     a
     CROSS APPLY
                (
                 SELECT TOP (1) 
                        b.val
                 FROM 
                      a AS b
                 WHERE b.id <= a.id
                       AND b.val LIKE '%[0-9].[0-9]%'
                        ORDER BY 
                                 b.id DESC
     ) AS z(a)
WHERE a.val NOT LIKE '%[0-9].[0-9]%';
14 фев 20, 12:27    [22079891]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
nullin
Member

Откуда: pullin
Сообщений: 112
alexeyvg
nullin
А в чем смысл циклы городить?
Очевидно, такое задание дал препод.
Вариант с одним запросом уже дали, в соседней теме ТС.

Хорошо немножко мозги размять, делая в один проход.

Сообщение было отредактировано: 14 фев 20, 12:34
14 фев 20, 12:33    [22079903]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7319
Sadmann,

isnull(@SecondValue,'') <> ''


Бредовое выражение, т.к null никогда не равен пустой строке и вообще какой-бы то ни было строке.

declare @SecondValue char;

if isnull(@SecondValue,'') <> ''
	print 'ok'
else
	print 'bad'

if @SecondValue <> ''
	print 'ok'
else
	print 'bad'
14 фев 20, 12:34    [22079904]     Ответить | Цитировать Сообщить модератору
 Re: Update через цикл While  [new]
msLex
Member

Откуда:
Сообщений: 7601
Владислав Колосов
Бредовое выражение, т.к null никогда не равен пустой строке и вообще какой-бы то ни было строке.


Любое сравнение с null дает unknown а не false. В вашем простом примере @SecondValue <> '' результатом вычисление логического выражения будет unknown, и так как это не true, то выполнение уйдет в ветку else.

Достаточно поместить ваше @SecondValue <> '' в более сложное условие not (@SecondValue <> ''), и результат меняется, т.к. not от unknown это тоже unknown.


declare @SecondValue char;

if not (isnull(@SecondValue,'') <> '')
	print 'ok'
else
	print 'bad'

if not (@SecondValue <> '')
	print 'ok'
else
	print 'bad'


Сообщение было отредактировано: 14 фев 20, 14:25
14 фев 20, 14:26    [22080035]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить