Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > Вставка слова в таблицу


Автор: Sliva 8.5.2006, 13:55
У меня  в таблице хранится кроссворд: 
id -  идентификатор слова
x- координата буквы в таблице 
y- координата буквы в таблице
len- длина слова
VH- вертикально расположено или горизонтально
(работаю в PL\SQL)
 Мне нужно вставить слово в кроссворд - должна быть функция вставки.
Подскажите как?  smile  

Автор: HalkaR 8.5.2006, 13:59
Так вам на чем на PL\SQL или MySQL? 

Автор: Sliva 9.5.2006, 01:07
PL\SQL!  smile  Плиз! 

Автор: Ignat 9.5.2006, 12:48

M
Ignat
Перемещено из MySQL

 

Автор: LSD 9.5.2006, 13:49
Полную структуру таблиц дай, сколько их там у тебя 1 или 2. 

Автор: Sliva 9.5.2006, 14:58
Код
CREATE TABLE  Crossword
(
  id  INTEGER PRIMARY KEY,  // id слова
  x  INTEGER,  // координаты в таблице
  y  INTEGER, //
  len  INTEGER, // длина слова
  word VARCHAR2 (10),  // само слово
  VH INTEGER,  // горизонтально или вертикально
  idT  INTEGER FOREIGN KEY  // id кроссворда, в которой расположено слово
);

Т.е. получается, что у меня есть таблица, в которой хранятся слова, и в которой указано к какому кроссворду они принадлежат.
А мне нужно в PL\SQL написать вставку слова в кроссворд. Help!  smile   

Автор: LSD 9.5.2006, 16:45
Я не пойму, что должна делать процедура. Никакой обработки вставляемых данных тут нет. Максимум триггером проверить что VH имеет правильное значение и вычислить LEN. 

Автор: Sliva 9.5.2006, 17:28
Дело в том, что программно надо написать процедуру, у которой в параметрах будет слово и его вставить в таблицу. Надо же учитывать на какую позицию вставляем:  Нельзя же вставить слово на место другого слова!  smile  
А про триггеры  нам еще не рассказывали  smile  а как с ними?
 

Автор: LSD 9.5.2006, 17:30
Т.е. процедура должна перебрать все свободные места и найти нужное? 

Автор: Sliva 9.5.2006, 17:49
Фактически она должна вставить слово на пустое место, куда захочет пользователь - вот в чем дело  

Автор: Sliva 9.5.2006, 21:29
Если быть точнее, 
то я пишу следю процедуру:
 
Код

PROCEDURE  InsertWord  (w in VARCHAR2(10),  xst in INTEGER, yst in INTEGER, pol in INTEGER, ic in INTEGER)  
 -- st - столбец x  ,str -строка  y, pol - положение слова - по горизонтали -1 или вертикали - 0

IS 

 --  выбирает символ из таблицы   
CURSOR getSymb (st in INTEGER, str in INTEGER) IS
   SELECT word  FROM Crossword WHERE  (x = st)  AND (y = str);

  BEGIN 
     i  INTEGER;
    lenw INTEGER; -- длина слова
    h INTEGER;
    v  INTEGER; 
   symP VARCHAR2(1);  -- текущий символ справа
  symL VARCHAR2(1);  -- текущий символ  слева


    lenw:= LENGTH(w); -- узнали длину вставляемого слова 
   
     open getSymb (xst-1,yst); 
     FETCH getSymb INTO  symL;    --  узнали букву  слева
    open getSymb (xst+1,yst);           
    FETCH getSymb INTO  symP;    --  узнали букву    справа 
      

   IF  ( (symP = '' ) and (pol = 1) )   -- если справа пусто и вставляем слово по горизонтали
     FOR i in xst..lenw 
    LOOP
         UPDATE  Crossword  SET  y = yst, len = lenw, word = w[i],  VH = 1, idT = ic  
             WHERE  x = i; 
    END LOOP;      
   ELSE   --   IF ((symP = "") and (pol ))    -- если справа пусто и вставляем слово по вертикально
    FOR i in yst..lenw 
    LOOP
         UPDATE  Crossword  SET x = xst, len = lenw, word = w[i],  VH = 0, idT = ic  
            WHERE  y = i;              
    END  LOOP;       
  
  END InsertWord; 

 

Автор: LSD 10.5.2006, 22:47
Цитата(Sliva @  9.5.2006,  22:29 Найти цитируемый пост)
Если быть точнее, 
то я пишу следю процедуру:

У тебя тут есть пара небольших синтаксических ошибок, неправильно организован цикл. Но это все лего поправимо, главное я не могу понять как у тебя хранятся в базе слова. Зачем тебе надо делать несколько инсертов в таблицу для каждого слова? И каков смысл тех проверок, что ты делаешь? 

Автор: Sliva 10.5.2006, 23:06
Я вставляю слово на произвольное место в кроссворде (то бишь в таблицу), но там же может стоять другое слово! Мне нужно проверить:
1. Можно ли вставить слово, т.е. есть ли свободное место;
2. Если там есть слово, то можем ли мы верно вставить слово, например: по горизонтали стоит слово "восток", а я вставляю слово "кот" по вертикали. Т.е. я МОГУ ВСТАВИТЬ, но я должна проверить, что я вставляю на последнюю букву слова "востоК". 
Я сижу сейчас, разбираюсь - тут по идее должна быть целая куча проверок, ifов!!!  
Посмотри, пожалуйста!  smile  

Автор: LSD 10.5.2006, 23:14
Тогда я думаю лучше будет хранить не слово, а буквы (или ввести еще одну таблицу с буквами), каждую в своей ячейке. И соответсвенно при вставке делать проверки. 

Автор: Sliva 10.5.2006, 23:27
Я, кстати, вчера изменила таблицу. Теперь она выглядит так: 
Код
CREATE TABLE  Crossword
(
  x  INTEGER,  
  y  INTEGER, 
  word VARCHAR2 (1), // буква
  VH boolean,
  idCros FOREIGN KEY 
);

Только со вставкой замучаешься! 
А в моей процедуре InsertWord - тоже тогда в параметрах передавать букву или можно слово?  smile  И вообще корректно в цикле писать, например: for i in 1..len w:= word[i]? 
Если w типа VARCHAR2(1), а word  типа  VARCHAR2(10)????  

Автор: LSD 11.5.2006, 20:53
У меня получилось следующая структура: 2 таблицы.

Одна содержит слово, координаты начала и направление:
Код
create table WORDS
(
  ID        raw(16) default sys_guid(),
  X         number(5) not null,
  Y         number(5) not null,
  DIRECTION number(1) not null,
  WORD      varchar2(25) not null
);

alter table WORDS
  add constraint WORDS_PK primary key (ID);
alter table WORDS
  add constraint WORDS_UNIC unique (X, Y, DIRECTION);


Другая содержит букву, ссылку на слово к которому она принадлежит, координаты:
Код
create table LETTERS_GRID
(
  ID     raw(16) default sys_guid(),
  WORD   raw(16) not null,
  X      number(5) not null,
  Y      number(5) not null,
  LETTER char(1) not null
);

alter table LETTERS_GRID
  add constraint LETTERS_GRID_PK primary key (ID);
alter table LETTERS_GRID
  add constraint LETTERS_GRID_FK foreign key (WORD)
  references WORDS (ID) on delete cascade;

create index LETTERS_GRID_IDX on LETTERS_GRID (X, Y, LETTER);

(при удалении слова все связанные с ним буквы удаляются)

Процедура которая для заданного слова заполняет таблицу с буквами:
Код
create or replace procedure FILL_LETTERS_GRID(WORD_ID in raw) is

  WORD      varchar2(25);
  LEN       number;
  LETTER    char(1);
  X         number;
  Y         number;
  CUR_X     number;
  CUR_Y     number;
  DIRECTION number;
  I         number;
  J         number;

begin

  select W.X, W.Y, W.DIRECTION, UPPER(W.WORD)
    into X, Y, DIRECTION, WORD
    from WORDS W
   where W.ID = WORD_ID;

  LEN   := LENGTH(WORD);
  CUR_X := X;
  CUR_Y := Y;

  for I in 1 .. LEN loop
  
    if DIRECTION = 0 then
      CUR_Y := Y + I - 1;
    else
      CUR_X := X + I - 1;
    end if;
  
    LETTER := SUBSTR(WORD, I, 1);
  
    select count(*)
      into J
      from LETTERS_GRID L
     where L.X = CUR_X
       and L.Y = CUR_Y
       and L.LETTER <> LETTER;
  
    if J = 0 then
      insert into LETTERS_GRID (WORD, X, Y, LETTER) values (WORD_ID, CUR_X, CUR_Y, LETTER);
    else
      RAISE_APPLICATION_ERROR(-20101, 'Invalid invalid letter at [' || TO_CHAR(CUR_X) || ',' || TO_CHAR(CUR_Y) || ']');
    end if;
  
  end loop;

end FILL_LETTERS_GRID;


Триггер на табличку со словами, который при вставке очередного слова будет заполнять таблицу с буквами:
Код
create or replace trigger FILL_LETTERS_GRID_TRG
  after insert on WORDS
  for each row
begin
  FILL_LETTERS_GRID(:new.ID);
end FILL_LETTERS_GRID_TRG;


Пользователю на таблицу LETTERS_GRID дать только select, а в таблице WORDS запретить изметять столбец WORD или дописать логику по обработке такой ситуации.  

Автор: Sliva 11.5.2006, 20:53
Очень нужно! Ответьте, пожалуйста - корректна ли следующая запись: for i in 1..len w:= word[i]? 
w - БУКВА VARCHAR(1)
word - СЛОВО VARCHAR2(10)? 

Автор: LSD 11.5.2006, 20:55
Цитата(Sliva @  11.5.2006,  21:53 Найти цитируемый пост)
Очень нужно! Ответьте, пожалуйста - корректна ли следующая запись: for i in 1..len w:= word[i]? 
w - БУКВА VARCHAR(1)
word - СЛОВО VARCHAR2(10)? 

Нет, переменная VARCHAR2 это не массив. 

Автор: Sliva 11.5.2006, 21:04
Спасибо, LSD! Сейчас буду разбираться  smile  

Автор: LSD 11.5.2006, 21:13
Плиз smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)