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

Откуда:
Сообщений: 953
Короче в таблице есть поле.
МНе надо выбрать все значения у которых это поле представляет из себя 12 символов в интервале от [0-9]...


select * from TABLE1 where [b]IN[/b]N like ...
14 окт 08, 08:06    [6301447]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
Мордор Держимордов
Member

Откуда:
Сообщений: 953
Мордор Держимордов
Короче в таблице есть поле.
МНе надо выбрать все значения у которых это поле представляет из себя 12 символов в интервале от [0-9]...


select * from TABLE1 where [b]IN[/b]N like ...



select * from TABLE1 where INN like ...
[/quot]


... где INN должен быть 12 символов в интервале от [0-9].
14 окт 08, 08:07    [6301449]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
Добрый Э - Эх
Guest
Все идеи, нужные для решения поставленной задачи, ты можешь найти тут: Тынц
14 окт 08, 08:14    [6301462]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
select * from TABLE1 where INN like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
select * from TABLE1 where INN like REPLICATE('[0-9]',12);
Но ИНН бывает не только 12-ти значный. К тому же ИНН должен удоветворять определённым критериям. Была, например, тема Проверка ИНН.
Могу внести свои 5 коп. Когда-то сочинил функцию
CREATE FUNCTION [dbo].[CheckINN](@INN VARCHAR(12),@Legal BIT=NULL)
RETURNS BIT /*1 -> Ok! 0 -> Wrong...*/
BEGIN
 DECLARE @Result INT;
 SET @Result=0;
 IF (ISNULL(@Legal,0)=0 AND @INN LIKE REPLICATE('[0-9]',10)) OR (ISNULL(@Legal,1)=1 AND @INN LIKE REPLICATE('[0-9]',12))
 BEGIN
  DECLARE @WeightNumbers TABLE(ID INT NOT NULL,Weight INT NOT NULL);
  INSERT @WeightNumbers(ID,Weight)
            SELECT  1,  3
  UNION ALL SELECT  2,  5
  UNION ALL SELECT  3,  7
  UNION ALL SELECT  4, 13
  UNION ALL SELECT  5, 17
  UNION ALL SELECT  6, 19
  UNION ALL SELECT  7, 23
  UNION ALL SELECT  8, 29
  UNION ALL SELECT  9, 31
  UNION ALL SELECT 10, 37
  UNION ALL SELECT 11, 41;
  WITH CRC(V1,V2,V3,I) AS
  (
   SELECT 0,0,Weight*SUBSTRING(@INN,1,1),2 FROM @WeightNumbers WHERE ID=11
   UNION ALL
   SELECT
    CRC.V1+WN.Weight*SUBSTRING(@INN,CRC.I-2,1)/*Legal only*/
   ,CRC.V2+WN.Weight*SUBSTRING(@INN,CRC.I-1,1)
   ,CRC.V3+WN.Weight*NULLIF(SUBSTRING(@INN,CRC.I,1),'')
   ,CRC.I+1
   FROM @WeightNumbers WN JOIN CRC ON WN.ID=12-CRC.I
   WHERE WN.ID>0
  )
  SELECT TOP 1
    @Result=1-ABS(SIGN(11-NULLIF(ISNULL(NULLIF(NULLIF(ISNULL(V3%11,-1),0),1),11),-1)-SUBSTRING(@INN,12,1)))
   ,@Result=@Result*(1-ABS(SIGN(11-ISNULL(NULLIF(NULLIF(V2%11,0),1),11)-SUBSTRING(@INN,11,1))))
   ,@Result=ISNULL(@Result,1-ABS(SIGN(11-ISNULL(NULLIF(NULLIF(V1%11,0),1),11)-SUBSTRING(@INN,10,1))))
  FROM CRC
  ORDER BY I DESC;
 END;
 RETURN @Result;
END
GO
Здесь @Legal=0 означает "ИНН физического лица",
@Legal=1 - "ИНН юридического лица",
@Legal IS NULL - если передана строка длины 10, то для физического лица, а если 12, то юридического.
Как видите, используется рекурсивное CTE
14 окт 08, 08:37    [6301502]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Сейчас бы я, наверно, вместо табличной переменной использовал ещё одно CTE:
CREATE FUNCTION [dbo].[CheckINN](@INN VARCHAR(12),@Legal BIT=NULL)
RETURNS BIT /*1 -> Ok! 0 -> Wrong...*/
BEGIN
 DECLARE @Result INT;
 SET @Result=0;
 IF (ISNULL(@Legal,0)=0 AND @INN LIKE REPLICATE('[0-9]',10)) OR (ISNULL(@Legal,1)=1 AND @INN LIKE REPLICATE('[0-9]',12))
 BEGIN
  WITH WeightNumbers(ID,Weight) AS
  (
             SELECT  1,  3
   UNION ALL SELECT  2,  5
   UNION ALL SELECT  3,  7
   UNION ALL SELECT  4, 13
   UNION ALL SELECT  5, 17
   UNION ALL SELECT  6, 19
   UNION ALL SELECT  7, 23
   UNION ALL SELECT  8, 29
   UNION ALL SELECT  9, 31
   UNION ALL SELECT 10, 37
   UNION ALL SELECT 11, 41
  )
  ,CRC(V1,V2,V3,I) AS
  (
   SELECT 0,0,Weight*SUBSTRING(@INN,1,1),2 FROM WeightNumbers WHERE ID=11
   UNION ALL
   SELECT
    CRC.V1+WN.Weight*SUBSTRING(@INN,CRC.I-2,1)/*Legal only*/
   ,CRC.V2+WN.Weight*SUBSTRING(@INN,CRC.I-1,1)
   ,CRC.V3+WN.Weight*NULLIF(SUBSTRING(@INN,CRC.I,1),'')
   ,CRC.I+1
   FROM WeightNumbers WN JOIN CRC ON WN.ID=12-CRC.I
   WHERE WN.ID>0
  )
  SELECT TOP 1
    @Result=1-ABS(SIGN(11-NULLIF(ISNULL(NULLIF(NULLIF(ISNULL(V3%11,-1),0),1),11),-1)-SUBSTRING(@INN,12,1)))
   ,@Result=@Result*(1-ABS(SIGN(11-ISNULL(NULLIF(NULLIF(V2%11,0),1),11)-SUBSTRING(@INN,11,1))))
   ,@Result=ISNULL(@Result,1-ABS(SIGN(11-ISNULL(NULLIF(NULLIF(V1%11,0),1),11)-SUBSTRING(@INN,10,1))))
  FROM CRC
  ORDER BY I DESC;
 END;
 RETURN @Result;
END
GO
14 окт 08, 08:57    [6301537]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
Мордор Держимордов
Member

Откуда:
Сообщений: 953
iap
Сейчас бы я, наверно, вместо табличной переменной использовал ещё одно CTE:
CREATE FUNCTION [dbo].[CheckINN](@INN VARCHAR(12),@Legal BIT=NULL)
RETURNS BIT /*1 -> Ok! 0 -> Wrong...*/
BEGIN
 DECLARE @Result INT;
 SET @Result=0;
 IF (ISNULL(@Legal,0)=0 AND @INN LIKE REPLICATE('[0-9]',10)) OR (ISNULL(@Legal,1)=1 AND @INN LIKE REPLICATE('[0-9]',12))
 BEGIN
  WITH WeightNumbers(ID,Weight) AS
  (
             SELECT  1,  3
   UNION ALL SELECT  2,  5
   UNION ALL SELECT  3,  7
   UNION ALL SELECT  4, 13
   UNION ALL SELECT  5, 17
   UNION ALL SELECT  6, 19
   UNION ALL SELECT  7, 23
   UNION ALL SELECT  8, 29
   UNION ALL SELECT  9, 31
   UNION ALL SELECT 10, 37
   UNION ALL SELECT 11, 41
  )
  ,CRC(V1,V2,V3,I) AS
  (
   SELECT 0,0,Weight*SUBSTRING(@INN,1,1),2 FROM WeightNumbers WHERE ID=11
   UNION ALL
   SELECT
    CRC.V1+WN.Weight*SUBSTRING(@INN,CRC.I-2,1)/*Legal only*/
   ,CRC.V2+WN.Weight*SUBSTRING(@INN,CRC.I-1,1)
   ,CRC.V3+WN.Weight*NULLIF(SUBSTRING(@INN,CRC.I,1),'')
   ,CRC.I+1
   FROM WeightNumbers WN JOIN CRC ON WN.ID=12-CRC.I
   WHERE WN.ID>0
  )
  SELECT TOP 1
    @Result=1-ABS(SIGN(11-NULLIF(ISNULL(NULLIF(NULLIF(ISNULL(V3%11,-1),0),1),11),-1)-SUBSTRING(@INN,12,1)))
   ,@Result=@Result*(1-ABS(SIGN(11-ISNULL(NULLIF(NULLIF(V2%11,0),1),11)-SUBSTRING(@INN,11,1))))
   ,@Result=ISNULL(@Result,1-ABS(SIGN(11-ISNULL(NULLIF(NULLIF(V1%11,0),1),11)-SUBSTRING(@INN,10,1))))
  FROM CRC
  ORDER BY I DESC;
 END;
 RETURN @Result;
END
GO



Мать всех японцев!
А ведь зашёл просто глюпий вопрос задать.

ШПАСИБО ТОВАРЕСЧ!
14 окт 08, 09:11    [6301580]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74930
Как вариант:

CREATE FUNCTION dbo.CheckINN
	(
	 @OriginINN	string
	)
RETURNS int --0-ИНН корректен, -1 не корректен
BEGIN
  --проверяем длину
  IF LEN(@OriginINN) NOT IN (10, 12) RETURN -1

  DECLARE @INN bigint
  SET @INN = CONVERT(bigint, @OriginINN)
  declare @chk varchar(20), @chk1 tinyint, @chk2 tinyint

  declare @c table([n]		tinyint,
                   [k1]		as power(convert(bigint,10), [n]),	-- вспомогательный столбец для выделения цифр из ИНН
                   [k2]		as power(convert(bigint,10), [n]-1),-- вспомогательный столбец для выделения цифр из ИНН
                   [c10]	tinyint,							-- весовые коэффициенты для 10-значного ИНН
                   [c12_1]	tinyint,							-- весовые коэффициенты[1] для 12-значного ИНН
                   [c12_2]	tinyint)							-- весовые коэффициенты[2] для 12-значного ИНН

  -- заполняем таблицу коэффициентов
  insert @c([n],	[c10],	[c12_1],	[c12_2])
    select	1,		0,		0,			0	union all
    select	2,		8,		0,			8	union all
    select	3,		6,		8,			6	union all
    select	4,		4,		6,			4	union all
    select	5,		9,		4,			9	union all
    select	6,		5,		9,			5	union all
    select	7,		3,		5,			3	union all
    select	8,		10,		3,			10	union all
    select	9,		4,		10,			4	union all
    select	10,		2,		4,			2	union all
    select	11,		0,		2,			7	union all
    select	12,		0,		7,			3

  -- расчет контрольных чисел
  select @chk1 = sum([c10]*((@INN%[k1]-@INN%[k2])/[k2]))%11%10,
         @chk2 =(sum([c12_1]*((@INN%[k1]-@INN%[k2])/[k2]))%11%10)*10+
                 sum([c12_2]*((@INN%[k1]-@INN%[k2])/[k2]))%11%10
    from @c

  -- сравниваем расчитанные контрольные числа с имеющимис
  return case
           when len(@inn) = 10 and @chk1 = @INN%10  then 0
           when len(@inn) = 12 and @chk2 = @INN%100 then 0
           else -1
         end
END
14 окт 08, 09:18    [6301615]     Ответить | Цитировать Сообщить модератору
 !!!  [new]
Мордор Держимордов
Member

Откуда:
Сообщений: 953
Я ЛЮБЛЮ MS SQL!
ПОТОМУ ЧТО У МЕНЯ СТАЛО ЧТО-ТО БОЛЬНЕЕ - МЕНЕЕ ПОЛУЧАТЬСЯ!

ЭТО НЕ ШИЗА, ПРОСТО МЕНЯ ПРЁТ!

ЗАДАНИЕ КОТОРОЕ КАЗАЛОСЬ МНЕ ГОРОЙ ОБРЕЛО РЕШЕНИЕ!
17 окт 08, 09:01    [6318787]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Строка в несколько знаков определенной длины.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
iap, pkarklin это конечно всё занимательно на первом этапе. Но:
1. Функция специализированная, зачем этот универсализм в виде циклов и универсального запроса
2. Это уже конечно не так важно, но скалярка не есть гуд.

Напишите одно единственное цельное выражение.

PS: Если не забуду, в понедельник приведу для своей страны, укороченное.
27 ноя 11, 03:45    [11665876]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Mnior
2. Это уже конечно не так важно, но скалярка не есть гуд.
В СНЕCK констрейнте другая невозможна
27 ноя 11, 11:50    [11666172]     Ответить | Цитировать Сообщить модератору
 Re: Строка в несколько знаков определенной длины.  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
iap
В СНЕCK констрейнте другая невозможна
Арнумент. Поэтому дублирую.

CREATE FUNCTION [dbo].[fnIDNCheck] (
	@IDN	VarChar(14)
) RETURNS Bit WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT AS BEGIN RETURN (
SELECT	CASE	WHEN Len(@IDN) = 13 AND @IDN NOT LIKE '%[^0-9]%'
		 AND	( Convert(TinyInt,SubString(@IDN,12,1))
			+ Convert(TinyInt,SubString(@IDN, 9,1))
			+ Convert(TinyInt,SubString(@IDN, 6,1))
			+ Convert(TinyInt,SubString(@IDN, 3,1))
			+ 3 * (40			   
			+ Convert(TinyInt,SubString(@IDN,11,1))
			+ Convert(TinyInt,SubString(@IDN, 8,1))
			+ Convert(TinyInt,SubString(@IDN, 5,1))
			+ Convert(TinyInt,SubString(@IDN, 2,1))
			- Convert(TinyInt,SubString(@IDN,10,1))
			- Convert(TinyInt,SubString(@IDN, 7,1))
			- Convert(TinyInt,SubString(@IDN, 4,1))
			- Convert(TinyInt,SubString(@IDN, 1,1))
		)) % 10 = Convert(TinyInt,SubString(@IDN,13,1))
		THEN Convert(Bit,1)
		ELSE Convert(Bit,0)
		END
) END
GO
29 ноя 11, 14:43    [11678122]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить