Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / UPDATE без CASE / 5 сообщений из 5, страница 1 из 1
17.04.2002, 14:23
    #32028109
Новичок
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UPDATE без CASE
Как вот это сделать без CASE'a
...
UPDATE Personnel
SET lft = CASE
WHEN lft BETWEEN droplft AND droprgt THEN lft - 1
WHEN lft > droprgt THEN lft - 2
ELSE lft END
rgt = CASE
WHEN rgt BETWEEN droplft AND droprgt THEN rgt - 1
WHEN rgt > droprgt THEN rgt -2
ELSE rgt END;
WHERE lft > droplft;
END;
...


CREATE TABLE Personnel
(emp CHAR (10) PRIMARY KEY,
salary DECIMAL (8,2) NOT NULL CHECK (salary >=
0.00),
lft INTEGER NOT NULL UNIQUE CHECK(lft > 0),
rgt INTEGER NOT NULL UNIQUE CHECK(rgt > 0),
CHECK (lft < rgt));
...
Рейтинг: 0 / 0
18.04.2002, 03:30
    #32028139
Replicant
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UPDATE без CASE
А чем собственно CASE не устраивает (если он работает как надо)?
...
Рейтинг: 0 / 0
18.04.2002, 08:35
    #32028167
Новичок
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UPDATE без CASE
Дело в том, что это MS SQL конструкция, а мне надо хотя бы близко к стандарту. У меня FireBird стоит, а там таких "подпрыжек" нет.

Таблица такая


CREATE TABLE CLASS (
CLASSID INTEGER NOT NULL PRIMARY KEY ,
NAME CHAR(64) ,
lft INTEGER NOT NULL UNIQUE CHECK (lft > 0),
rght INTEGER NOT NULL UNIQUE CHECK (rgt > 1),
CONSTRAINT order_okay CHECK (lft < rgt));


Если циклом делать, примерно так:


CREATE PROCEDURE CLASS_INSERT (
CLASSID INTEGER ,
NAME CHAR (64) ,
PARENT INTEGER )
AS
DECLARE VARIABLE RIGHT_MOST_SIBLING INTEGER ;
DECLARE VARIABLE VAL_LEFT INTEGER ;
DECLARE VARIABLE VAL_RIGHT INTEGER ;
DECLARE VARIABLE VAL_ID INTEGER ;

BEGIN

SELECT
WC.RGHT FROM CLASS WC
WHERE (WC.CLASSID = :PARENT)
INTO :RIGHT_MOST_SIBLING;

FOR
SELECT
W1.LFT, W1.RGHT, W1.CLASSID
FROM CLASS W1
WHERE (W1.RGHT >= :RIGHT_MOST_SIBLING)
INTO :VAL_LEFT, :VAL_RIGHT, :VAL_ID
DO
BEGIN

IF
(:VAL_LEFT > :RIGHT_MOST_SIBLING) THEN
VAL_LEFT = :VAL_LEFT + 2;

UPDATE CLASS WR
SET WR.RGHT = :VAL_RIGHT + 2,
WR.RGHT = :VAL_LEFT
WHERE WR.CLASSID = :VAL_ID;
END

INSERT INTO CLASS (
CLASSID,
NAME,
LFT,
RGHT)
VALUES (
:CLASSID,
:NAME,
:RIGHT_MOST_SIBLING,
(:RIGHT_MOST_SIBLING + 1));
END


то выдаёт:


Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
violation of PRIMARY or UNIQUE KEY constraint "LFT" on table "CLASS".
...
Рейтинг: 0 / 0
18.04.2002, 08:37
    #32028169
Новичок
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UPDATE без CASE
Дело в том, что это MS SQL конструкция, а мне надо хотя бы близко к стандарту. У меня FireBird стоит, а там таких "подпрыжек" нет.

Таблица такая


CREATE TABLE CLASS (
CLASSID INTEGER NOT NULL PRIMARY KEY ,
NAME CHAR(64) ,
lft INTEGER NOT NULL UNIQUE CHECK (lft > 0),
rght INTEGER NOT NULL UNIQUE CHECK (rgt > 1),
CONSTRAINT order_okay CHECK (lft < rgt));


Если циклом делать, примерно так:


CREATE PROCEDURE CLASS_INSERT (
CLASSID INTEGER ,
NAME CHAR (64) ,
PARENT INTEGER )
AS
DECLARE VARIABLE RIGHT_MOST_SIBLING INTEGER ;
DECLARE VARIABLE VAL_LEFT INTEGER ;
DECLARE VARIABLE VAL_RIGHT INTEGER ;
DECLARE VARIABLE VAL_ID INTEGER ;

BEGIN

SELECT
WC.RGHT FROM CLASS WC
WHERE (WC.CLASSID = :PARENT)
INTO :RIGHT_MOST_SIBLING;

FOR
SELECT
W1.LFT, W1.RGHT, W1.CLASSID
FROM CLASS W1
WHERE (W1.RGHT >= :RIGHT_MOST_SIBLING)
INTO :VAL_LEFT, :VAL_RIGHT, :VAL_ID
DO
BEGIN

IF
(:VAL_LEFT > :RIGHT_MOST_SIBLING) THEN
VAL_LEFT = :VAL_LEFT + 2;

UPDATE CLASS WR
SET WR.RGHT = :VAL_RIGHT + 2,
WR.RGHT = :VAL_LEFT
WHERE WR.CLASSID = :VAL_ID;
END

INSERT INTO CLASS (
CLASSID,
NAME,
LFT,
RGHT)
VALUES (
:CLASSID,
:NAME,
:RIGHT_MOST_SIBLING,
(:RIGHT_MOST_SIBLING + 1));
END


то выдаёт:


Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
violation of PRIMARY or UNIQUE KEY constraint "LFT" on table "CLASS".
...
Рейтинг: 0 / 0
18.04.2002, 11:05
    #32028198
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UPDATE без CASE
А почему нельзя просто написать?

UPDATE Personnel
SET lft = lft - 1
where lft BETWEEN droplft AND droprgt

UPDATE Personnel
SET lft = lft - 2
where lft > droprgt

UPDATE Personnel
SET rgt = rgt - 1
where rgt BETWEEN droplft AND droprgt

UPDATE Personnel
SET rgt = rgt - 2
WHEN rgt > droprgt
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / UPDATE без CASE / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]