ErrorsManager/SQLServer/ErrorsManager.server.sql
2026-07-15 14:32:32 +02:00

809 lines
28 KiB
Transact-SQL

if (select top 1 0 from sys.databases where name = 'ErrorsManager') is null create database ErrorsManager collate Latin1_General_CI_AS
go
use ErrorsManager
if object_id(N'dbo.tables_drop', N'P') is not null drop procedure dbo.tables_drop
go
create procedure dbo.tables_drop as begin set nocount on
-- Level 1.
if object_id(N'dbo.Settings', N'U') is not null drop table dbo.Settings
-- Level 0.
if object_id(N'dbo.Sets', N'U') is not null drop table dbo.Sets
if object_id(N'dbo.Types', N'U') is not null drop table dbo.Types
if object_id(N'dbo.Messages', N'U') is not null drop table dbo.Messages
end
go
if object_id(N'dbo.tables_create', N'P') is not null drop procedure dbo.tables_create
go
create procedure dbo.tables_create as begin set nocount on
-- Level 0.
if object_id(N'dbo.Sets', N'U') is null create table dbo.Sets(
id int not null identity(1, 1),
[key] varchar(32) not null,
alphabet varchar(128) collate Latin1_General_CS_AS not null,
base smallint not null,
power tinyint not null,
in_use bit not null constraint sets_df_in_use default 0,
[description] varchar(512),
date_in datetime not null constraint sets_df_date_in default getdate(),
last_selection datetime,
date_out datetime,
constraint sets_pk primary key clustered (id),
constraint sets_uk_key unique nonclustered ([key]) with (fillfactor = 90),
constraint sets_uk_data unique nonclustered (alphabet, base, power) with (fillfactor = 90),
constraint sets_ck_key check (
[key] not like '%[^a-zA-Z0-9_]%' and
len([key]) > 0 and
len([key]) <= 32
),
constraint sets_ck_alphabet check (
datalength(alphabet) >= 2 and
datalength(alphabet) <= 128
),
constraint sets_ck_base check (base >= 2 and base <= 128),
constraint sets_ck_power check (power > 0 and power < 8)
)
if object_id(N'dbo.Types', N'U') is null create table dbo.Types(
id int not null identity(1, 1),
[name] varchar(32) not null,
[description] varchar(512),
date_in datetime not null constraint types_df_date_in default getdate(),
date_out datetime,
constraint types_pk primary key clustered (id),
constraint types_uk_name unique nonclustered ([name]) with (fillfactor = 90),
constraint types_ck_name check (
[name] not like '%[^a-zA-Z0-9_]%' and
len([name]) > 0 and
len([name]) <= 32
)
)
if object_id(N'dbo.Messages', N'U') is null create table dbo.Messages(
id int not null identity(1, 1),
[bit] smallint not null,
[message] varchar(64) not null,
date_in datetime not null constraint messages_df_date_in default getdate(),
date_out datetime,
constraint messages_pk primary key clustered (id),
constraint messages_uk_data unique nonclustered ([bit], [message]) with (fillfactor = 90)
)
-- Level 1.
if object_id(N'dbo.Settings', N'U') is null create table dbo.Settings(
id int not null identity(1, 1),
[type] integer not null,
[key] varchar(32) not null,
[value] varchar(128),
[description] varchar(512),
date_in datetime not null constraint settings_df_date_in default getdate(),
date_out datetime,
constraint settings_pk primary key clustered (id),
constraint settings_fk_type foreign key ([type]) references dbo.Types(id)
on update no action
on delete no action,
constraint settings_uk_key unique nonclustered ([key]) with (fillfactor = 90),
constraint settings_ck_key check (
[key] not like '%[^a-zA-Z0-9_]%' and
len([key]) > 0 and
len([key]) <= 32
)
)
end
go
if object_id(N'dbo.tables_update', N'P') is not null drop procedure dbo.tables_update
go
create procedure dbo.tables_update as begin set nocount on
declare @database varchar(64) = db_name()
-- Level 0.
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Sets' and column_name = 'key') is null
alter table dbo.Sets add
[key] varchar(32) not null,
constraint sets_uk_key unique nonclustered ([key]) with (fillfactor = 90),
constraint sets_ck_key check (
[key] not like '%[^a-zA-Z0-9_]%' and
len([key]) > 0 and
len([key]) <= 32
)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Sets' and column_name = 'alphabet') is null
alter table dbo.Sets add
alphabet varchar(128) not null,
constraint sets_ck_alphabet check (
datalength(alphabet) >= 2 and
datalength(alphabet) <= 128
)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Sets' and column_name = 'base') is null
alter table dbo.Sets add
base smallint not null,
constraint sets_ck_base check (base >= 2 and base <= 128)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Sets' and column_name = 'power') is null
alter table dbo.Sets add
power tinyint not null,
constraint sets_ck_power check (power > 0 and power < 8)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Sets' and column_name = 'in_use') is null
alter table dbo.Sets add in_use bit not null constraint sets_df_in_use default 0
if (select top 1 0 from information_schema.constraints where table_catalog = @database and table_name = 'Sets' and constraint_name = 'sets_uk_data') is null
alter table dbo.Sets add constraint sets_uk_data unique nonclustered (alphabet, base, power) with (fillfactor = 90)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Types' and column_name = 'name') is null
alter table dbo.Types add
[name] varchar(32) not null,
constraint types_uk_name unique nonclustered ([name]) with (fillfactor = 90),
constraint types_ck_name check (
[name] not like '%[^a-zA-Z0-9_]%' and
len([name]) > 0 and
len([name]) <= 32
)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Types' and column_name = 'description') is null
alter table dbo.Types add [description] varchar(512)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Messages' and column_name = 'bit') is null
alter table dbo.Messages add [bit] smallint not null
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Messages' and column_name = 'message') is null
alter table dbo.Messages add [message] varchar(64) not null
if (select top 1 0 from information_schema.constraints where table_catalog = @database and table_name = 'Messages' and constraint_name = 'messages_uk_data') is null
alter table dbo.Messages add constraint messages_uk_data unique nonclustered ([bit], [message]) with (fillfactor = 90)
-- Level 1.
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Settings' and column_name = 'key') is null
alter table dbo.Settings add
[key] varchar(32) not null,
constraint settings_uk_key unique nonclustered ([key]) with (fillfactor = 90),
constraint settings_ck_key check (
[key] not like '%[^a-zA-Z0-9_]%' and
len([key]) > 0 and
len([key]) <= 32
)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Settings' and column_name = 'value') is null
alter table dbo.Settings add [value] varchar(128)
if (select top 1 0 from information_schema.columns where table_catalog = @database and table_name = 'Settings' and column_name = 'description') is null
alter table dbo.Settings add [description] varchar(512)
end
go
if object_id(N'dbo.tables_fill', N'P') is not null drop procedure dbo.tables_fill
go
create procedure dbo.tables_fill as begin set nocount on
if object_id(N'tempdb..#Settings', N'U') is not null drop table #Settings
create table #Settings(
[type] varchar(32) not null,
[key] varchar(32) not null,
[value] varchar(128)
)
if object_id(N'tempdb..#Messages', N'U') is not null drop table #Messages
create table #Messages(
[bit] smallint not null,
[message] varchar(64) not null
)
insert into #Settings([type], [key], [value]) values
('string', 'alphabet', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='),
('integer', 'base', '64')
insert into #Messages([bit], [message]) values
(0, 'invalid_alphabet'),
(1, 'invalid_base'),
(2, 'invalid_alphabet_type'),
(3, 'too_short_alphabet'),
(4, 'repeated_characters_in_alphabet'),
(5, 'too_long_alphabet'),
(6, 'base_lower_than_2'),
(7, 'base_greater_than_128'),
(8, 'base_greater_than_alphabet')
insert into dbo.Types([name]) select distinct [type] from #Settings where [type] not in (
select [name] from dbo.Types
)
insert into dbo.Settings([type], [key], [value]) select
types.id,
settings.[key],
settings.[value]
from #Settings as settings
inner join dbo.Types as types on types.name = settings.type
where settings.[key] not in (
select [key] from dbo.Settings
)
insert into dbo.Messages([bit], [message]) select
[bit],
[message]
from #Messages where ([bit], [message]) not in (
select [bit], [message] from dbo.Messages
)
if (select count(1) from dbo.Sets) = 0 begin
end
drop table #Settings
end
go
if object_id(N'dbo.settings_get', N'FN') is not null drop function dbo.settings_get
go
create function dbo.settings_get(
@key varchar(32),
@default varchar(128)
) returns varchar(128) as begin
return isnull((
select top 1 [value] from dbo.Settings where [key] = @key and date_out is null order by date_in desc
), @default)
end
go
if object_id(N'dbo.settings_get_int', N'FN') is not null drop function dbo.settings_get_int
go
create function dbo.settings_get_int(
@key varchar(32),
@default integer
) returns integer as begin
return convert(integer, dbo.settings_get(@key, @default))
end
go
if object_id(N'dbo.shift', N'FN') is not null drop function dbo.shift
go
create function dbo.shift(
@value integer,
@bits smallint
) returns integer as begin
return (case
when @bits is null or @value is null then 0
when @bits > 0 then @value * power(2, @bits)
when @bits < 0 then @value / power(2, -@bits)
else @value end)
end
go
if object_id(N'dbo.unique', N'FN') is not null drop function dbo.unique
go
create function dbo.unique(
@string varchar(max)
) returns varchar(128) as begin
declare @i integer = 1
declare @l integer = datalength(@string)
declare @unique varchar(128) = ''
while @i <= @l begin
declare @character char(1) = substring(@string, @i, 1)
if charindex(@character, @unique) = 0
set @unique += @character
set @i += 1
end
return @unique
end
go
if object_id(N'dbo.log2', N'FN') is not null drop function dbo.log2
go
create function dbo.log2(
@value float
) returns float as begin
return log(@value) / log(2)
end
go
if object_id(N'dbo.set_alphabet', N'P') is not null drop procedure dbo.set_alphabet
go
create procedure dbo.set_alphabet(
@alphabet varchar(max),
@base smallint,
@id integer output,
@error integer output
) begin set nocount on
declare @original_length integer
declare @power tinyint
set @error = 0
if @alphabet is null set @alphabet = dbo.settings_get('alphabet', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=')
if @base is null set @base = dbo.settings_get_int('base', 64)
set @original_length = datalength(@alphabet)
set @alphabet = dbo.unique(@alphabet)
if datalength(@alphabet) > 2 begin
set @error = @error | dbo.shift(1, 3)
set @alphabet = dbo.settings_get('alphabet', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=')
end
if datalength(@alphabet) != original_length
set @error = @error | dbo.shift(1, 4)
if datalength(@alphabet) > 128
set @error = @error | dbo.shift(1, 5)
set @error = @error | dbo.shift(1, case
when @base < 2 then 6
when @base > 128 then 7
when @base >= datalength(@alphabet) then 8
else null end)
if dbo.shift(error, -6) = 0 set @alphabet = substring(@alphabet, 1, @base)
set @power = cast(dbo.log2(datalength(substring(@alphabet, 1, 128))) as integer)
set @base = power(2, @power)
insert into dbo.Sets(alphabet, base, power) values
(substring(@alphabet, 1, @base), @base, @power)
set @id = scope_identity()
end
go
if object_id(N'dbo.change', N'P') is not null drop procedure dbo.change
go
create procedure dbo.change(
@key varchar(32)
) begin set nocount on
if (select top 1 0 from dbo.Sets where [key] = @key and in_use = 1) = 0 begin
update dbo.Sets set in_use = 0 where in_use = 1
update dbo.Sets set
in_use = 1,
last_selection = getdate()
where [key] = @key
end
end
if object_id(N'dbo.get_alphabet', N'FN') is not null drop function dbo.get_alphabet
go
create function dbo.get_alphabet() returns varchar(128) as begin
return (select top 1 alphabet from dbo.Sets where in_use = 1)
end
go
if object_id(N'dbo.to_string', N'FN') is not null drop function dbo.to_string
go
create function dbo.to_string(
@code integer
) returns varchar(512) as begin
declare @hexas varchar(512) = ''
declare @alphabet varchar(128)
declare @base smallint
select top 1 @alphabet = alphabet, @base = base from dbo.Sets where in_use = 1
while @code != 0 begin
declare @module integer = @code % @base
set @hexas = @hexas + substring(@alphabet, @module + 1, 1)
set @code = @code / @base
end
return @hexas
end
go
if object_id(N'dbo.to_integer', N'FN') is not null drop function dbo.to_integer
go
create function dbo.to_integer(
@code varchar(512)
) returns integer as begin
declare @integer integer = 0
declare @alphabet varchar(128)
declare @base smallint
declare @i integer = datalength(@code)
select top 1 @alphabet = alphabet, @base = base from dbo.Sets where in_use = 1
while @i > 0 begin
declare @value integer = charindex(substring(@code, @i, 1), @alphabet)
if @value != 0 set @integer = @integer * @base + @value - 1
set @i = @i - 1
end
return @integer
end
go
if object_id(N'dbo.to_binary', N'FN') is not null drop function dbo.to_binary
go
create function dbo.to_binary(
@integer integer
) returns varchar(32) as begin
declare @binary varchar(32) = ''
while @integer != 0 begin
set @binary = convert(char(1), @integer % 2) + @binary
set @integer = @integer / 2
end
return @binary
end
go
if object_id(N'dbo.to_string_binary', N'FN') is not null drop function dbo.to_string_binary
go
create function dbo.to_string_binary(
@string varchar(512),
@integer integer
) returns varchar(3584) as begin
declare @binary varchar(3584) = ''
declare @alphabet varchar(128)
declare @base smallint
declare @power tinyint
select top 1 @alphabet = alphabet, @base = base, @power = power from dbo.Sets where in_use = 1
if @string is not null begin
declare @i integer = datalength(@string)
while @i > 0 begin
declare @value integer = charindex(substring(@string, @i, 1), @alphabet)
if @value != 0 set @binary = right('0000000' + dbo.to_binary(@value - 1), @power) + @binary
set @i = @i - 1
end
end else if @integer is not null begin
set @binary = dbo.to_binary(@integer)
while len(@binary) % @power != 0
set @binary = '0' + @binary
end
return @binary
end
go
if object_id(N'dbo.get_bits', N'FN') is not null drop function dbo.get_bits
go
create function dbo.get_bits(
@string varchar(512),
@integer integer
) returns smallint as begin
if @string is not null begin
declare @alphabet varchar(128)
declare @base smallint
declare @power tinyint
select top 1 @alphabet = alphabet, @base = base, @power = power from dbo.Sets where in_use = 1
return (case
when datalength(@string) = 0 then 0
else (datalength(@string) - 1) * @power + ceiling(dbo.log2(charindex(substring(@string, datalength(@string), 1), @alphabet))) end)
end
if @integer is not null
return ceiling(dbo.log2(@integer))
return 0
end
go
if object_id(N'dbo.get_from_bits', N'P') is not null drop procedure dbo.get_from_bits
go
create procedure dbo.get_from_bits(
@string varchar(512),
@integer integer,
@from smallint output,
@bits smallint output
) begin set nocount on
if @from < 0 begin
set @from = dbo.get_bits(@string, @integer) + @from
if @from < 0 set @from = 0
end
if @bits < 0 begin
set @from = @from + @bits
set @bits = -@bits
if @from < 0 begin
set @bits = @bits + @from
set @from = 0
end
end
end
go
if object_id(N'dbo.clean', N'P') is not null drop procedure dbo.clean
go
create procedure dbo.clean(
@string varchar(512) output,
@integer integer output
) as begin set nocount on
if @string is not null begin
declare @character_0 char(1)
select top 1 @character_0 = substring(alphabet, 1, 1) from dbo.Sets where in_use = 1
while datalength(@string) != 0 and right(@string, 1) = @character_0
set @string = left(@string, datalength(@string) - 1)
if @string = '' set @string = @character_0
end
end
go
if object_id(N'dbo.get_range', N'P') is not null drop procedure dbo.get_range
go
create procedure dbo.get_range(
@string varchar(512) output,
@integer integer output,
@from smallint,
@bits smallint
) as begin set nocount on
execute dbo.get_from_bits @string, @integer, @from output, @bits output
if @string is not null begin
if @bits = 0 set @bits = dbo.get_bits(@string, @integer) - @from
if @bits > 0 begin
declare @alphabet varchar(128)
declare @base smallint
declare @power tinyint
declare @shift smallint
select top 1 @alphabet = alphabet, @base = base, @power = power from dbo.Sets where in_use = 1
if @from > 0 begin
declare @mask smallint = ~-@base
set @shift = @from % @power
set @string = substring(@string, @from / @power + 1, datalength(@string))
if @shift != 0 and datalength(@string) > 0 begin
declare @l integer = datalength(@string)
declare @i integer = 1
while @i < @l begin
set @string = (
left(@string, @i - 1) +
substring(@alphabet, ((
dbo.shift(charindex(substring(@string, @i, 1), @alphabet) - 1, @shift) |
dbo.shift(charindex(substring(@string, @i + 1, 1), @alphabet) - 1, @power - @shift)
) & @mask) + 1, 1) +
right(@string, @l - @i)
)
set @i = @i + 1
end
end
end
if @bits > 0 begin
set @shift = @bits % @power
set @string = left(@string, ceiling((@from + @bits) / cast(@power as float)))
if @shift != 0 and datalength(@string) > 0
set @string = (
substring(@string, 1, datalength(@string) - 1) +
substring(@alphabet, (
dbo.shift(charindex(right(@string, 1), @alphabet) - 1, -@shift) & ~-cast(power(2, @power - @shift) as integer)
) + 1, 1)
)
end
end
execute dbo.clean @string output, @integer output
end else if @integer is not null begin
if @from > 0 set @integer = dbo.shift(@integer, @from) & (dbo.shift(1, 31 - @from) - 1)
if @bits > 0 or @from < 31 begin
if @from + @bits > 31 set @bits = 31 - @from
set @integer = dbo.shift(@integer, -@from) & (dbo.shift(1, @bits) - 1)
end
end
execute dbo.clean @string output, @integer output
end
go
if object_id(N'dbo.bitwise', N'P') is not null drop procedure dbo.bitwise
go
create procedure dbo.bitwise(
@string varchar(512) output,
@integer integer output,
@bits smallint
) as begin set nocount on
if @string is not null begin
if len(@string) > 0 and @bits != 0 begin
declare @alphabet varchar(128)
declare @base smallint
declare @power tinyint
declare @shift smallint
declare @mask smallint
declare @l integer
declare @i integer
select top 1 @alphabet = alphabet, @base = base, @power = power from dbo.Sets where in_use = 1
set @shift = abs(@bits) % @power
set @mask = ~-@base
if @bits < 0 begin
set @string = right(@string, datalength(@string) - (-@bits / @power))
if @shift != 0 and datalength(@string) > 0 begin
set @l = datalength(@string) - 1
set @i = 1
while @i <= @l begin
set @string = left(@string, @i - 1) + substring(@alphabet, ((
dbo.shift(charindex(substring(@string, @i, 1), @alphabet) - 1, -@shift) |
dbo.shift(charindex(substring(@string, @i + 1, 1), @alphabet) - 1, @power - @shift)
) & @mask) + 1, 1) + right(@string, @l + 1 - @i)
set @i = @i + 1
end
set @string = left(@string, @l) + substring(@alphabet, dbo.shift(charindex(right(@string, 1), @alphabet) - 1, -@shift) + 1, 1)
end
end else begin
declare @length integer = ceiling(@bits / cast(@power as float)) + datalength(@string)
declare @character_0 char(1) = substring(@alphabet, 1, 1)
if @shift != 0 begin
declare @last_hexa smallint = dbo.shift(charindex(right(@string, 1), @alphabet) - 1, @shift)
set @l = datalength(@string)
set @i = @l
while @i > 1 begin
set @string = left(@string, @i - 1) + substring(@alphabet, ((
dbo.shift(charindex(substring(@string, @i, 1), @alphabet) - 1, @shift) |
dbo.shift(charindex(substring(@string, @i - 1, 1), @alphabet) - 1, @shift - @power)
) & @mask) + 1, 1) + right(@string, @l - @i)
set @i = @i - 1
end
set @string = (
substring(@alphabet, (dbo.shift(charindex(substring(@string, 1, 1), @alphabet) - 1, @shift) & @mask) + 1, 1) +
right(@string, @l - 1)
)
if @last_hexa >= @base
set @string = @string + substring(@alphabet, dbo.shift(@last_hexa, -@power) + 1, 1)
end
while len(@string) < @length
set @string = @character_0 + @string
end
end
end else if @integer is not null
set @integer = dbo.shift(@integer, @bits)
execute dbo.clean @string output, @integer output
end
go
if object_id(N'dbo.reset', N'P') is not null drop procedure dbo.reset
go
create procedure dbo.reset(
@string varchar(512) output,
@integer integer output,
@from smallint,
@bits smallint = 0,
@reversed bit = 0
) as begin set nocount on
execute dbo.get_from_bits @string, @integer, @from output, @bits output
if @string is not null begin
declare @alphabet varchar(128)
declare @base smallint
declare @power tinyint
declare @hexa_from integer
declare @hexa_to integer
declare @l integer
declare @i integer
declare @from_mask integer
declare @to_mask integer
declare @m integer = datalength(@string)
declare @character_0 char(1) = substring(@alphabet, 1, 1)
select top 1 @alphabet = alphabet, @base = base, @power = power from dbo.Sets where in_use = 1
set @hexa_from = @from / @power
set @hexa_to = (@from + @bits) / @power
if @reversed = 1 begin
set @l = @from % @power
set @from_mask = ~(dbo.shift(1, @l) - 1)
set @to_mask = dbo.shift(1, (@from + @bits) % @power) - 1
set @i = 1
while @i <= @m begin
if @i < @hexa_from or @i < @hexa_to
set @string = left(@string, @i - 1) + @character_0 + right(@string, @m - @i)
set @i = @i + 1
end
if @hexa_from = @hexa_to
set @string = (
left(@string, @hexa_from - 1) +
substring(@alphabet, (@from_mask & @to_mask) + 1, 1) +
right(@string, @m - @hexa_from)
)
else
set @string = (
left(@string, @hexa_from - 1) +
substring(@alphabet, @from_mask + 1, 1) +
right(@string, @m - @hexa_from)
)
if @hexa_to < @m
set @string = (
left(@string, @hexa_to - 1) +
substring(@alphabet, @to_mask + 1, 1) +
right(@string, @m - @hexa_to)
)
end else begin
set @l = (@from + @bits) % @power
set @from_mask = dbo.shift(1, @from % @power) - 1
set @to_mask = dbo.shift(dbo.shift(1, @power - @l) - 1, @l)
if @hexa_from = @hexa_to
set @string = (
(case when @hexa_from > 0 then left(@string, @hexa_from - 1) else '' end) +
substring(@alphabet, (@from_mask | @to_mask) + 1, 1) +
(case when @m - @hexa_to > 0 then right(@string, @m - @hexa_to) else '' end)
)
else
set @string = (
iif(@hexa_from - 1 < 0, '', left(@string, @hexa_from - 1)) +
substring(@alphabet, @from_mask + 1, 1) +
iif(@m - @hexa_to < 0, '', right(@string, @m - @hexa_to))
)
set @i = @hexa_from + 1
while @i < @hexa_to begin
if @i >= @m
break
set @string = left(@string, @hexa_from + @i - 1) + @character_0 + right(@string, @m - (@hexa_from + @i))
set @i = @i + 1
end
if @hexa_to < @m
set @string = left(@string, @hexa_to - 1) + substring(@alphabet, @to_mask + 1, 1) + right(@string, @m - @hexa_to)
end
end else if @integer is not null begin
if @from + @bits > 31 set @bits = 31 - @from
set @integer = @integer & (case
when @reversed = 1 then dbo.shift((dbo.shift(1, @bits) - 1), @shift)
else dbo.shift(dbo.shift(1, dbo.get_bits(@integer)) - 1, @from + @bits) | (dbo.shift(1, @from) -1) end)
end
execute dbo.clean @string output, @integer output
end
go