Удаление записей из интервала

  • Автор темы NikSoft
  • Дата начала
N

NikSoft

#1
Пусть нам нам надо удалить из заданной таблицы n записей из заданного интервала. Следующая процедура решает задачу.

Код:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sp_RemoveRowsFromInterval] 
@table varchar(50),
@StartInterval int,
@EndInterval int
AS
BEGIN

DECLARE @result integer, @ExecSql nvarchar(2500)

SELECT @ExecSql = N'
DECLARE @Start integer, @End integer, @Temp integer

IF OBJECT_ID(N''costupdate..TempTable'', N''U'') IS NOT NULL 
DROP TABLE TempTable

SELECT @End = COUNT(*) FROM ' + @table +
' 
IF @End = 0
BEGIN
RAISERROR('''', 0, 1) -- a success - nothing to delete
RETURN
END
IF ' + RTRIM(Convert(char, @StartInterval)) + ' < 1
SET @Start = 1
ELSE
IF ' + RTRIM(Convert(char, @StartInterval)) + ' > @End
SET @Start = @End
ELSE
SET @Start = ' + Convert(char, @StartInterval) + 
' 

IF ' + RTRIM(Convert(char, @EndInterval)) + ' > @End
SET @Temp =1
ELSE
IF ' + RTRIM(Convert(char, @EndInterval)) + ' < 1
SET @End = 1
ELSE
SET @End = ' + Convert(char, @EndInterval) + 
' 
SELECT * INTO TempTable FROM ' + @table + ' WHERE 1 = 2	

IF(@Start > @End) OR (@End < @Start)
BEGIN
IF OBJECT_ID(N''costupdate..TempTable'', N''U'') IS NOT NULL 
DROP TABLE TempTable

RAISERROR(''This is an error!'', 17, 1) -- an error - wrong indexes 
RETURN;
END
ELSE
BEGIN
ALTER TABLE TempTable ADD PrimKey int NOT NULL IDENTITY (1, 1)
ALTER TABLE TempTable ADD CONSTRAINT constraint_TempTable PRIMARY KEY(PrimKey)

INSERT TempTable SELECT * FROM ' + @table +

' 
DELETE TempTable WHERE PrimKey BETWEEN @Start AND @End

TRUNCATE TABLE ' + @table + 
' 

ALTER TABLE TempTable DROP CONSTRAINT constraint_TempTable
ALTER TABLE TempTable DROP COLUMN PrimKey

INSERT ' + @table +' SELECT * FROM TempTable

IF OBJECT_ID(N''costupdate..TempTable'', N''U'') IS NOT NULL 
DROP TABLE TempTable

RAISERROR('''', 0, 1) -- a success 
RETURN
END
'
EXEC @result = sp_executesql @ExecSql
SET @result = @@ERROR
RETURN @result

END
В качестве параметров процедуры задается имя таблицы, порядковые номера первой и последней удаляемых записей. Предполагается, что таблица не имеет PK,FK ключей. Данная процедура может быть вызвана на языке C# следующим методом.

Код:
public void RemoveRowsFromIntervals(string tableName, int startInterval, int endInterval)
{
try
{
Connection.Open();

SqlCommand command = new SqlCommand("sp_RemoveRowsFromInterval", Connection);
command.CommandType = CommandType.StoredProcedure;

SqlParameter parameter1 = command.Parameters.Add("@table", SqlDbType.VarChar, 50);
parameter1.Value = tableName;

SqlParameter parameter2 = command.Parameters.Add("@StartInterval", SqlDbType.Int);
parameter2.Value = startInterval;

SqlParameter parameter3 = command.Parameters.Add("@EndInterval", SqlDbType.Int);
parameter3.Value = endInterval;

command.ExecuteNonQuery();

}
catch (SqlException ex)
{
Debug.WriteLine("A sql exception was encountered: " + ex.Message + "\nType of sql exception: " + ex.GetType() + "\nStack of sql exception: " +ex.StackTrace);
}
catch (Exception e)
{
Debug.WriteLine("An exception was encountered: " + e.Message + "\nType of exception: " + e.GetType() + "\nStack of exception: " +e.StackTrace);
}  
finally
{
Connection.Close();
}
}
Заметим, что выражение ex.Message в случае ошибки ( например, неправильно задан интервал записей: 19, 11 ) будет содержать сообщение ''This is an error!'' из процедуры. Таким образом, помимо всего прочего, показан метод передачи диагностики из процедуры в программу, которая ее вызывает.