Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
Есть следующий триггер:
CREATE TRIGGER T_STICKER_LIST_INSERT
 ON Sticker_list
 AFTER INSERT
 AS 
  DECLARE STICKER_LIST_CUR CURSOR SCROLL 
  FOR SELECT * FROM Sticker_list
  FOR UPDATE OF PRINTDATE
  
  OPEN STICKER_LIST_CUR
  FETCH LAST FROM STICKER_LIST_CUR    
  
  UPDATE Sticker_list 
  SET PRINTDATE = GETDATE()
  WHERE CURRENT OF STICKER_LIST_CUR
GO

При попытке добавить запись в таблицу
INSERT INTO Sticker_list
(SERNUM, STICKER_DATA_ID, USERID)
VALUES('9806080', 1, 1564)
Выдается сообщение: Server:
Msg 16957, Level 16, State 4, Procedure T_STICKER_LIST_INSERT, Line 6
FOR UPDATE cannot be specified on a READ ONLY cursor.

Почему курсор только для чтения я понять не могу, т.к. ему явно было указано, что курсор создается для обновления.
Может кто-нибудь уже сталкивался с подобной проблемой? Помогите.
13 апр 05, 10:48    [1463447]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Glory
Member

Откуда:
Сообщений: 104760
т.к. ему явно было указано, что курсор создается для обновления.
И как по вашему сервер сможет обновить что-то, если у вашей таьблицы к примеру отсутствует ПК ?
13 апр 05, 10:52    [1463486]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
Я плохо знаю MS SQL. В Oracle все делается гораздо проще. Тут же проблемы.
В общем, задача при Insert записать текущую дату в добавленную запись.
13 апр 05, 11:09    [1463594]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
А зачем тут вообще курсор? Тут можно прекрасно обойтись одним апдейтом, если есть поле (набор полей) однозначно определяющий запись. Пишем апдейт с джойном рабочей таблицы и inserted и все. Никаких курсоров.
13 апр 05, 11:09    [1463596]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Glory
Member

Откуда:
Сообщений: 104760
В общем, задача при Insert записать текущую дату в добавленную запись.

UPDATE a  SET PRINTDATE = GETDATE()
FROM Sticker_list  a
INNER JOIN inserted on a.PKfield = b.PKfield

А еще лучше назначить DEFAULT для столбца PRINTDATE.
13 апр 05, 11:10    [1463607]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Glory
Member

Откуда:
Сообщений: 104760
Я плохо знаю MS SQL. В Oracle все делается гораздо проще
Поэтому в Рекомендациях по оформлению сообщений и сказано
"6.
...
Подумайте также над тем, чтобы описать решаемую Вами задачу целиком. Возможно, что тот способ решения, который Вы стремитесь воплотить в жизнь, не является наилучшим, а лишь кажется Вам таковым.
..."
13 апр 05, 11:16    [1463639]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
Итак таблица имеет следующие метаданные:
CREATE TABLE Sticker_list
(
  SERNUM VARCHAR(10),
  STICKER_DATA_ID INT,
  PRINTDATE DATETIME,
  USERID INT
)
GO

-- Create Foreign key for Sticker_list to Sticker_data
ALTER TABLE Sticker_list
ADD CONSTRAINT STICKER_LIST_FK FOREIGN KEY (STICKER_DATA_ID)
REFERENCES Sticker_data (ID)   
GO

-- Create Check for Sticker_list
ALTER TABLE Sticker_list
ADD CONSTRAINT STICKER_LIST_SERNUM_CHK CHECK (SERNUM IS NOT NULL)
GO	

Хранит она записи из определенного заказа. Все заказы размещаются в Sticker_data. Соответственно создавать в Stricker_list поле IDENTITY не нужно, оно там избыточно. А значит не получится обновление вроде
UPDATE Sticker_list
SET PRINTDATE = GETDATE()
WHERE ID = @@IDENTITY
В Oracle подобные вещи решаются так:
CREATE OR REPLACE TRIGGER t_sticker_list
BEFORE INSERT ON sticker_list FOR EACH ROW
BEGIN
  :NEW.Print_Date := SYSDATE; -- Удобно, правда. И никах тебе курсоров
END t_sticker_list;
Соответственно, вопрос. Как реализовать указанную функциональность в MS SQL.
13 апр 05, 11:52    [1463877]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
Вам же Glory уже написал все.
13 апр 05, 11:53    [1463883]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
GreenSunrise
Вам же Glory уже написал все.

Так Glory предлагает создать Primary Key. А зачем мне нужно такое поле, если им никто пользоваться не будет.
Вопрос, как сделать указанное мной обновление без изменения структуры таблицы.
13 апр 05, 12:02    [1463950]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Glory
Member

Откуда:
Сообщений: 104760
А зачем мне нужно такое поле, если им никто пользоваться не будет.
Т.е. информация в таблицу будет только заносится ?
Ни удалятся ни обновлятся она не будет ?
13 апр 05, 12:04    [1463973]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
Glory
А зачем мне нужно такое поле, если им никто пользоваться не будет.
Т.е. информация в таблицу будет только заносится ?
Ни удалятся ни обновлятся она не будет ?

Если и будет удаляться, то только вручную. Обновляться не будет вообще.
Ок.
Мы несколько ушли от темы. В общем, единственный оптимальный выход - это курсор.
У меня курсор почему-то создается ReadOnly. Видимо это происходит из-за SCROLL. Убрал его - все нормально. Но. Теперь надо найти последнюю вставленную запись. Вопрос как. FETCH LAST не подойдет, т.к. курсор последовательный.
13 апр 05, 12:14    [1464027]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
nomshar
Если и будет удаляться, то только вручную. Обновляться не будет вообще

Вручную - это пользователь типа глазами шарит по списку и давит кнопку "удалить"?

И связей с другими таблицами у вас нет? Внешние ключи там, все такое?

P.S. а я-то голову ломаю, откуда на форуме вылезают с завидной регулярностью примеры с таким, простите, "проектированием"... Раньше казалось, что это новички по зелености клепают. Теперь кажется, туда же надо добавить некоторую часть ораклистов... Которым rownum по жизни заменяет первичный ключ.
13 апр 05, 12:20    [1464053]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
ChA
Member

Откуда: Москва
Сообщений: 11128
Как говаривал некто ЧАЛ, у ораклистов без курсоров "ну просто беда", да primary key им не нужен, есть же доступный rowid, который недоступен в MSSQL в принципе.
13 апр 05, 12:22    [1464066]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Glory
Member

Откуда:
Сообщений: 104760
Если и будет удаляться, то только вручную.
Вручную это типа правкой файла на низком уровне ?
Если все таки запросом, то скажите пожалуйста, как вы удалите запись если у нее отсутствует ПК ?

Но. Теперь надо найти последнюю вставленную запись. Вопрос как. FETCH LAST не подойдет, т.к. курсор последовательный.
Нет такого понятия в РСУБД как первая/последняя/предыдущая/последующая запись. Поэтому _добавленную_ запись вы без ПК никак не найдете.

Либо задавайте DEFAULT для столбца.
Либо пишите INSTEAD OF триггер (курсор там тоже не надо будет использовать)

И почитаейте в BOL про виртуальные таблицы inserted/deleted. Чтобы не перебирать в какихто других курсорах ВСЮ таблицу
13 апр 05, 12:24    [1464077]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
nomshar
Теперь надо найти последнюю вставленную запись.

Это что означает?
13 апр 05, 12:24    [1464081]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
GreenSunrise
nomshar
Если и будет удаляться, то только вручную. Обновляться не будет вообще

Вручную - это пользователь типа глазами шарит по списку и давит кнопку "удалить"?

И связей с другими таблицами у вас нет? Внешние ключи там, все такое?

P.S. а я-то голову ломаю, откуда на форуме вылезают с завидной регулярностью примеры с таким, простите, "проектированием"... Раньше казалось, что это новички по зелености клепают. Теперь кажется, туда же надо добавить некоторую часть ораклистов... Которым rownum по жизни заменяет первичный ключ.


Стоп. С каких пор пользователям разрешают прямой доступ к таблицам. Конечно удалять данные будет адниминстратор. Вообще можно не удалять.
Второе. Вы метаданные таблицы выше в этой теме смотрели? Там ясно написано, что создается внешний ключ и также добавлено для чего и что в другой таблице будет хранится.
Я опять же повторяю. Я не профессионал MS SQL. Работаю в Oracle. Но поставлена задача, перекинуть некоторые таблицы со всей функциональностью в MS SQL.
И еще раз. Как в INSERT триггере обновить поле только что вставленной записи. Любые идеи, кроме добавления поля Primary key. Неужели нет в такой большой системе как MS SQL Server подобных механизмов? Задача в принципе тривиальная.
13 апр 05, 12:28    [1464096]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Glory
Member

Откуда:
Сообщений: 104760
Стоп. С каких пор пользователям разрешают прямой доступ к таблицам. Конечно удалять данные будет адниминстратор. Вообще можно не удалять.
Причем здесь права ?
Я спрашивал как мне из таблицы без ПК запросом удалить одну конкретную запись

И еще раз. Как в INSERT триггере обновить поле только что вставленной записи.
Вставленной записи при отсутсивии ПК - никак

Неужели нет в такой большой системе как MS SQL Server подобных механизмов? Задача в принципе тривиальная.
Таблицы надо правильно проектировать. Тогда будет все тревиально независимо от сервера.
13 апр 05, 12:33    [1464124]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Serbat_Ivan
Member

Откуда: SQL.RU
Сообщений: 1603
nomshar
А зачем мне нужно такое поле, если им никто пользоваться не будет.


Им сервер будет пользоваться. Он же не oracle, у него нету rownum :)
13 апр 05, 12:33    [1464128]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
nomshar
С каких пор пользователям разрешают прямой доступ к таблицам. Конечно удалять данные будет адниминстратор.

Ну замените в моей фразе слово пользователь на слово администратор

GreenSunrise
Вручную - это администратор типа глазами шарит по списку и давит кнопку "удалить"?

Вопрос остается.

Более того, как вам уже раза три сказали, раз у вас не планируется изменения данных в этой таблице, а только инсерт и апдейт, то вам триггер вообще не нужен. Сделайте default для поля и все.

nomshar
Как в INSERT триггере обновить поле только что вставленной записи.

Вместо PK можно использовать любое поле (сочетание полей),
обеспечивающее однозначную идентификацию записи в таблице.
13 апр 05, 12:35    [1464138]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
ChA
Member

Откуда: Москва
Сообщений: 11128
nomshar
Как в INSERT триггере обновить поле только что вставленной записи. Любые идеи, кроме добавления поля Primary key. Неужели нет в такой большой системе как MS SQL Server подобных механизмов? Задача в принципе тривиальная.
Никак, без PRIMARY KEY или UNIQUE или уникального индекса не получится. В MSSQL нет доступа к внутреннему идентификатору.
13 апр 05, 12:36    [1464149]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
GreenSunrise
[quot nomshar]Более того, как вам уже раза три сказали, раз у вас не планируется изменения данных в этой таблице, а только инсерт и апдейт, то вам триггер вообще не нужен. Сделайте default для поля и все.


Так, если использовать default поле, то можно ли в MS SQL использовать для него возвращаемое значение функции, например, все той же GETDATE()?
13 апр 05, 12:38    [1464158]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
GreenSunrise
Member

Откуда:
Сообщений: 12310
да
13 апр 05, 12:44    [1464184]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
Serbat_Ivan
Member

Откуда: SQL.RU
Сообщений: 1603
nomshar
Так, если использовать default поле, то можно ли в MS SQL использовать для него возвращаемое значение функции, например, все той же GETDATE()?

Легко.
13 апр 05, 13:09    [1464281]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
nomshar
Member

Откуда: Москва
Сообщений: 19
Все, спасибо. Слава, Богу, найдено оптимальное решение.
13 апр 05, 14:08    [1464599]     Ответить | Цитировать Сообщить модератору
 Re: Cursor  [new]
AAron
Member

Откуда: Москва
Сообщений: 4324
я подозреваю, что и в оракле такой же бардак с базой.

не нужно объявлять CHECK CONSTRAINT "STICKER_LIST_SERNUM_CHK", т.к. можно объявить столбец SERNUM VARCHAR(10) not null. Насчет PK - интересен подход - объявим FOREIGN KEY в таблицы, но не будем использовать PRIMARY KEY. В чем причина такого неприятия?
13 апр 05, 14:19    [1464672]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить