Главная страница


su.dbms.sql

 
 - SU.DBMS.SQL ------------------------------------------------------------------
 From : Andrey                               2:5083/13.5    01 Apr 2001  13:03:40
 To : All
 Subject : Дремина хитрость.
 -------------------------------------------------------------------------------- 
 
 
  Hi! Drema*
 
 > D> UPDATE ID_ SET @ID=ID=ID+1
 >   Дрема вот это и есть конкретное ламерство, тут тебя не сможет развести
 >ни один,даже самый мудрый сервер. Потому как даже строчная блокировка не
 >спасает от совершенно ненужной задержки пользователей работающих с вообще
 >никак не пересекающимися таблицами.Дрема,ты сам не понятно зачем организовал
 >узкое место в своей системе. Или же ты таким вот образом вылечил MS-SQL от
 >необходимости при его спотыканиях запускать checkident :))))). Крут ты Дрема
 >однако,кру-у-ут.:)))
  D> :) Короче, умник ты наш, зайди вот сюда:
  D> http://www.drema.c-net.ru/c_bd_ident.asp,
  D> там специально для таких как ты все разжевано...
  D> ЗЫ Подробнее объяснять тебе нет совершенно никакого желания.
 
   Так как не у всех фидошников есть интернет то я все же слазил за Дреминой 
 хитростью и просто офигел от того как можно простое сделать сложным и 
 окончательно все запутать. 
 
 Дальше и до конца пошел Дрема.
 В MSSQL есть возможность добавления в таблицу поля автоикремента - это всем
 известно. о иногда возникают проблемы с таким подходом. апример, если на клиенте
 нужно вставить строчку, а в этой таблице есть триггер, а в этом триггере есть
 операторы, которое тоже вставляют в таблицу с identity. В этом случае задача
 возврата значения identity клиенту становится уже не тривиальной.
 
 После некоторых раздумий, я решил вообще не пользоваться свойством identity. Для
 этого просто создал таблицу следующего содержания:
 
 create table NSI_ID15dev5
 (id_ int not null
 )
 insert iden values (0)
 
 То есть создал свой счетчик, причем принял за основу, что во всех таблицах моей 
 БД первичный ключ будет генерироваться из этой таблицы. Ясно дело, что нужно это
 делать с помощью процедуры или триггера. От триггера я сразу отказался, потому
 что что-то лень писать на каждую таблицу по своему триггеру. Исходя из всего
 вышеперечисленного решил при вставке всегда использовать процедуру.
 --- 
 Разберем это на примере таблицы клиентов:
 
 create table client
 (key_nsi int not null,
 name varchar(100),
 inn varchar(12),
 adress varchar(100)
 )
 
 Чтобы не заморачиваться с написанием различных процедур вставки для каждой
 таблицы, я постулирую следующее правило: Процедура вставки должна быть одна на
 все таблицы, то есть универсальной. Исходя из этого теперь можно сформулировать 
 задачи этой процедуры и данные которые ей нужны для выполнения.
 
 Входные данные:
 
 [Имя таблицы] в которую нужно вставлять данные. 
 Выходные данные:
 
 Первичный ключ вставленной записи 
 Здесь, как можно видеть, я опускаю необходимость иметь прочие данные для вставки
 (например поля name, inn и т.п.). Дело в том, что если их тоже передавать в
 процедуру, то будет невозможно написание одной универсальной процедуры, так как 
 количество полей в каждой таблице БД различно, а такой поддержки (переменного
 числа параметров) еще в MSSQL v.7 нету (может и появится в 2000-ой версии).
 
 Следовательно все поля кроме первичного ключа (key_nsi), должны иметь свойства
 NULL, то есть поддерживать вставку пустого значения. екоторые типы данных не
 поддерживают вставку значений NULL, например Boolean, тогда нужно применять
 вставку по умолчанию (defaults, для boolean это должно быть равно "1" например).
 Есть еще одна проблема с этим - если у вас будет стоять уникальный индекс по
 полю, то нельзя будет вставить два раза NULL. В этом случае нужно в defaults
 поля вставить случайное значение по умолчанию, например зависящее от даты.
 
 Еще одно условие на структуру таблицы данных - название первичного ключа
 (key_nsi) должно быть одинаково во всех таблицах.
 
 [Имя таблицы] передается клиентом, то есть он должен знать в какую таблицу он
 вставляет данные. Как лучше передавать имя таблицы? Я решил что просто текстовое
 название передавать не стоит (из последующего ясно, что я захочу поменять имя
 таблицы, не изменяя клиентской программы). В таком случае нужно передавать
 какой-либо код таблицы, для этого создаем еще одну вспомогательную таблицу:
 
 create table nsi_spravochnik
 (key_nsi_spravochnik int not null IDENTITY(1,1),
 table_name varchar(100) not null,
 table_name_rus varchar(100) not null
 )
 
 То есть в этой таблице находится информация о всех таблицах в БД с русскими
 именами. Имея такую таблицу мы можем на клиенте вывести диалог, который
 предлагает выбрать таблицу с которой необходимо работать. о пока самым главным
 для нас является то, что в поле key_nsi_spravochnik есть [номер] таблицы, а по
 этому номеру таблицы мы можем получить и физическое название таблицы. Таким
 образом мы определились с одним (и единственным) параметром у процедуры вставки 
 - это будет целое число однозначно определяющее таблицу.
 
 Опишем примерную структуру процедуры вставки:
 
 create procedure sp_InsertNewRecord
    @KEY_NSI int=0 OUTPUT
         -- При входе @KEY_NSI равен номеру справочника,
         -- При выходе - новому первичному ключу
 as begin
 
 -- Получаем новый ID
 UPDATE   NSI_ID SET  @KEY_NSI = ID_ = ID_ + 1
 
 -- Определяем название таблицы в которую происходит вставка
 declare  @name_table varchar(100)
 SELECT   @name_table = table_name
 FROM  nsi_spravochnik
 WHERE key_nsi_spravochnik = @KEY_NSI
 
 -- Составляем оператор, для вставки в таблицу данных
 declare  @SQL varchar(1000)
 SET   @SQL = 'INSERT '+@name_table+' (KEY_NSI) VALUES ('+
    convert(varchar(20),@KEY_NSI)+')'
 -- Выполняем вставку
 EXEC(@SQL)
 
 end
 
 Таким образом эта процедура будет работать на всех таблицах нашей БД.
 
 Что требуется от клиента?
 Клиентская программа (в моем случае написанная на Delphi) перед вставкой данных,
 должна иметь код таблицы в которую нужно вставить данные. В связи с
 особенностями моей программы, этот код мне всегда известен, причем он не "зашит"
 в программу, а получается при выборе из таблицы nsi_spravochnik.
 
 В Delphi я использую TDBGrid, который берет данные из TUpdateSQL. Я выбрал
 объект TUpdateSQL потому, что в нем легко вставлять свои строчки данных, которых
 нет на сервере. апример в TQuery такой возможности нет.
 
 Еще существует одна проблема с обновлением после вставки/изменения/удаления.
 Если я использую объект TUpdateSQL, то мне не надо обновлять весь курсор после
 того произошло обновление таблицы, мне достаточно обновить только те строчки,
 которые обновились.
 
 Опишем действия на клиенте по вставке стоки в таблицу. Для этого договоримся,
 что на данный момент объект TUpdateSQL отображает некий запрос по таблице,
 key_nsi_spravochnik которой известен (допустим, что он равен "133"):
 
 1.Вызов следующего оператора: 
 
 declare  @KEY_NSI int
 SET   @KEY_NSI = 133
 exec sp_InsertNewRecord @KEY_NSI = @KEY_NSI OUTPUT
 SELECT   @KEY_NSI
 
 Результатом будет курсор, содержащий первичный ключ в таблице (допустим он равен
 9876).
 
 2.Вставка в TUpdateSQL пустой строки
 
 3.Вызов на экран формы редактирования полей БД
 
 4.Если пользователь подтвердил процесс вставки, то выполняем следующий оператор:
 -- Определяем название таблицы в которую происходит вставка
 declare  @name_table varchar(100)
 SELECT   @name_table = table_name
 FROM  nsi_spravochnik
 WHERE key_nsi_spravochnik = 133
 
 declare  @SQL varchar(1000)
 SET   @SQL='UPDATE'+@name_table+
 ' SET name=''Клиент'', inn=''123456789'',adress=''ул. Ленина д.1''
 WHERE KEY_NSI = 9876'
 
 EXEC  (@SQL)
 То есть на самом деле происходит редактирование, а не вставка. Если же
 пользователь отказался от вставки, то пустая строчка должна быть удалена. Этот
 процесс у меня тоже описан в процедуре, которую я здесь приводить не буду.
 
 5.Данные из формы редактирования передаются в строку TUpdateSQL. (Заметьте, что 
 курсор как таковой не обновляется).
 
 Такой подход решает еще одну проблему. Допустим у вас есть какой-то документ, а 
 у этого документа есть строчки. Другими словами есть две таблицы, связанные
 отношением один-ко-многим. Для того, чтобы вставлять строки документа, нужно
 знать значение внешнего ключа, который ссылается на таблицу документа, а так как
 у нас уже есть пустая строчка в БД под этим ключом в главной таблице, то проблем
 не возникает.
 
 ...PS...
 а самом деле у меня сделано немного по другому и намного удобнее, но сама
 стратегия точно такая-же.
 --- 
  * Origin:    (2:5083/13.5)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 SELECT FROM INSERT ?   Leonid Sidorov   27 Mar 2001 20:46:06 
 Re: SELECT FROM INSERT ?   Igor V. Makeev   28 Mar 2001 12:02:39 
 Re: SELECT FROM INSERT ?   Maxim Tomilov   29 Mar 2001 19:30:27 
 RE: SELECT FROM INSERT ?   Drema*   29 Mar 2001 22:11:50 
 SELECT FROM INSERT ?   Andrey   30 Mar 2001 09:43:14 
 Re: SELECT FROM INSERT ?   Ilya Zvyagin   30 Mar 2001 09:55:06 
 RE: SELECT FROM INSERT ?   Drema*   30 Mar 2001 10:27:40 
 RE: SELECT FROM INSERT ?   Drema*   30 Mar 2001 19:17:28 
 Re: SELECT FROM INSERT ?   Roman S. Golubin   30 Mar 2001 21:10:43 
 SELECT FROM INSERT ?   Andrey   31 Mar 2001 01:27:28 
 RE: SELECT FROM INSERT ?   Drema*   31 Mar 2001 00:23:05 
 Re: SELECT FROM INSERT ?   Sergey Pratch   31 Mar 2001 18:07:40 
 Дремина хитрость 2   Andrey   01 Apr 2001 13:03:16 
 RE: Дремина хитрость 2   Drema*   01 Apr 2001 15:28:23 
 Дремина хитрость 2   Andrey   01 Apr 2001 20:43:00 
 RE: Дремина хитрость 2   Drema*   02 Apr 2001 23:11:06 
 Re: Дремина хитрость 2   Ilya Zvyagin   02 Apr 2001 12:44:01 
 Re: Дремина хитрость 2   Serg Vasiltsoff   02 Apr 2001 16:41:53 
 ЙRe: Дремина хитрость 2   Ilya Zvyagin   02 Apr 2001 17:38:59 
 Re: Дремина хитрость 2   Serg Vasiltsoff   02 Apr 2001 18:26:22 
 Re: Дремина хитрость 2   Ilya Zvyagin   02 Apr 2001 21:14:00 
 Re: Дремина хитрость 2   Serg Vasiltsoff   02 Apr 2001 22:58:47 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 10:49:55 
 Re: Дремина хитрость 2   Serg Vasiltsoff   03 Apr 2001 12:54:43 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 15:46:47 
 RE: Дремина хитрость 2   Drema*   02 Apr 2001 23:11:07 
 RE: Дремина хитрость 2   Drema*   02 Apr 2001 23:11:07 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 10:49:55 
 Re: Дремина хитрость 2   Serg Vasiltsoff   03 Apr 2001 12:54:43 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 16:07:17 
 Re: Дремина хитрость 2   Serg Vasiltsoff   03 Apr 2001 18:40:13 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 13:57:29 
 Re: Дремина хитрость 2   Serg Vasiltsoff   04 Apr 2001 15:29:06 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 17:25:26 
 RE: Дремина хитрость 2   Drema   03 Apr 2001 13:17:16 
 Re: Дремина хитрость 2   Tolik Tentser   03 Apr 2001 13:25:24 
 RE: Дремина хитрость 2   Drema   03 Apr 2001 14:16:42 
 Re: Дремина хитрость 2   Tolik Tentser   03 Apr 2001 14:35:07 
 RE: Дремина хитрость 2   Drema   04 Apr 2001 12:22:44 
 Re: Дремина хитрость 2   Tolik Tentser   04 Apr 2001 13:03:34 
 RE: Дремина хитрость 2   Drema   04 Apr 2001 15:25:02 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 17:29:28 
 Re: Дремина хитрость 2   Tolik Tentser   04 Apr 2001 18:24:32 
 Дремина хитрость 2   Sergey Ignatov   16 Apr 2001 23:34:30 
 Дремина хитрость 2   Sergey Ignatov   16 Apr 2001 23:08:19 
 Re: Дремина хитрость 2   Serg Vasiltsoff   04 Apr 2001 15:29:07 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 16:07:17 
 Re: Дремина хитрость 2   Serg Vasiltsoff   03 Apr 2001 16:15:24 
 RE: Дремина хитрость 2   Drema   04 Apr 2001 12:12:25 
 Re: Дремина хитрость 2   Serg Vasiltsoff   04 Apr 2001 12:59:29 
 RE: Дремина хитрость 2   Drema   04 Apr 2001 14:48:26 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 13:45:04 
 Re: Дремина хитрость 2   Serg Vasiltsoff   04 Apr 2001 15:29:07 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 13:45:04 
 Re: Дремина хитрость 2   Serg Vasiltsoff   04 Apr 2001 15:29:08 
 Re: Дремина хитрость 2   Tolik Gusin   09 Apr 2001 19:41:20 
 Re: Дремина хитрость 2   Anatoly Moskovsky   09 Apr 2001 20:40:22 
 Re: Дремина хитрость 2   Tolik Gusin   10 Apr 2001 19:01:32 
 Re: Дремина хитрость 2   Anatoly Moskovsky   10 Apr 2001 19:36:58 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 10:28:08 
 Re: Дремина хитрость 2   Anatoly Moskovsky   11 Apr 2001 12:46:42 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 18:55:02 
 Re: Дремина хитрость 2   Anatoly Moskovsky   11 Apr 2001 21:32:22 
 Re: Дремина хитрость 2   Tolik Gusin   11 Apr 2001 13:56:27 
 Re: Дремина хитрость 2   Anatoly Moskovsky   11 Apr 2001 15:16:10 
 Re: Дремина хитрость 2   Tolik Tentser   10 Apr 2001 18:09:35 
 Re: Дремина хитрость 2   Tolik Gusin   10 Apr 2001 19:01:28 
 Re[2]: Дремина хитрость 2   Drema   10 Apr 2001 22:42:27 
 Re: Re[2]: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 10:15:56 
 Re[4]: Дремина хитрость 2   Drema   11 Apr 2001 12:42:36 
 Re: Дремина хитрость 2   Tolik Gusin   11 Apr 2001 14:29:03 
 Hа: Дремина хитрость 2   Horsun Vlad   11 Apr 2001 15:16:11 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 19:19:29 
 Re: Дремина хитрость 2   Sergey Pratch   12 Apr 2001 19:42:52 
 Re: Дремина хитрость 2   Igor V. Makeev   13 Apr 2001 10:03:43 
 Re: Дремина хитрость 2   Sergey Pratch   13 Apr 2001 18:39:06 
 Insert в MSA   Igor V. Makeev   14 Apr 2001 14:43:45 
 Re: Insert в MSA   Sergey Pratch   16 Apr 2001 12:48:20 
 Re: Insert в MSA   Igor V. Makeev   16 Apr 2001 15:03:37 
 Re: Дремина хитрость 2   Tolik Gusin   11 Apr 2001 14:02:35 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 19:05:14 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 19:07:17 
 Re[2]: Дремина хитрость 2   Drema   11 Apr 2001 20:10:20 
 Дремина хитрость 2   Akzhan Abdulin   12 Apr 2001 13:15:01 
 Re: Дремина хитрость 2   Ilya Zvyagin   12 Apr 2001 18:21:00 
 Re: Дремина хитрость 2   Sergey Pratch   12 Apr 2001 19:42:53 
 Re: Дремина хитрость 2   Tolik Tentser   11 Apr 2001 18:44:45 
 Дремина хитрость 2   Akzhan Abdulin   12 Apr 2001 12:59:18 
 Дремина хитрость 2   Akzhan Abdulin   10 Apr 2001 15:20:38 
 Re: Дремина хитрость 2   Tolik Gusin   10 Apr 2001 19:10:25 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 10:28:08 
 Re: Дремина хитрость 2   Tolik Gusin   11 Apr 2001 13:54:23 
 Re: Дремина хитрость 2   Alexander Sakhatovskiy   11 Apr 2001 14:12:48 
 Re: Дремина хитрость 2   Tolik Gusin   11 Apr 2001 14:47:33 
 Re: Дремина хитрость 2   Ilya Zvyagin   11 Apr 2001 18:59:08 
 Дремина хитрость 2   Akzhan Abdulin   12 Apr 2001 13:02:40 
 Дремина хитрость 2   Makarov Vladimir   19 Apr 2001 10:20:17 
 Hа: Дремина хитрость 2   Horsun Vlad   11 Apr 2001 10:42:23 
 Re: Дремина хитрость 2   Serg Vasiltsoff   03 Apr 2001 12:54:43 
 RE: Дремина хитрость 2   Drema   03 Apr 2001 13:31:38 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 16:15:24 
 Re: Дремина хитрость 2   Ilya Zvyagin   02 Apr 2001 12:29:44 
 Re: Дремина хитрость 2   Sergey Pratch   02 Apr 2001 18:32:31 
 RE: Дремина хитрость 2   Drema*   02 Apr 2001 23:11:07 
 Re: Дремина хитрость 2   Serg Vasiltsoff   03 Apr 2001 10:58:04 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 13:15:14 
 RE: Дремина хитрость 2   Drema   03 Apr 2001 16:19:27 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 13:34:57 
 Дремина хитрость 2   Andrey   03 Apr 2001 09:14:42 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 10:49:55 
 RE: Дремина хитрость 2   Drema   03 Apr 2001 12:48:28 
 Re: Дремина хитрость 2   Ilya Zvyagin   03 Apr 2001 16:13:22 
 RE: Дремина хитрость 2   Drema   04 Apr 2001 12:28:49 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 13:45:04 
 Дремина хитрость 2   Akzhan Abdulin   03 Apr 2001 15:20:06 
 Re: Дремина хитрость 2   Ilya Zvyagin   04 Apr 2001 10:36:26 
 RE: Дремина хитрость 2   Drema   04 Apr 2001 14:48:26 
 Дремина хитрость 2   Akzhan Abdulin   04 Apr 2001 16:37:16 
 Дремина хитрость 2   Akzhan Abdulin   04 Apr 2001 16:28:32 
 Дремина хитрость.   Andrey   01 Apr 2001 13:03:40 
 Re: Дремина хитрость.   Serg Vasiltsoff   02 Apr 2001 16:41:54 
 Re: SELECT FROM INSERT ?   Tolik Tentser   30 Mar 2001 06:38:46 
 Re: SELECT FROM INSERT ?   Ilya Zvyagin   30 Mar 2001 09:59:10 
 Re: SELECT FROM INSERT ?   Ilya Zvyagin   30 Mar 2001 09:57:07 
 SELECT FROM INSERT ?   Andrei Sokolik   28 Mar 2001 12:16:18 
 Re: SELECT FROM INSERT ?   H.H.†гЄ®ў   28 Mar 2001 20:00:08 
Архивное /su.dbms.sql/2764ac7494ad.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional