Инструменты пользователя

Инструменты сайта


sql001.otbor_mnozhestva_zapisej_po_kljucham



SQL001. Отбор множества записей по ключам

Описание

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

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

Например, при построении отчета «Движение товарно-материальных ценностей по складу», когда пользователь указывает (ставит галочки) в клиентском приложении по каким именно товарно-материальным ценностям отбирать объекты-движения. Клиентское приложение на основании отмеченных пользователем записей формирует строку-параметр, в которой через запятую перечислены коды элементов (записей) справочника «Товарно-материальные ценности».

Пример

CREATE PROCEDURE CONVERT_IDS_TO_ROWS(
  IDS VARCHAR(32700)
)RETURNS (
  ID INTEGER
)AS
  DECLARE I INTEGER = 1;
  DECLARE J INTEGER = 1;
BEGIN
  IDS = TRIM(:IDS);
  WHILE (:I <= CHAR_LENGTH(:IDS)) DO
  BEGIN
    IF (',' = SUBSTRING(:IDS FROM :I FOR 1)) THEN
    BEGIN
      ID = SUBSTRING(:IDS FROM :J FOR :I - :J);
      SUSPEND;
      I = :I + 1;
      J = :I;
    END
    I = :I + 1;
  END
  IF (:I > :J) THEN
  BEGIN
    ID = SUBSTRING(:IDS FROM :J FOR :I - :J);
    SUSPEND;
  END
END
 
 
CREATE PROCEDURE LIST_TO_ROWS (
    A_LST BLOB SUB_TYPE TEXT,
    A_DELIMITER CHAR(1) = ',',
    A_NULL VARCHAR(1) = '')
RETURNS (
    LINE INTEGER,
    ITEM VARCHAR(32000))
AS
  DECLARE POS_   INTEGER;
  DECLARE OFFSET INTEGER = 1;
  DECLARE BEG    INTEGER;
  DECLARE BUF    VARCHAR(32000);
BEGIN
  IF (A_LST IS NULL) THEN EXIT;
  LINE = 0;
 
  WHILE (0=0) DO BEGIN
    BUF = SUBSTRING(A_LST FROM OFFSET FOR 32000);
    POS_ = 1; BEG = 1;
    WHILE (POS_ <= CHAR_LENGTH(BUF) AND POS_ <= 32000) DO BEGIN
      IF (SUBSTRING(BUF FROM POS_ FOR 1) = A_DELIMITER) THEN BEGIN
        IF (POS_ > BEG) THEN
          ITEM = SUBSTRING(BUF FROM BEG FOR POS_ - BEG);
        ELSE
          ITEM = A_NULL;
        SUSPEND;
        LINE = LINE + 1;
        BEG = POS_ + 1;
      END
      POS_ = POS_ + 1;
    END
    IF (BEG = 1 AND POS_ > 32000) THEN LEAVE;
    IF (OFFSET + POS_ - 2 = CHAR_LENGTH(A_LST)) THEN LEAVE;
    OFFSET = OFFSET + BEG - 1;
    IF (OFFSET > CHAR_LENGTH(A_LST)) THEN LEAVE;
  END
 
  IF (BEG = 1 AND POS_ > 32000) THEN BEGIN
    ITEM = '#N/A';
  END
  ELSE IF (POS_ > BEG) THEN BEGIN
    ITEM = SUBSTRING(BUF FROM BEG FOR POS_ - BEG);
  END
  ELSE BEGIN
    ITEM = A_NULL;
  END
  SUSPEND;
END

См. также

Источник

Форум SQL.RU, автор: WildSery

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
W K H W H
 
sql001.otbor_mnozhestva_zapisej_po_kljucham.txt · Последнее изменение: 2016/03/10 13:59 — wildsery