Конференция "Базы" » Update одной таблицы по условию из другой таблицы [DB2]
 
  • Юрий Зотов © (18.05.09 15:25) [0]
    Люди, что-то не соображу как сделать следующее

    Есть таблица T1 с полями K11 (int), K12 (int), F1 (char) и таблица T2 с полями K21 (int), K22 (int), F2 (char). Поля K11 и K12 есть составной ключ некоего документа, такой же ключ составляют поля K21 и K22.

    Требуется проапдейтить поле F1 в записях таблицы T1, удовлетворяющих условию:

    T1.K11 = T2.K21
    and
    T1.K12 = T2.K22
    and
    T2.F2 = 'НЕЧТО'

    И в силу недостаточного знания SQL не могу сообразить, как этот update написать. Поможите кто добрый, плз.
  • Игорь Шевченко © (18.05.09 15:37) [1]
    update t1 a set ...
    where (a.k11, a.k12) in (select b.k21,b.k22 from t2 b where b.f2 = 'НЕЧТО')

    ?
  • Игорь Шевченко © (18.05.09 15:39) [2]
    или exists

    update t1 a set ...
    where exists (select null from t2 b where b.k21 = a.k11 and b.k22 = a.k12 and b.f2 = 'НЕЧТО')
  • Romkin © (18.05.09 15:42) [3]
    Чем апдейтить-то? :)
    create table T1 (K11 int not null, K12 int not null, F1 char(<...>), primary key (K11, K12));
    create table T2 (K21 int not null, K22 int not null, F2 char(<...>), primary key (K21, K22));


    Вообще решение зависит от того, насколько полно поддерживается стандарт SQL, чего я о DB2 не знаю :(
    1.
    update T1 set F1 = <...>
    where (K11, K12) in (select K21, K22 from T2 where F2= 'НЕЧТО');


    2.
    update T1 set F1 = <...>
    where exists (select * from T2 where T2.K21 = T1.K11 and T2.K22 = T1.K12 and T2.F2 = 'НЕЧТО');

  • Romkin © (18.05.09 15:43) [4]
    :D
  • Игорь Шевченко © (18.05.09 15:47) [5]
    Romkin ©   (18.05.09 15:42) [3]

    :D
  • Ega23 © (18.05.09 16:06) [6]

    > Требуется проапдейтить поле F1 в записях таблицы T1, удовлетворяющих
    > условию:


    А на что идёт Update F1? На значение T2.F2 (в данном случае - 'НЕЧТО')?
  • sniknik © (18.05.09 16:08) [7]
    а явных джойнов DB2 не поддерживает?

    UPDATE T1
    SET T1.F1 = T1.F1 + T2.F1
    FROM T1 INNER JOIN T2 ON (T1.K11 = T2.K21 and T1.K12 = T2.K22 and T2.F2 = 'НЕЧТО')



    имхо проще.
  • sniknik © (18.05.09 16:11) [8]
    > имхо проще.
    да и быстрее должно быть чем с перезапросом на каждую запись.
  • Ega23 © (18.05.09 16:14) [9]
    Короче, должно сработать как-то так

    Update T1 set
     T1.F1 = ...
    from T1 inner join T2 on (T1.K11=T2.K21 and T1.K12=T2.K22 and T2.F2='НЕЧТО')



    Только у меня сомнения насчёт того, что должно в  
    T1.F1 = ...

    стоять. Вроде, там и значение из T1 и из T2 должно быть.

    З.Ы. Кстати. Так и не смог придумать тестового примера, дабы данные расходились...  :)
  • Ega23 © (18.05.09 16:15) [10]

    > sniknik ©   (18.05.09 16:08) [7]


    :)
  • Anatoly Podgoretsky © (18.05.09 16:18) [11]
    Юрий Зотов ©   (18.05.09 15:25)  
    До Update желательно написать работающий SELECT и тогда будет видно что проапдейтится и правильно, затем заменишь SELECT на Update
  • sniknik © (18.05.09 16:18) [12]
    немного поправлюсь, а то запрос получился логически неверным. не стоит смешивать условия объединения с условиями  отбора (получается перекос уже в другую сторону...)

    UPDATE T1
    SET T1.F1 = T1.F1 + T2.F1
    FROM T1 INNER JOIN T2 ON (T1.K11 = T2.K21 and T1.K12 = T2.K22)
    WHERE T2.F2 = 'НЕЧТО'



    так лучше. (опять имхо)
  • Юрий Зотов © (18.05.09 17:15) [13]
    Люди, вы гиганты. Спасибо.
  • Игорь Шевченко © (18.05.09 18:43) [14]
    sniknik ©   (18.05.09 16:18) [12]

    Синтаксис UPDATE...FROM для меня несколько странен...
  • Ega23 © (18.05.09 20:04) [15]

    > Синтаксис UPDATE...FROM для меня несколько странен...


    Должен быть. В ANSI, вроде как, присутствует.
  • Игорь Шевченко © (18.05.09 20:41) [16]

    > Должен быть. В ANSI, вроде как, присутствует


    Вот хорошо тебе - ты SQL недавно изучаешь. А представь, что 20 с лишним лет ты видел один синтаксис, а потом всякие там ANSI придумывают нечто.

    Кроме того синтаксис
    UPDATE foo SET ...
    WHERE

    более очевиден, чем

    UPDATE foo SET ...
    FROM ...

    В первом случае ты понимаешь, что надо обновить по условию, во втором впадаешь в ступор.
  • Petr V. Abramov © (18.05.09 21:04) [17]

    > Игорь Шевченко ©   (18.05.09 20:41) [16]


    > а потом всякие там ANSI придумывают нечто.

    угу.
    вот их бы посадить запросы писать-читать, а не стандарты выдумывать.
    я серьезно.
    про метлы не утрирую. пока не утрирую.
  • sniknik © (18.05.09 21:59) [18]
    > А представь, что 20 с лишним лет ты видел один синтаксис, а потом всякие там ANSI придумывают нечто.
    ну я поменьше 20-ти, но тем не менее начинал в базах с foxpro, где селект был даже не запросом, а открытием рабочей области, и только после "трансформировался" в подобие запроса, на самом деле была та же рабочая область просто с условиями (можно было повторно открыть такой "запрос" указав вместо запроса индекс рабочей области). и ничего адаптировался. и считаю, что то, что есть теперь, удобнее.

    > более очевиден, чем
    серьезно? и как тогда в "твоем" запросе "по условию"
    > update t1 a set ...
    > where (a.k11, a.k12) in (select b.k21,b.k22 from t2 b where b.f2 = 'НЕЧТО')
    без объединения использовать в апдейте данные другой таблицы, как здесь
    > UPDATE T1
    > SET T1.F1 = T1.F1 + T2.F1
    > FROM T1 INNER JOIN T2 ON (T1.K11 = T2.K21 and T1.K12 = T2.K22)
    > WHERE T2.F2 = 'НЕЧТО'

    очевидно объединение нужно, ну сделаешь ты его неявным но по сути будет тоже самое.

    > вот их бы посадить запросы писать-читать, а не стандарты выдумывать.
    думаешь их придумывают совсем неграмотные?
  • Игорь Шевченко © (18.05.09 22:33) [19]

    > но тем не менее начинал в базах с foxpro


    Во-во.

    Я нисколько ни умаляю твои знания, но тем не менее, если долго работать с ненастольными базами, да еще если они поддерживают SQL, да еще если поддерживают так, как Oracle, это, знаешь ли, накладывает свои отпечатки на точку зрения.

    Я повторюсь - лично для меня UPDATE ... FROM выглядит необычно. Точно также я буду спотыкаться на UPDATE ... WHERE CURRENT OF, хотя этому синтаксису поболе лет, чем UPDATE FROM, но все равно он идет от магнитных лент и настольных баз.
  • Игорь Шевченко © (19.05.09 02:43) [20]
    Кстати, о стандартах:

    "Хотя большинство комитетов по стандартам, как правило, создают нечто ужасное, стандарт 1003.1 заметно отличается от общего правила в лучшую сторону....

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

    (с) Эндрю Таненбаум
  • Anatoly Podgoretsky © (19.05.09 09:18) [21]

    > Игорь Шевченко ©   (18.05.09 22:33) [19]

    Предложи другой вариант синтаксиса, где источников для обновления больше одного и они не только простые таблицы, но соединения, при том множественные на одну и туже таблицу. Ведь все равно придется придумывать какой то синтаксис, пускай без естественного FROM

    Вот выписка из справки

    > Определяет, что для определения критериев операции обновления
    > используется таблица, представление или производный источник
    > таблицы. Дополнительные сведения см. в разделе FROM (Transact-
    > SQL).
    >
    > Если обновляемый объект тот же самый, что и объект в предложении
    > FROM, и в предложении FROM имеется только одна ссылка на
    > этот объект, псевдоним объекта указывать необязательно.
    > Если обновляемый объект встречается в предложении FROM несколько
    > раз, одна и только одна ссылка на этот объект не должна
    > указывать псевдоним таблицы. Все остальные ссылки на объект
    > в предложении FROM должны включать псевдоним объекта.


    А вот дополнение

    > Указывает таблицы, представления, производные таблицы и
    > соединяемые таблицы, которые используются в инструкциях
    > DELETE, SELECT и UPDATE. В инструкции SELECT требуется предложение
    > FROM, за исключением тех случаев, когда список выбора содержит
    > только константы, переменные и арифметические выражения
    > (без имен столбцов).
  • Ega23 © (19.05.09 10:16) [22]
    Я сегодня с утра так немного подумал...
    Вобщем, у Юрия условие какое-то странное.

    T1.K11 = T2.K21
    and
    T1.K12 = T2.K22
    and
    T2.F2 = 'НЕЧТО'



    'НЕЧТО' - избыточное условие, и так всё сработает (в случае, когда таких сочетаний больше нуля).
    Либо надо что-то типа

    T1.K11 = T2.K21
    and
    T1.K12 = T2.K22
    and
    T1.F1=T2.F2
    and
    T2.F2 = 'НЕЧТО'

  • Игорь Шевченко © (19.05.09 11:01) [23]

    > Предложи другой вариант синтаксиса


    собственно в самом начале предложил
  • palva © (19.05.09 11:12) [24]

    > Ega23 ©   (19.05.09 10:16) [22]

    Что-то я не понял, почему условие лишнее.
    Надо обновить только те записи T1, которые после соединения (один к одному) дают T2.F2 = 'НЕЧТО'
    Как же можно этого добиться без указания 'НЕЧТО'
  • Ega23 © (19.05.09 11:15) [25]

    > Что-то я не понял, почему условие лишнее.


    Всё нормально, я уже уточнил условие. Просто я [0] не так понял.
    [22] - снято.
  • Anatoly Podgoretsky © (19.05.09 11:54) [26]

    > собственно в самом начале предложил

    Если ты имеешь в виду [1] и [2], то не вижу
  • Игорь Шевченко © (19.05.09 12:04) [27]
    Anatoly Podgoretsky ©   (19.05.09 11:54) [26]


    > Если ты имеешь в виду [1] и [2], то не вижу



    > Предложи другой вариант синтаксиса, где источников для обновления
    > больше одного и они не только простые таблицы, но соединения,
    >  при том множественные на одну и туже таблицу.


    Переведи пожалуйста эту фразу. Я не понимаю, что имеется в виду - одним UPDATE изменять несколько таблиц или изменять одну таблицу, но критерией для отбора записей для изменения является N таблиц ?
    Во втором случае - [1] или [2].
  • Anatoly Podgoretsky © (19.05.09 12:31) [28]
    > Игорь Шевченко  (19.05.2009 12:04:27)  [27]

    set f1=t2.f1, f2=t3.f2,... fN=tN.fN
    где tX - это или просто таблицы, или представления, или соединения с другими таблицами по JOIN при том возможно несколько соединений с одной и той же таблицей.
    где количество источников столько сколько нужно и нет ограничения на тип и без вложеных запросов. Вот для этого и нужно ключевое слово FROM что бы можно было создать и использовать алиасы для указания источника. Или другими словами справа может быть любая структура допустимая для SELECT ... FROM список источников.
  • Игорь Шевченко © (19.05.09 14:13) [29]

    > set f1=t2.f1, f2=t3.f2,... fN=tN.fN
    > где tX - это или просто таблицы, или представления, или
    > соединения с другими таблицами по JOIN при том возможно
    > несколько соединений с одной и той же таблицей.
    > где количество источников столько сколько нужно и нет ограничения
    > на тип и без вложеных запросов. Вот для этого и нужно ключевое
    > слово FROM что бы можно было создать и использовать алиасы
    > для указания источника. Или другими словами справа может
    > быть любая структура допустимая для SELECT ... FROM список
    > источников.


    В этом случае гораздо проще использовать UPDATE ... WHERE CURRENT OF
  • Anatoly Podgoretsky © (19.05.09 14:29) [30]
    > Игорь Шевченко  (19.05.2009 14:13:29)  [29]

    Может быть и так, но это синтаксис Оракла и я не уверен на присутствие в стандарте или в других SQL серверах, в T-SQL этого формата нет и я даже не представляю ее синтаксиса.
  • sniknik © (19.05.09 14:35) [31]
    > В этом случае гораздо проще использовать UPDATE ... WHERE CURRENT OF
    проще? объединение с курсором и правилами объединения описанными где то "в стороне", да это имхо еще более неявно чем неявное объединение...

    для примера, кто не в курсе
    http://www.techonthenet.com/oracle/cursors/current_of.php

    ну или покажи на примере аналог запроса из [12] с CURRENT OF, так чтобы он был проще для восприятия.

    p.s. это в тебе просто говорит неприятие нового, а не реальное знание, что что-то проще.
  • sniknik © (19.05.09 14:40) [32]
    > но это синтаксис Оракла
    был рожден в оракле и помрет в нем же, а если бы это было реально удобнее и проще то давно бы уже повторили, а может и стандартом сделали. ведь довольно старая конструкция, время осмыслить было.
  • Ega23 © (19.05.09 14:45) [33]

    > в T-SQL этого формата нет и я даже не представляю ее синтаксиса.


    Чё-это нет-то сразу?

    Использование инструкции UPDATE с предложением FROM
    Результаты инструкции UPDATE не определены, если инструкция включает предложение FROM, в котором для каждого вхождения обновляемого столбца не задано единственное значение, то есть если инструкция UPDATE не является детерминированной. Например, в инструкции UPDATE следующего сценария обе строки в Table1 удовлетворяют условиям предложения FROM в инструкции UPDATE, но не определено, какая строка из Table1 используется для обновления строки в Table2.

    USE AdventureWorks;
    GO
    IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
       DROP TABLE dbo.Table1;
    GO
    IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
       DROP TABLE dbo.Table2;
    GO
    CREATE TABLE dbo.Table1
       (ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
    GO
    CREATE TABLE dbo.Table2
       (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
    GO
    INSERT INTO dbo.Table1 VALUES(1, 10.0);
    INSERT INTO dbo.Table1 VALUES(1, 20.0);
    INSERT INTO dbo.Table2 VALUES(1, 0.0);
    GO
    UPDATE dbo.Table2
    SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
    FROM dbo.Table2
       INNER JOIN dbo.Table1
       ON (dbo.Table2.ColA = dbo.Table1.ColA);
    GO
    SELECT ColA, ColB
    FROM dbo.Table2;




    То же самое может произойти при сочетании предложений FROM и WHERE CURRENT OF. В следующем примере обе строки в Table2 удовлетворяют условиям предложения FROM в инструкции UPDATE. Не определено, какая строка из Table2 должна использоваться для обновления строки в Table1.

    USE AdventureWorks;
    GO
    IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
       DROP TABLE dbo.Table1;
    GO
    IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
       DROP TABLE dbo.Table2;
    GO
    CREATE TABLE dbo.Table1
       (c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
    GO
    CREATE TABLE dbo.Table2
       (d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
    GO
    INSERT INTO dbo.Table1 VALUES (1, 10);
    INSERT INTO dbo.Table2 VALUES (1, 20);
    INSERT INTO dbo.Table2 VALUES (2, 30);
    GO
    DECLARE abc CURSOR LOCAL FOR
       SELECT c1, c2
       FROM dbo.Table1;
    OPEN abc;
    FETCH abc;
    UPDATE dbo.Table1
    SET c2 = c2 + d2
    FROM dbo.Table2
    WHERE CURRENT OF abc;
    GO
    SELECT c1, c2 FROM dbo.Table1;
    GO



    Только курсор для этого ещё открывать - некузяво как-то для T-SQL
  • Игорь Шевченко © (19.05.09 14:45) [34]
    Anatoly Podgoretsky ©   (19.05.09 14:29) [30]


    > Может быть и так, но это синтаксис Оракла и я не уверен
    > на присутствие в стандарте


    Вообще-то это синтаксис SQL-92

    sniknik ©   (19.05.09 14:35) [31]


    > p.s. это в тебе просто говорит неприятие нового, а не реальное
    > знание, что что-то проще.


    Безусловно. Если ты читаешь внимательно, то увидишь, что я говорю исключительно о своем впечатлении. Надеюсь, на этой благостной ноте мы закончим дискуссию.

    P.S. Я еще использую синтаксис с (+) вместо OUTER JOIN в силу присущего мне консерватизма.
  • Petr V. Abramov © (20.05.09 11:22) [35]

    > sniknik ©   (18.05.09 21:59) [18]


    > думаешь их придумывают совсем неграмотные?

    ну почему, минимум писАть умеют.

    > P.S. Я еще использую синтаксис с (+) вместо OUTER JOIN в
    > силу присущего мне консерватизма.

    а я думал, потому что букаф меньше и запрос читабельней
  • Ega23 © (20.05.09 11:37) [36]

    > и запрос читабельней


    Ой, Петь, это крайне спорный вопрос насчет читабельности. Я конечно понимаю, что в чужой монастырь (Oracle, Postgres, MSSQL или ещё что-нибудь) со своим уставом соваться не положено, но Outer Join - он даже в Access Outer Join. А вот (+) - далеко не везде...  :)
  • ANB (20.05.09 11:42) [37]
    update с from штука удобная, я пользовался ей в MS SQL.
    В оракле ее нету. Но в оракле можно прекрасно обойтись и без оной - либо через IN либо через пл/скл скрипт.
    А вот в MS SQL скрипт писать с курсором запаришься, да и курсоры в нем хреново реализованы (о чем написано в BOL), посему, видимо, и реализовали апдейт с фромом.
  • ANB (20.05.09 11:46) [38]

    > Ой, Петь, это крайне спорный вопрос насчет читабельности.
    >  Я конечно понимаю, что в чужой монастырь (Oracle, Postgres,
    >  MSSQL или ещё что-нибудь) со своим уставом соваться не
    > положено, но Outer Join - он даже в Access Outer Join. А
    > вот (+) - далеко не везде...  :)

    Ну и что, что не везде. Один хрен, попытка писать запросы так, чтобы выполнялись на всех СУБД - полностью бестолковая затея.
    Зато с (+) на оракле и читать удобнее и писать меньше.
  • sniknik © (20.05.09 11:52) [39]
    если считать, что читабельнее то где меньше букв, то надо признать что perl самый понятный язык, причем в самой его "жесткой" форме, когда в строчку умещается целая программа. (а еще круче если перл скрипт выполняется прям из архива, архив будет прям эталоном читабельности... и проще всего прямо в его кодах и писать)
    и C на порядок понятнее дельфей (ну как же вместо begin (6) пишут { (1), и т.д.).
  • ANB (20.05.09 12:00) [40]

    > Зато с (+) на оракле и читать удобнее и писать меньше.



    > и C на порядок понятнее дельфей (ну как же вместо begin
    > (6) пишут { (1), и т.д.).

    Всегда считал C понятнее паскаля.
  • sniknik © (20.05.09 12:11) [41]
    > Один хрен, попытка писать запросы так, чтобы выполнялись на всех СУБД - полностью бестолковая затея.
    смысл не в том чтобы везде выполнялось одно и тоже, а в унифицированности синтаксиса... т.е. где бы то ни было начинаешь писать по стандарту, и если не заработало сразу, то мелкие изменения делаются прямо на месте по "наводке" ошибок от компилятора.

    и кстати вопрос к поборникам (+) (не к Игорю, он признает, что пишет так по привычке) вы писали долгое время используя только join? (чтобы привычка была ~ одинакова)
    я просто писал и так и так, на первасвиле, когда у него явных джойнов не было, года полтора, потом пришлось на accecc... и было поначалу очень непривычно, но варианта с альтернативой попросту не было... привык. а когда поработал с полгода так и понял что явные удобнее, именно по читабельности, т.к. запрос структурирован, объединения отдельно, условия отдельно, а + в большой массе условий может попросту потеряться.
    не говоря уже о том, что у явных возможностей больше (естественно, новое развивается, старое застаивается).

    > Всегда считал C понятнее паскаля.
    что же ты тогда тут делаешь?
  • Ega23 © (20.05.09 12:21) [42]

    > Ну и что, что не везде. Один хрен, попытка писать запросы
    > так, чтобы выполнялись на всех СУБД - полностью бестолковая
    > затея.
    > Зато с (+) на оракле и читать удобнее и писать меньше.


    А я не говорю, что нужно писать так, чтобы на любой СУБД выполнилось. Вот уж действительно бестолковая затея.
    Но. Когда я вижу Outer Join - я понимаю, о чём идёт речь. Причём понимаю вне зависимости от диалекта. А вот с (+) или ещё с какой-нибудь фигнёй - уже надо лезть в доку по конкретному диалекту и смотреть - а что же это такое?

    Для T-SQL данные конструкции равнозначны и равновозможны:

    Select Name=CatName from Categories
    Select CatName Name from Categories
    Select CatName as Name from Categories



    Но, по-идее, правильнее - третий вариант. Он будет понятен вообще любому, кто с зачатками ANSI SQL знаком.
  • Игорь Шевченко © (20.05.09 12:51) [43]

    > в унифицированности синтаксиса... т.е. где бы то ни было
    > начинаешь писать по стандарту, и если не заработало сразу,
    >  то мелкие изменения делаются прямо на месте по "наводке"
    > ошибок от компилятора.


    Нафиг не нужна унифицированность синтаксиса. Каждая СУБД (и каждый язык программирования, кстати), предоставляют свои уникальные возможности, и не использовать их было бы глупо. К примеру, в том же Oracle есть масса встроенных функций и конструкций SQL, которые уникальны для Oracle, но позволяют решать задачи оптимальным образом.
    И что, от них отказываться в пользу унифицированности ?
    Нафиг надо
  • Игорь Шевченко © (20.05.09 12:55) [44]
    Ega23 ©   (20.05.09 12:21) [42]


    > Но, по-идее, правильнее - третий вариант. Он будет понятен
    > вообще любому, кто с зачатками ANSI SQL знаком.


    Понимаешь, в чем дело - мы MS-SQL-щиков, например, на работу не берем. Мы берем тех, кто знает Оракл. Причина простая - мало писать понятные запросы, надо еще знать различия в их выполнении на разных СУБД. Для Оракла выполнение одинаково написанного запроса может отличаться от выполнения его же на MS-SQL, Sybase, Informix, DB2, далее со всеми остановками до станции Можайск Смоленского направления.
    А нам важно, чтобы народ писал запросы с учетом особенностей Oracle, а не с учетом стандартов ANSI
  • Ega23 © (20.05.09 12:59) [45]

    > Для Оракла выполнение одинаково написанного запроса может
    > отличаться от выполнения его же на MS-SQL, Sybase, Informix,
    >  DB2, далее со всеми остановками до станции Можайск Смоленского
    > направления.


    Блин. Игорь, пойми, я не агитирую за то, чтобы все всегда писали по стандарту. Естественно, в конкретной СУБД есть свои фичи. И не пользоваться ими - просто глупо, а зачастую и "преступно".
    Но если (+)  и Outer join абсолютно равнозначны по скорости выполнения запроса, то ЛИЧНО Я бы написал outer join, т.к. это будет более понятно ЛЮБОМУ человеку. А не только тому, кто знает Oracle.
  • Ega23 © (20.05.09 13:02) [46]

    > Ega23 ©   (20.05.09 12:59) [45]


    Вдогонку.
    Собственно, с чего всё началось. Да, в MSSQL есть UPDATE ... WHERE CURRENT OF. Но поскольку реализовано это дело через курсор, а они в MSSQL - штука довольно тяжёлая - проще Update..From использовать.
  • Игорь Шевченко © (20.05.09 13:07) [47]
    Ega23 ©   (20.05.09 12:59) [45]


    > Но если (+)  и Outer join абсолютно равнозначны по скорости
    > выполнения запроса, то ЛИЧНО Я бы написал outer join, т.
    > к. это будет более понятно ЛЮБОМУ человеку. А не только
    > тому, кто знает Oracle.


    Лично для тебя - синтаксис OUTER JOIN в Oracle появился гораздо позже (+).
    Собственно почему я и пишу про ЛИЧНО СВОЮ разницу в восприятии.

    Лично для тебя - по скорости не различается, в плане исполнения запроса и в том и в другом случае будет стоять JOIN OUTER.

    Мы не ставим целью писать запросы, понятные человекам, знакомым с другими СУБД - что толку писать часть запроса стандартно, а далее, в том же запросе использовать кучу Оракловских фич - запрос от этого понятнее человеку, незнакомому с Oracle, не станет.
  • Anatoly Podgoretsky © (20.05.09 13:20) [48]

    > > Может быть и так, но это синтаксис Оракла и я не уверен
    >
    > > на присутствие в стандарте
    >
    >
    > Вообще-то это синтаксис SQL-92

    Я нашел синтаксис в стандарте SQL-99, но это не одно и тоже,
    where current of <cursor>


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

    > где количество источников столько сколько нужно и нет ограничения
    > на тип и без вложеных запросов.
  • sniknik © (20.05.09 13:21) [49]
    > И что, от них отказываться в пользу унифицированности ?
    ну ты же отказываешься от дополнительных возможностей явных джойнов пользу привычных тебе методов объединений, ради привычки, почему бы не отказаться и в этом случае ради "великой идеи"?
    (хотя я то как раз не предлагал ни от чего отказываться, но раз уж зашел разговор...)

    > мало писать понятные запросы
    вообще то понятные запросы, если они по стандарту, в общем случае лучше "перевариваются" оптимизатором и планировщиком, и как правило чаще всего быстрее запутанных.
    хотя, оракл в число близко знакомых мне баз не входит, допускаю что там может быть по другому. (написан толпой индусов без четкой "линии партии" ;), может наиболее отлаженные как раз старые алгоритмы.)
  • ANB (20.05.09 13:23) [50]

    > А не только тому, кто знает Oracle.

    А тому, кто не знает, оно, как правило, и не надо.

    И у плюсов есть свое достоинство - на 8-ке работают только они. А 8-ку снесли еще далеко не все.
  • Anatoly Podgoretsky © (20.05.09 13:24) [51]

    > Нафиг не нужна унифицированность синтаксиса. Каждая СУБД
    > (и каждый язык программирования, кстати), предоставляют
    > свои уникальные возможности, и не использовать их было бы
    > глупо. К примеру, в том же Oracle есть масса встроенных
    > функций и конструкций SQL, которые уникальны для Oracle,
    >  но позволяют решать задачи оптимальным образом.
    > И что, от них отказываться в пользу унифицированности ?

    Полностью согласен.
  • ANB (20.05.09 13:28) [52]

    > ну ты же отказываешься от дополнительных возможностей явных
    > джойнов пользу привычных тебе методов объединений

    Никто от них не отказывается. Когда нужны эти доп. возможности - пользуемся явными джойнами. Только это так редко нужно . . .
  • Игорь Шевченко © (20.05.09 13:36) [53]

    > вообще то понятные запросы, если они по стандарту, в общем
    > случае лучше "перевариваются" оптимизатором и планировщиком,
    >  и как правило чаще всего быстрее запутанных.


    полная ерунда
  • Ega23 © (20.05.09 13:39) [54]
    Я вот что скажу. Довольно долго сидел под MSSQL и нифига кроме TSQL ничего не знал. И тут потребовалось под Postgres писать. Скажу честно - я сам не заметил, как у меня поменялся стиль написания запросов. Потому что, когда сразу с несколькими СУБД приходится работать - в одной что-то подзабылось, в другой - тоже фигня какая-то своя. А так - более-менее унифицировано получается.

    Тоже самое произошло, когда на JavaScript начал писать. Сам не заметил, как все локальные переменные в любом языке начал с LowerCase писать. Если раньше
    var
     i, CurrID : Integer

    то теперь
    var
     i, currID : Integer



    Собственно, речь об этом, а не о том, что "необходимо стандарта придерживаться"
  • Игорь Шевченко © (20.05.09 13:41) [55]
    Anatoly Podgoretsky ©   (20.05.09 13:20) [48]

    > Я нашел синтаксис в стандарте SQL-99, но это не одно и тоже,
    >  
    > where current of <cursor>
    > Я же не про курсоры говорил, хотя возможно и ими можно сделать
    > в контексте


    Я наверное тебя запутал в начале :) Синтаксис WHERE CURRENT OF конечно же подразумевает WHERE CURRENT OF <cursor>, собственно с этой конструкцией я познакомился еще в WATCOM SQL, когда он не был продан Sybase, и в описании тамошнего синтаксиса было написано, что конструкция соответствует стандарту ANSI SQL. А это было до 1999-года :)

    В SQL-92 этот синтаксис имеется
  • Игорь Шевченко © (20.05.09 13:48) [56]
    Ega23 ©   (20.05.09 13:39) [54]

    Э...Я довольно долго писал запросы под Oracle и под Interbase, а также под разную для меня экзотику - как ни странно, ни разу не было желания писать что-то единое для всех. Обычному SELECT-у пофиг, а всякие частности - они все одно у каждого свои и запросы писались так, чтобы они были похожи на принятые для этой СУБД привычные формы.

    К примеру, NVL и DECODE в Oracle не во всех версиях можно заменить CASE, хотя бы потому, что CASE не во всех версиях включен в синтаксис :)

    А что касается твоего примера с JavaScript - я, опять же, довольно долго служил ямщиком на почте, то есть, писал на C, паскале и C#
    Как только я вижу код на С, в котором идентификаторы написаны с большой буквы или код на паскале, где идентификаторы содержат в себе подчеркивание (this_is_ident), моя рука тянется к пистолету, так как существуют неписанные традиции для языка, и знание этих традиций облегчает понимание кода.

    Кстати, за что я никогда не любил Borland C++ builder - он смешивает традиции.
  • Ega23 © (20.05.09 13:53) [57]

    > или код на паскале, где идентификаторы содержат в себе подчеркивание


    Я так только константы именую. с_[аббривиатура категории]_[мнемоническое имя]
  • Anatoly Podgoretsky © (20.05.09 14:29) [58]
    > Игорь Шевченко  (20.05.2009 13:41:55)  [55]

    Да просто под рукой 99 и выше оказались. Кроме того и T-SQL тоже обнаружился, хотя я там пробовал искать, но видимо не там.
  • Ega23 © (20.05.09 14:40) [59]

    > хотя я там пробовал искать, но видимо не там.


    Курсоры в TSQL медленные.
  • Игорь Шевченко © (20.05.09 15:41) [60]

    > Курсоры в TSQL медленные.


    Это как ? Ты хочешь сказать, что сформировать result set быстрее, чем двигаться по нему ?

    То есть,
    SELECT foo FROM bar
    будет быстрее, чем

    CURSOR foobar IS SELECT foo FROM bar;

    OPEN foobar;
    FETCH foobar INTO foobardata;
    ...

    ?
  • sniknik © (20.05.09 16:10) [61]
    > Ты хочешь сказать, что сформировать result set быстрее, чем двигаться по нему ?
    смотря для чего, если выбрать одну запись где то ближе к началу то курсором быстрее (если есть индекс то может и нет), если цель в обработке всех то вариант пакетной команды очевидно будет быстрее чем перебор и обработка тех же самых записей по одной в курсоре.

    и это, имхо, от языка не зависит. даже в чудесном оракле должно быть тоже самое.
  • Игорь Шевченко © (20.05.09 16:32) [62]
    sniknik ©   (20.05.09 16:10) [61]

    В чудесном оракле для получения result set можно указать, что нужно сделать быстрее - получить первую запись или получить все записи.
    Как двигаться по вперед по result set после его получения - без разницы, скорость будет одинаковая. Любая СУБД, насколько мне известно, отдает полученные в result set записи той или иной формой курсора (явного, неявного - без разницы).

    Если в MS SQL иначе - то вот вам еще одно различие между базами, непреодолимое способом записи SQL, по стандарту ANSI или по стандарту СУБД
  • ANB (20.05.09 16:33) [63]

    > Это как ? Ты хочешь сказать, что сформировать result set
    > быстрее, чем двигаться по нему ?

    Ну это даже в оракле быстрее.

    Массовые апдейты я вообще иногда инсертами делаю.
  • Anatoly Podgoretsky © (20.05.09 16:34) [64]
    > Ega23  (20.05.2009 14:40:59)  [59]

    Да зачем мне курсоры, при наличии механизма FROM
  • ANB (20.05.09 16:35) [65]

    > Если в MS SQL иначе

    В ms sql курсоры мало того, что дебильные по синтаксису, так еще и настолько тормозные, что в BOL прямо было прописано - по возможности ими не пользоваться.
  • Игорь Шевченко © (20.05.09 16:54) [66]

    > Массовые апдейты я вообще иногда инсертами делаю.


    Дурное дело нехитрое
  • sniknik © (20.05.09 16:58) [67]
    > Любая СУБД, насколько мне известно, отдает полученные в result set записи той или иной формой курсора (явного, неявного - без разницы).
    в mssql очевидно не так... т.к. если бы было подобие курсора то тригеры бы срабатывали на одну запись, а они работают там "на пакет".

    > что в BOL прямо было прописано - по возможности ими не пользоваться.
    а в оракле значит в хелпе обманывают, что они быстрее? очень плохо.
  • Игорь Шевченко © (20.05.09 17:08) [68]

    > т.к. если бы было подобие курсора то тригеры бы срабатывали
    > на одну запись, а они работают там "на пакет".


    триггеры на SELECT ?
  • sniknik © (20.05.09 17:12) [69]
    > триггеры на SELECT ?
    на update/insert
  • Игорь Шевченко © (20.05.09 17:17) [70]
    sniknik ©   (20.05.09 17:12) [69]

    В update/insert нет курсоров - не с чем сравнивать.

    А насчет срабатывания триггеров - в чудесном оракле есть возможность указать метод срабатывания триггеров - на каждую строку или на весь оператор
  • sniknik © (20.05.09 17:29) [71]
    > В update/insert нет курсоров - не с чем сравнивать.
    как же не с чем? а синтаксис с CURRENT OF, т.е.  то с чего начали.
  • Игорь Шевченко © (20.05.09 18:21) [72]
    sniknik ©   (20.05.09 17:29) [71]


    > как же не с чем? а синтаксис с CURRENT OF, т.е.  то с чего
    > начали.


    А почитать синтаксис не ? :) Там еще и SELECT участвует
  • sniknik © (20.05.09 18:30) [73]
    > Там еще и SELECT участвует
    селект в описании курсора это не настоящий селект... это всего лишь условие по которому выбираются записи. ну да, условие имеет вид селекта ну и что?
  • Alarm © (20.05.09 18:49) [74]
    > Юрий Зотов ©   (18.05.09 17:15) [13]
    > Люди, вы гиганты. Спасибо.


    Хотя бы только из-за этого, я бы уже прекратил постить в эту ветку
    :(
  • Игорь Шевченко © (20.05.09 18:49) [75]

    > селект в описании курсора это не настоящий селект...


    критерии "настоящего" SELECT в студию


    > ну и что?


    А о чем вообще дискуссия ?
  • sniknik © (20.05.09 18:59) [76]
    > критерии "настоящего" SELECT в студию
    возвращает выборку, т.е. рекордсет, куда, сервер/клиент неважно. если же это просто запись из которой другие команды берут условия для собственной работы, а она сама ничего не делает, то это не настоящий селект.

    > А о чем вообще дискуссия ?
    не знаю. ты спрашиваешь/комментируешь, я отвечаю.
  • Игорь Шевченко © (20.05.09 19:05) [77]

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


    Я полагаю, есть смысл прекратить дискуссию
  • Petr V. Abramov © (20.05.09 19:08) [78]

    > sniknik ©   (20.05.09 16:58) [67]


    > а в оракле значит в хелпе обманывают, что они быстрее? очень
    > плохо.

    быстрее, чем что?
  • sniknik © (20.05.09 19:53) [79]
    > быстрее, чем что?
    читать не умеешь? или выборочно, раньше фразы ничего не воспринимается?
    быстрее пакетных команд, типа проход курсором для апдейта быстрее чем апдейт с from, или составление рекордсета по курсору быстрее чем селект.
    ну так получается, судя по тому что мне тут говорят. и не верить нельзя, т.к. говорят, что так в оракле который я не знаю.
 
Конференция "Базы" » Update одной таблицы по условию из другой таблицы [DB2]
Есть новые Нет новых   [134473   +31][b:0.001][p:0.004]