Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Всем доброго настроения.
Уважаемые фуромчане не подскажете как получив знавение уменьшить его на 1.
Вмысл сводится к следующему: выбираем из тиблицы самое минимальное значение и уменьшаем его на 1.
ALTER procedure [dbo].[AddRootDictionary]
@ID int output,
@DictName nvarchar(150),
@DictDescription nvarchar(MAX)
as
declare @ParentID int
select @ParentID = MIN(ParentID) from Dictionary where ParentID < 0
-- я тут использовал 
-- select @ParentID = @ParentID -1
-- но это неправильно
 insert into Dictionary([ParentID],[DictName],[DictDescription],[Created])
 values (@ParentID, @DictName, @DictDescription,GETDATE())
 select @ID = SCOPE_IDENTITY()
select @@VERSION
[FIXED]
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86)   Mar 29 2009 10:27:29   Copyright (c) 1988-2008 Microsoft Corporation  Express Edition with Advanced Services on Windows NT 5.1 <X86> (Build 2600: Service Pack 3) 
[/FIXED]

Одна из основных проблем человека - проблема выбора.
24 авг 09, 14:12    [7572997]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
select @ParentID = MIN(ParentID) - 1
  from Dictionary
 where ParentID < 0
?
24 авг 09, 14:15    [7573016]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
хотя вообще задача какая-то странная
если в БД присутствует ID равное 100 то это еще не значит, что имеется ID равное 99
автор, опишите, пожалуйста, задачу подробнее
24 авг 09, 14:17    [7573033]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель
select @ParentID = MIN(ParentID) - 1
  from Dictionary
 where ParentID < 0
?

да, сработало, Спасибо.
24 авг 09, 14:17    [7573035]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
insert into Dictionary([ParentID],[DictName],[DictDescription],[Created])
 select MIN(ParentID) - 1
, @DictName, @DictDescription,GETDATE()
  from Dictionary
 where ParentID < 0
24 авг 09, 14:18    [7573042]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель
хотя вообще задача какая-то странная
если в БД присутствует ID равное 100 то это еще не значит, что имеется ID равное 99
автор, опишите, пожалуйста, задачу подробнее

есть таблица Dictonary
USE [C:\DOCUMENTS AND SETTINGS\GDS\MY DOCUMENTS\VISUAL STUDIO 2008\PROJECTS\BOOKKEEPER\SHELLBOOKKEEPER\APPDATA\BOOKKEEPER.MDF]
GO

/****** Object:  Table [dbo].[Dictionary]    Script Date: 08/24/2009 14:18:26 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Dictionary](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[ParentID] [int] NOT NULL,
	[DictName] [nvarchar](150) NOT NULL,
	[Created] [datetime] NOT NULL,
	[Modified] [datetime] NULL,
	[stamp] [timestamp] NOT NULL,
	[state] [int] NOT NULL,
	[DictDescription] [nvarchar](max) NULL,
 CONSTRAINT [PK_Dictionary] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Dictionary] ADD  DEFAULT (getdate()) FOR [Created]
GO

ALTER TABLE [dbo].[Dictionary] ADD  DEFAULT ((3)) FOR [state]
GO

Некие древовидные данные. т.е.

1 -1 Статусы 2009-08-21 17:41:29.003 NULL 0x0000000000000FA5 3 Отображает состояние объектов/строк в Базе Данных
2 1 Общие статусы 2009-08-21 17:44:07.627 NULL 0x0000000000000FA6 3 Отображает стандартные статусы системы. Используются во всей базе данных.
3 2 Добавлен 2009-08-21 17:47:48.340 NULL 0x0000000000000FA9 3 Объект/запись добавлен(а) пользователем.
4 2 Заблокирован 2009-08-21 17:47:48.343 NULL 0x0000000000000FA8 3 Объект/запись заблокирован(а) пользователем.
5 2 Удален 2009-08-21 17:47:48.343 NULL 0x0000000000000FAA 3 Объект/запись удален(а) пользователем.
6 1 Сотрудники 2009-08-24 12:54:42.830 NULL 0x0000000000000FAB 3 Отображает дополнительные статусы для таблицы Сотрудники (Personal).
7 6 Активен 2009-08-24 13:31:31.363 NULL 0x0000000000000FAC 3 Сотрудник в настоящее время работает.
8 6 Отпуск 2009-08-24 13:31:31.363 NULL 0x0000000000000FAD 3 Сотрудник в настоящее время находится в отпуске.
9 6 На больничном 2009-08-24 13:31:31.363 NULL 0x0000000000000FAE 3 Сотрудник в настоящее время находиться на больничном.
10 6 Уволен 2009-08-24 13:31:31.367 NULL 0x0000000000000FAF 3 Сотрудник уволен.
11 -2 Подразделение 2009-08-24 13:34:22.587 NULL 0x0000000000000FB2 3 Отображает в каком подразделении числится сотрудник.
12 11 Основное 2009-08-24 13:34:22.587 NULL 0x0000000000000FB1 3 Основное подразделение. Присваивается по умолчанию.
14 -3 Типы Адресов 2009-08-24 14:16:44.880 NULL 0x0000000000000FB4 3 Содержит типы адресов
Все корни дерева имеют parentID отрицательные.
Надо сделать две процедуры.
1. добавляет элемент дерева - реализована. Входные параметры (id,parentid,name,...)
2. Добавляет корень дерева - реализована с вашей помошью. Входные параметры (id,name,...)
24 авг 09, 14:22    [7573071]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
gds
Все корни дерева имеют parentID отрицательные
А где они потом используются, эти отрицательные parentID ?
24 авг 09, 14:28    [7573114]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель
gds
Все корни дерева имеют parentID отрицательные
А где они потом используются, эти отрицательные parentID ?

в программе в отображении редактора словарей по средствам
/****** Object:  View [dbo].[v_rootDictionary]    Script Date: 08/24/2009 14:31:33 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

create view [dbo].[v_rootDictionary] as 
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.Created,d.Modified,d.stamp from [Dictionary] as d
where (d.ParentID < 0)
and (d.state = 3)
GO
а потом на основе этого строится дерево через
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION GetTreeDictionary 
(	
	@ParentID int
)
RETURNS TABLE 
AS
RETURN
with ste_dictionary(ID,ParentID,DictName,DictDescription,State,stamp,Created,Modified) as
(
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.stamp,d.Created,d.Modified 
from Dictionary as d 
where (d.state = 3) and (d.ParentID = @ParentID)
union all
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.stamp,d.Created,d.Modified 
from Dictionary as d 
inner join ste_dictionary as ste on d.ParentID = ste.ID
) select * from ste_dictionary

GO

24 авг 09, 14:55    [7573361]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
По этому условию
gds
where (d.state = 3) and (d.ParentID = @ParentID)
всегда будет отобрана одна запись, а именно какой-то из корней
и с нее CTE начнет рекурсивно выбирать все дерево, принадлежащее этому корню
я правильно понял?
24 авг 09, 15:02    [7573417]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель
По этому условию
gds
where (d.state = 3) and (d.ParentID = @ParentID)
всегда будет отобрана одна запись, а именно какой-то из корней
и с нее CTE начнет рекурсивно выбирать все дерево, принадлежащее этому корню
я правильно понял?

да
24 авг 09, 15:04    [7573448]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
а зачем Вы идентифицируете одну запись по ParentID?
Для этого же есть ID...

Другими словами, я не понимаю, почему GetTreeDictionary принимает на вход ParentID а не ID ?
24 авг 09, 15:07    [7573466]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
вот еще сейчас заметил, может кто подскажет правильно или нет?
при выполнении
with ste_dictionary(ID,ParentID,DictName,DictDescription,State,stamp,Created,Modified) as
(
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.stamp,d.Created,d.Modified 
from Dictionary as d 
where (d.state = 3) and (d.ParentID = -1)
union all
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.stamp,d.Created,d.Modified 
from Dictionary as d 
inner join ste_dictionary as ste on d.ParentID = ste.ID
) select ID,ParentID,DictName from ste_dictionary
результат 1

1 -1 Статусы
2 1 Общие статусы
6 1 Сотрудники
7 6 Активен
8 6 Отпуск
9 6 На больничном
10 6 Уволен
3 2 Добавлен
4 2 Заблокирован
5 2 Удален

Вообщето я ожидал что нить в этом духе
Результат 2

1 -1 Статусы
2 1 Общие статусы
6 1 Сотрудники
3 2 Добавлен
4 2 Заблокирован
5 2 Удален
7 6 Активен
8 6 Отпуск
9 6 На больничном
10 6 Уволен

в оракл отобразилось бы
Результат 3

1 -1 Статусы
2 1 Общие статусы
3 2 Добавлен
4 2 Заблокирован
5 2 Удален
6 1 Сотрудники
7 6 Активен
8 6 Отпуск
9 6 На больничном
10 6 Уволен

ладно хрен с ним Ораклом. Но по мне более логичным кажется это "результат 2".
Может че не так делаю?
Одна из основных проблем человека - проблема выбора.
24 авг 09, 15:10    [7573486]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
gds
Вообщето я ожидал что нить в этом духе
то есть те же данные, но в другом порядке?
А Вы порядок через order by задали?
24 авг 09, 15:14    [7573519]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель
а зачем Вы идентифицируете одну запись по ParentID?
Для этого же есть ID...

Другими словами, я не понимаю, почему GetTreeDictionary принимает на вход ParentID а не ID ?

В таблице Dictionary будут храниться несколько словарей (деревьев) например: статусы, типы адресов, типы документов. Что бы отобрать отдельное дерево надо либо вводить доп поле которое будет ответственным за то что это корень и соответсвенно... А кажется я понял к чему вы клоните. т.е. Вы, предлагаете отфильтровывать корни по ParentID < 0, а строить дерево по ID этой записи?
24 авг 09, 15:16    [7573539]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель
gds
Вообщето я ожидал что нить в этом духе
то есть те же данные, но в другом порядке?
А Вы порядок через order by задали?

Понял исправил. Просто в Оракл с построением дерева в этом случае чуть проще. Тогда получается что если в таблице имеется/будет предусмотрено только одно дерево. заморачиваться с СТЕ вобще не стоит, достаточно
order by ParentID, ID
?
24 авг 09, 15:20    [7573578]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
gds
Вы, предлагаете отфильтровывать корни по ParentID < 0
Нет
Я пытаюсь сказать, что ParentID должен использоваться по назначению
То есть для указания иерархии
Для "корней" родитель неизвестен
Поэтому можно туда всегда вписывать NULL,
а не заниматься генерированием несуществующих идентификаторов
путем нахождения минимумов и отнимания единиц

А отфильтровывать "корни" можно будет п условию ParentID IS NULL

gds
а строить дерево по ID этой записи?
Да, начинать с корня, идентифицируя его по ID
(предназначение Вашего state=3 я не знаю, оставлять или нет - решать Вам)
24 авг 09, 15:21    [7573585]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Паганель, всем понял спасибо за разъяснения.

Паганель
предназначение Вашего state=3 я не знаю, оставлять или нет - решать Вам

автор


3 2 Добавлен 2009-08-21 17:47:48.340 NULL 0x0000000000000FA9 3 Объект/запись добавлен(а) пользователем.
24 авг 09, 15:27    [7573626]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
gds
достаточно
order by ParentID, ID
?
Не знаю
Если Вы не задали order by, сервер имеет право выдать Вам данные в любом порядке
(грубо говоря - Вы не задали порядок значит он Вам неважен)

Но чтобы задать order by, нужно сперва для себя хотя бы по-русски попытаться объяснить -
как именно Вы хотите, чтобы сервер отсортировал данные
ID обязаны быть уникальными, но не обязаны быть возрастающими
Поэтому сортировать по ID имхо неверно
(ну не встречал я таких задач, хотя представляю себе,
что где-то в бухгалтерии сотрудников могли бы по номерам сотрировать в каком-нибудь отчете)

А как верно сортировать - этого, повторюсь, я не знаю, пока не увижу Ваше правило на русском языке
24 авг 09, 15:28    [7573638]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
И еще один вопросик.
Можно ли в функции использовать order by?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetTreeDictionary] 
(	
	@ParentID int
)
RETURNS TABLE 
AS
RETURN
with ste_dictionary(ID,ParentID,DictName,DictDescription,State,stamp,Created,Modified) as
(
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.stamp,d.Created,d.Modified 
from Dictionary as d 
where (d.state = 3) and (d.ParentID = @ParentID)
union all
select d.ID,d.ParentID,d.DictName,d.DictDescription,d.state,d.stamp,d.Created,d.Modified 
from Dictionary as d 
inner join ste_dictionary as ste on d.ParentID = ste.ID
) select * from ste_dictionary order by ParentID,ID

выдает ошибку
Msg 1033, Level 15, State 1, Procedure GetTreeDictionary, Line 17
Предложение ORDER BY не допускается в представлениях, встроенных функциях, производных таблицах, вложенных запросах и обобщенных табличных выражениях, если не указано TOP или FOR XML.
или можно только использовать в запросе?
select * from dbo.GetTreeDictionary(-1)
order by ParentID,ID
Одна из основных проблем человека - проблема выбора.
24 авг 09, 15:31    [7573651]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36808
Его придется использовать в запросе, если вы хотите иметь нужную сортировку.
24 авг 09, 15:33    [7573660]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22552
gds
или можно только использовать в запросе?
Да
Другими словами, Вы можете в одном запросе объединить (напр., через join) несколько table-valued функций
Если в каждой из них можно будет указывать свою сортировку, то сервер просто не будет знать, как именно сортировать

Поэтому задавайте сортировку в том запросе, в котором у Вас эта функция используется
24 авг 09, 15:35    [7573670]     Ответить | Цитировать Сообщить модератору
 Re: как уменьшить int на единицу  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Гавриленко Сергей Алексеевич,

Спасибо понял.

И в завершении Всем принимавшим участие огромное спасибо.

Топик наверное можно закрыть. По этой теме вопросов у меня больше нет.
24 авг 09, 15:36    [7573676]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить