Конференция "Базы" » ado и access
 
  • Тимофей Ю. (23.06.11 14:05) [0]
    Всем привет, есть база на access. Выбрана потому что в ОС встроен драйвер и за собой можно таскать всего один файл базы.
    Подключаюсь по адо, все бы хорошо, но в access нет фиксированного порядка строк. Для клиента обязательно чтобы можно было менять местами записи в таблице.
    Структура таблицы:
    id(autoinc) | value(text)

    Без запросов тут не обойтись полагаю, профи подскажите как реализовать перемещение записей в таблице. Нужно всего две кнопки - вверх, вниз.
  • Ega23 © (23.06.11 14:19) [1]
    create table ttt (
     id int identity (1,1) not null,
     value varchar(...),
     orderField int not null default 0
    )

    select * from ttt order by orderField

    udpate ttt set orderField = x where id = ...

  • Тимофей Ю. (23.06.11 15:22) [2]
    id | value | orderField
    1 | sdfsd  |   ??
    2 | sdf sd |
    3 | hjfg
    4 | asd
    5 | nbvn
    6 | qwe
    7 | hjf

    спасибо, Ega23, мне не понятно что должно быть в поле orderField, если также числа по номерации, то какой смысл в этом столбце если можно использовать для этого столбец id ? А если мне нужно переместить 6 запись на месте 2, при этом все записи начиная с 2 сдвинуться вверх
  • sniknik © (23.06.11 15:53) [3]
    > если можно использовать для этого столбец id ?
    потому что его нельзя использовать... для этого.
    + а еще лучше ему поставить PRIMARY KEY и использовать как искусственный ключ... по назначению.
  • SQLEXPRESS (23.06.11 15:53) [4]
    >> какой смысл в этом столбце если можно использовать для этого столбец id ?
    можно. но нельзя.

    id дается раз и навсегда, по нему на эту строку могут ссылаться другие строки
    а если при каждой сортировке менять id, будет разброд и шатание и адъ с израелем
  • Ega23 © (23.06.11 16:00) [5]

    >  мне не понятно что должно быть в поле orderField, если
    > также числа по номерации, то какой смысл в этом столбце
    > если можно использовать для этого столбец id ? А если мне
    > нужно переместить 6 запись на месте 2, при этом все записи
    > начиная с 2 сдвинуться вверх


    Смотри. У тебя есть уникальный идентификатор ID, первичный ключ. В моём примере он int, но может быть что угодно (составной по нескольким полям, GIUD или ещё что-то).
    У тебя есть поле orderField, которое строго int. И вот выборку ты сортируешь уже по нему.
    Лично я предпочитаю отдать это поле на "откуп" пользователю. Т.е. когда он редактирует конкретную запись в таблице, он сам задаёт это значение. Чем меньше - тем "выше" в выборке будет запись (или чем больше, тогда добавить
    order by orderField desc

    )

    можно сделать в "автоматическом режиме". Например, у тебя в таблице 9 записей:

    1  'a'  1
    2  'б'  3
    3  'в'  5
    4  'г'  7
    5  'д'  9
    6  'е'  2
    7  'ж'  4
    8  'з'  6
    9  'и'  8



    Делаем
    select * from ttt order by orderField



    получаем

    1  'a'  1
    6  'е'  2
    2  'б'  3
    7  'ж'  4
    3  'в'  5
    8  'з'  6
    4  'г'  7
    9  'и'  8
    5  'д'  9



    Допустим, ты хочешь поменять местами вторую и пятую запись в данной выборке. Т.е. 'е' и 'в'
    Тогда:
    1. Запоминаем id и orderField для е. Это 6 и 2
    2. Запоминаем id и orderField для в. Это 3 и 5
    3.
    Update ttt set orderField = 5 where id = 6


    4.
    Update ttt set orderField = 2 where id = 3



    снова выбираем:
    select * from ttt order by orderField


    получаем

    1  'a'  1
    3  'в'  2
    2  'б'  3
    7  'ж'  4
    5  'е'  5
    8  'з'  6
    4  'г'  7
    9  'и'  8
    5  'д'  9

  • sniknik © (23.06.11 16:01) [6]
    > id дается раз и навсегда
    автоинкремент это не ключ... просто их часто совмещают, но это не значит что они равны...

    > по нему на эту строку могут ссылаться другие строки
    это ключ
    и он вполне может быть "естественным", а автоиинкремент рядом для других целей.
  • SQLEXPRESS (23.06.11 16:02) [7]
    потом понадобится, например, каждую строчку расшифровать, причем многократно.

    id | value
    1 | sdfsd  
    2 | sdf sd

    Заведем еще одну таблицу
    id | value                                  | FK_ID
    1 | Да, самый настоящий sdfsd    | 1
    2 | sdfsd - только у нас!             | 1
    3 | sdf sd - дешевле конкурентов | 2

    если связать FK_ID и id - задача выполнена

    А теперь представим, что id плавает... и плюем в разработчика такой БД.
  • SQLEXPRESS (23.06.11 16:04) [8]
    sniknik ©   (23.06.11 16:01) [6]
    согласен.
    Но.. а для чего ты это сказал? :)
  • Ega23 © (23.06.11 16:06) [9]

    > Ega23 ©   (23.06.11 16:00) [5]


    Опечатка. В последней выборке будет

    снова выбираем:
    select * from ttt order by orderField


    получаем

    1  'a'  1
    3  'в'  2
    2  'б'  3
    7  'ж'  4
    6  'е'  5
    8  'з'  6
    4  'г'  7
    9  'и'  8
    5  'д'  9

  • Ega23 © (23.06.11 16:14) [10]
    Да, и ещё: если не хотим повторяющихся значений в orderField (хотя почему бы и нет?), то при вставке новой записи ставим
    orderField = select IsNull(Max(orderField) + 1, 1)

  • sniknik © (23.06.11 16:23) [11]
    > Но.. а для чего ты это сказал? :)
    автоинкремент не раз и навсегда, от него ничего не поплывет, это ты говорил про ключ... а в примере выше, на вопрос от которого ты отвечал, просто автоинкремент...

    например есть табличка где раз в 3 месяца автоинкременты с 0 пускают... просто людям так проще, сказать - "15796" запись, чем значение гуида (ключа) выговорить, особенно по телефону, а разбирают только сегодня/вчера.
  • SQLEXPRESS (23.06.11 16:32) [12]
    [11]
    ну да, есть такое дело

    а как еще можно понять в таблице наименование поля id, к тому же оно number. К тому же, считаю, что таблица без ключа - инвалид.

    Кстати с гайдами, имхо и работает медленнее, и есть вероятность пересечения, вроде бы, если репликации из многих БД в одну идут.
  • Ega23 © (23.06.11 16:33) [13]

    > автоинкремент не раз и навсегда


    Ну и эта.. Не знаю, как в Access, но в MSSQL:


    USE AdventureWorks2008R2;
    GO
    -- Create tool table.
    CREATE TABLE dbo.Tool(
      ID INT IDENTITY NOT NULL PRIMARY KEY,
      Name VARCHAR(40) NOT NULL
    )
    GO
    -- Inserting values into products table.
    INSERT INTO dbo.Tool(Name) VALUES ('Screwdriver')
    INSERT INTO dbo.Tool(Name) VALUES ('Hammer')
    INSERT INTO dbo.Tool(Name) VALUES ('Saw')
    INSERT INTO dbo.Tool(Name) VALUES ('Shovel')
    GO

    -- Create a gap in the identity values.
    DELETE dbo.Tool
    WHERE Name = 'Saw'
    GO

    SELECT *
    FROM dbo.Tool
    GO

    -- Try to insert an explicit ID value of 3;
    -- should return a warning.
    INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel')
    GO
    -- SET IDENTITY_INSERT to ON.
    SET IDENTITY_INSERT dbo.Tool ON
    GO

    -- Try to insert an explicit ID value of 3.
    INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel')
    GO

    SELECT *
    FROM dbo.Tool
    GO
    -- Drop products table.
    DROP TABLE dbo.Tool
    GO



    http://msdn.microsoft.com/ru-ru/library/ms188059.aspx
  • Ega23 © (23.06.11 16:35) [14]

    > Кстати с гайдами, имхо и работает медленнее, и есть вероятность
    > пересечения, вроде бы, если репликации из многих БД в одну
    > идут.


    Совпадения в принципе возможны, но крайне маловероятны.
    Но никто не мешает тебе сделать составной ключ, по GUID и Identity
  • SQLEXPRESS (23.06.11 16:45) [15]
    по гайду перестал вообще делать
    однажды попробовав схему  ID_DEPARTMENT + Identity, считаю ее оптимальной

    или последовательности, например четные/нечетные
    (когда в одной БД с 1 начинается, а в другой с 2, и шаг у обоих 2)

    ну или +10. т.е. все id заканчивающиеся на 1 - из одной БД. на 2 - из другой,
    на 9 из девятой
  • Ega23 © (23.06.11 17:34) [16]

    > SQLEXPRESS   (23.06.11 16:45) [15]


    Это от задачи зависит. Мы как-то для сливки баз с разных объектов для записи использовали bigint, где старший int - id базы, младший - id записи
  • Сергей М. © (24.06.11 15:02) [17]

    > в access нет фиксированного порядка строк. Для клиента обязательно
    > чтобы можно было менять местами записи в таблице


    Ты не поверишь - не найдется, пожалуй, ни одной мало-мальски приличной СУБД, которая выкрутасничала бы с "менять местами записи в таблице" в угоду ничем не обоснованным сиюминутным капризам.
  • MsGuns © (29.06.11 14:13) [18]
    Похоже, каприз рожден привычкой работать "как в экселе".
    Диагноз: полная аптутация :)
  • Игорь Шевченко © (29.06.11 14:38) [19]

    > К тому же, считаю, что таблица без ключа - инвалид.


    опыт дело наживное
 
Конференция "Базы" » ado и access
Есть новые Нет новых   [134465   +0][b:0][p:0.003]