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

Откуда:
Сообщений: 72
У меня есть таблица в хранимой процедуре:
DECLARE @defferPlayers table(ID int identity PRIMARY KEY, ID_Player int);
INSERT @defferPlayers
SELECT ID
FROM Players
WHERE ID_Team = @Team2 AND PlayerType = 1


Она используется в цикле, каждый раз она должна очищатся в конце цикла, а потом снова наполнятся, мне нужно чтобы идентификатор всегда начинался с 1, но не получается использовать DBCC CHECKIDENT для таблицы что является переменной, подскажите пожалуйста, можно ли при помощи DBCC CHECKIDENT это сделать или по-другому как-то??
18 мар 12, 21:28    [12270428]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
Использовать временную таблицу, или избавиться от цикла, или работу с таблицей-переменной вынести в отдельную процедуру.
18 мар 12, 21:38    [12270458]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
mantap
Member

Откуда:
Сообщений: 72
Спасибо огромное, я твой должник, использовал функцию, просто уже час с этим долбался, мозг на взрыве был, спасибо огромное
18 мар 12, 21:55    [12270499]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
Еще можно в конце каждой итерации определять максимальное значение ID и использовать его в качестве смещения на следующей.
А еще лучше попробовать избавиться от цикла.
18 мар 12, 23:08    [12270769]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
mantap
Member

Откуда:
Сообщений: 72
Спасибо за идею со смещением, в следующей хранимой процедуре понадобилась сильно. От цикла избавится никак, SQL месяц только изучаю, до этого работал с C#, поэтому сама логика в MS SQL локальной переменной не очень понятно, по завершению текущего этапа цикла она должна удалять, а потом заново создаваться в следующем этапе цикла, но она не удаляется, а поскольку с логикой Pascal не знаком, проблемно немного.
20 мар 12, 18:57    [12283680]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
mantap,

Показывайте код целиком.
А Паскаль тут откуда взялся?
20 мар 12, 19:13    [12283756]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
mantap
Member

Откуда:
Сообщений: 72
invm,

У меня есть задание:

Создать БД "Чемпионат страны по футболу".
Необходимо хранить следующую информацию о команде:

-название команды;
-состав команды (личные данные каждого игрока + количество забитых голов игроком (для голкипера - пропущенные мячи));
-ФИО тренера;
-названия стадионов на которых играет команда;
-результат игры команды по каждому туру (имя команды соперника, счет матча, количество добытых очков).

Задания (в виде хрнимых процедур и функций):

1.подсчитать количество забитых (пропущенных) командой голов;
2.вывести лучшего бомбардира чемпионата и лучшего бомбардира по команде;
3.вывести лучшего голкипера;
4.определить турнирное положение команды по заданному туру;
5.вывести результаты конкретной команды по каждому туру;
6.вывести "турнирный путь" чемпиона;
7.вывести имя команды, забившей большее количество голов.

Структуру я уже создал:
CREATE TABLE Trainers
(
ID int identity PRIMARY KEY,
FirstName varchar(32),
LastName varchar(32)
)

CREATE TABLE Stadions
(
ID int identity PRIMARY KEY,
Name varchar(64)
)

CREATE TABLE Teams
(
ID int identity PRIMARY KEY,
Name varchar(64),
ID_Trainer int FOREIGN KEY REFERENCES Trainers,
ID_Stadion int FOREIGN KEY REFERENCES Stadions
)

CREATE TABLE Players
(
ID int identity PRIMARY KEY,
FirstName varchar(32),
LastName varchar(32),
Age int,
Score int,
PlayerType bit,
ID_Team int FOREIGN KEY REFERENCES Teams
)

CREATE TABLE Games
(
ID int identity PRIMARY KEY,
ID_HomeTeam int FOREIGN KEY REFERENCES Teams,
ID_GuestTeam int FOREIGN KEY REFERENCES Teams,
HomeTeamScore int,
GuestTeamScore int,
Tournament int
)


Я заполнил таблицы команд, игроков и стадионов вручную
Есть хранимая процедура которая в зависимости от количества команд генерирует автоматически игры, random'но устанавливает голы и также random'но выбираются игроки и им начисляются очки, я её прикрипил в файле к сообщению
Изначально вопрос адрессовался именно из-за проблемы с этой хранимой процедурой, мне необходимо было использовать переменную типа table(ID int PRIMARY KEY, ID_Player int) в цикле, в цикле я ей в каждом этапе вконце очищал, поскольку она в отличие от переменных в C# не удалялась, но ID мне нужно было чтобы постоянно начинался с 1, а при очистке identity всё равно продалжал давать ID с последнего значения, поэтому я использовал функцию как вы советывали, всё это есть в прикреплённом запросе.

Сейчас я делаю задание:
5.вывести результаты конкретной команды по каждому туру;
У меня снова возникла аналогичная проблема в цикле, но здесь уже не выйдет решить проблему функцией
Привожу пример: Я сформировал таблицу по 3-тему туру, куда записал ID строки данной, название команды и их очки, потом по очкам сортирую и мне необходимо определить место команды по данной таблице, но поскольку после сортироваки ID строк идут в разброс, поэтому всё что я пока что придумал, это создать аналагичную переменную типа таблицы с ID identity и туда залить отсортированные данные. Может вы ещё подскажите какую идею, буду очень благодарен. Вот код этой хранимой процедуры:
ALTER PROCEDURE TeamStatusByChampionship @Team varchar(64) AS
DECLARE @ResTable table(ID int identity PRIMARY KEY, Place int, Score int);--таблица для данной команды по каждому туру(ИД, Место в данном туре, Очки)
DECLARE @STable table(ID int identity PRIMARY KEY, TName varchar(64), Games int, Vins int, DeadHeats int , Loses int, Score int);--таблица с очками команд по определённому циклу
DECLARE @j int;
SET @j = 1;
WHILE @j <= (SELECT COUNT(*) FROM Tournaments)
BEGIN
	DECLARE @i int;
	SET @i = 1;
	DECLARE @tmp table(ID int identity PRIMARY KEY, TName varchar(64), Score int);--временная таблица
	WHILE @i <= (SELECT COUNT(*) FROM Teams)
	BEGIN
		DECLARE @CurrentTeamName varchar(64);--название текущей команды
		DECLARE @Score int;--очки
		DECLARE @Vins int;--победы
		DECLARE @DeadHeats int;--ничьи
		DECLARE @Loses int;--проигрыши
		SET @Score = 0;
		SET @Vins = 0;
		SET @DeadHeats = 0;
		SET @Loses = 0;
		SET @Vins = @Vins + (SELECT COUNT(*)
							 FROM Games
							 WHERE ID_HomeTeam = @i AND HomeTeamScore>GuestTeamScore AND Tournament <= @j
							 OR ID_GuestTeam = @i AND HomeTeamScore<GuestTeamScore AND Tournament <= @j);
		SET @DeadHeats = @DeadHeats + (SELECT COUNT(*)
							 FROM Games
							 WHERE ID_HomeTeam = @i AND HomeTeamScore=GuestTeamScore AND Tournament <= @j
							 OR ID_GuestTeam = @i AND HomeTeamScore=GuestTeamScore AND Tournament <= @j);
		SET @Loses = @j - (@Vins + @DeadHeats)
		SET @CurrentTeamName = (SELECT Name FROM Teams WHERE ID = @i);
		SET @Score = (@Vins * 2) + @DeadHeats;
		INSERT INTO @STable VALUES(@CurrentTeamName, @j, @Vins, @DeadHeats, @Loses, @Score);
		SET @i = @i + 1;
	END
	INSERT @tmp
	SELECT TName, Score
	FROM @STable
	ORDER BY Score DESC
	
	DECLARE @change int;
	SET @change = ((SELECT COUNT(*) FROM Teams) * (@j-1));

	UPDATE @tmp
	SET ID = ID - @change

	DECLARE @Place int;
	SET @Place = (SELECT ID FROM @tmp WHERE TName = @Team);
	DECLARE @TSBT int;
	SET @TSBT = (SELECT Score FROM @tmp WHERE TName = @Team);
	INSERT INTO @ResTable VALUES(@Place, @TSBT);
	DELETE FROM @tmp;
	DELETE FROM @STable;
	SET @j = @j + 1;
END
SELECT *
FROM @ResTable;
20 мар 12, 20:54    [12284128]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
mantap, при работе с SQL старайтесь быстрее отвыкнуть от императивного мышления, иначе будут сплошные циклы.
with scores(Tournament, team_id, Score) as
(
 select
  Tournament,
  ID_HomeTeam,
  HomeTeamScore
 from
  dbo.Games

 union all

 select
  Tournament,
  ID_GuestTeam,
  GuestTeamScore
 from
  dbo.Games
),
tournament_scores as
(
 select
  s.Tournament,
  s.team_id,
  t.Name,
  s.Score + isnull(x.PrevScoreSum , 0) as Score,
  row_number() over (partition by s.Tournament order by s.Score + isnull(x.PrevScoreSum , 0) desc) as Place
 from
  scores s join
  dbo.Teams t on t.ID = s.team_id outer apply
  (select sum(Score) from scores where Tournament < s.Tournament and team_id = s.team_id) x(PrevScoreSum)
)
select
 *
from
 tournament_scores
order by
 Tournament, Place;
20 мар 12, 22:37    [12284601]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
mantap
Member

Откуда:
Сообщений: 72
Спасибо за помощь.
Я хотел бы узнать пару вопросов:
1)Почему не желательно использовать циклы(в моём случае понятно, я в цикле кучу раз по таблицам перебераю)?
2)Что означает x(PrevScoreSum)??
20 мар 12, 22:58    [12284720]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
mantap
1)Почему не желательно использовать циклы(в моём случае понятно, я в цикле кучу раз по таблицам перебераю)?
Потому что SQL сервера предназначены для эффективной работы с множествами, а не для построчной обработки данных. Т.е., говоря простым языком, циклы и построчная обработка -- практически гарантированные тормоза.
mantap
2)Что означает x(PrevScoreSum)??
Алиас вместе с указанием наименований полей.
20 мар 12, 23:12    [12284779]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
mantap
Member

Откуда:
Сообщений: 72
Можете пожалуйста мне на почту mantap@mail.ru прислать ваш скайп или другой способ через который можно с вами поговорить, просто есть пару вопросов которые на 1-2 мин обсуждения, а на форуме на долго это. Взаранее спасибо.
20 мар 12, 23:55    [12284938]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с DBCC CHECKIDENT  [new]
invm
Member

Откуда: Москва
Сообщений: 9845
mantap, мыло в профиле.
21 мар 12, 00:00    [12284964]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить