如何使用列的值多次调用我的存储过程?

How can I make numerous calls to my stored procedure using the values of column?

我在 SQL 中开发了一个存储过程来验证 13 位国民身份证号码是否有效。目前该程序运行良好,但我一次只能验证 1 个号码。程序 returns 有效则为 1,无效则为 0。这是我可以自动执行此操作的一种方法,这样我就可以检查很多 ID 号,而不是手动执行。

我写的存储过程如下图。

CREATE PROCEDURE [dbo].[verifyRSAIDs]
    @idNumber VARCHAR(13),      -- ID number to be checked 
    @isValid INT OUTPUT         -- Will return 0 if ID number is not valid and 1 otherwise
AS
BEGIN 
    SET NOCOUNT OFF

    DECLARE @digit1 int,                    --holds the 1st digit
            @digit2 int,                    --holds the 2nd digit 
            @digit3 int,                    --holds the 3rd digit
            @digit4 int,                    --holds the 4th digit
            @digit5 int,                    --holds the 5th digit
            @digit6 int,                    --holds the 6th digit
            @digit7 int,                    --holds the 7th digit
            @digit8 int,                    --holds the 8th digit
            @digit9 int,                    --holds the 9th digit
            @digit10 int,                   --holds the 10th digit
            @digit11 int,                   --holds the 11th digit
            @digit12 int,                   --holds the 12th digit
            @digit13 int                    --holds the 13th digit

    SET @digit1 = substring(@idNumber, 1 , 1) --Extract all the digits
    SET @digit2 = substring(@idNumber, 2 , 1)
    SET @digit3 = substring(@idNumber, 3 , 1)
    SET @digit4 = substring(@idNumber, 4 , 1)
    SET @digit5 = substring(@idNumber, 5 , 1)
    SET @digit6 = substring(@idNumber, 6 , 1)
    SET @digit7 = substring(@idNumber, 7 , 1)
    SET @digit8 = substring(@idNumber, 8 , 1)
    SET @digit9 = substring(@idNumber, 9 , 1)
    SET @digit10 = substring(@idNumber, 10 , 1)
    SET @digit11 = substring(@idNumber, 11 , 1)
    SET @digit12 = substring(@idNumber, 12 , 1)
    SET @digit13 = substring(@idNumber, 13 , 1)

    --Multiple every second digit from the right most by 2
    --If the result is greater than 10 the new digit is the sum of the two digits 

    --Digit 12
    SET @digit12 = @digit12 * 2

    IF @digit12 > 9 
        SET @digit12 = @digit12 - 9

    --Digit 10
    SET @digit10 = @digit10 * 2

    IF @digit10 > 9 
        SET @digit10 = @digit10 - 9

    --Digit 8
    SET @digit8 = @digit8 * 2

    IF @digit8 > 9
        SET @digit8 = @digit8 - 9

    --Digit 6
    SET @digit6 = @digit6 * 2

    IF @digit6 > 9 
        SET @digit6 = @digit6 - 9

    --Digit 4
    SET @digit4 = @digit4* 2

    IF @digit4 > 9 
        SET @digit4 = @digit4 - 9

    --Digit 2
    SET @digit2 = @digit2 * 2

    IF @digit2 > 9 
        SET @digit2 = @digit2 - 9

    DECLARE @sum as int                 --Will hold the sum of all the digits
    DECLARE @result as int              --Will hold the result of modulo 10   division

    --Add all the new digits
    -- If the modulo 10 of the sum is zero then the ID number is valid
    SET @sum = @digit1 + @digit2 + @digit3 +  @digit4 + 
               @digit5 + @digit6 + @digit7 + @digit8 + 
           @digit9 + 
           @digit10 +
           @digit11 + 
           @digit12 + 
           @digit13
SET @result = @sum % 10 

if @result = 0
SET @isValid = 1                    --Valid ID number
else
SET @isValid = 0                    --Invalid ID number
END

--I am calling the proceedure as follows with an example id number:
DECLARE @check as INT
EXEC verifyRSAIDs 
@idNumber = '0002131000008', 
@isValid = @check OUTPUT
SELECT @check AS 'ID Valid'

--I want to run the procedure on the following ID numbers:
('0002131000008'),('9910260000006'),('9907089000001'),('9903208000006'),('9811307000001'), 
('9808126000006'),('null'),
('9905292000002'),('9702081000004'),('9610210000003'),('9607039000008'),('9603158000002'), 
('9511267000005'),('9504205000005'),
('9412314000009'),('9409123000006'),('9405252000007'),('9310170000008'),('9306299000002'), 
('9303118000008'),('9211217000003'),
('9208036000008'),('9204155000002'),('9112274000003'),('9105212000002'),('9101311000001'), 
('9010130000003'),('9006259000006'),
('9003078000002'),('8911177000007'),('8907306000009'),('8904115000007'),('8809033000007'), 
('8805162000008'),('8801271000005'),
('8710090000007'),('8706219000001'),('8703038000007'),('8611137000002'),('8607266000003'), 
('8604075000001'),('8512184000004'),
('8508303000008'),('8505122000003'),('8501221000002'),('8413040000005'),('8406169000008'), 
('8402278000005'),('8311097000007'),
('8307226000009'),('8304035000007'),('8208263000003'),('8205082000008'),('8201181000007'), 
('8109300000008'),('8106129000003'),
('8102228000002'),('8011047000004'),('8007176000005'),('7912104000004'),('7908223000008'), 
('7905042000003'),('7901141000002'),
('7809260000002'),('7806089000007'),('7802188000006'),('7710317000005'),('7703255000004'), 
('7608173000004'),('7604292000009'),
('7601101000006'),('7509220000007'),('7506049000000'),('7502148000001'),('7407096000005'), 
('7312014000006'),('7304252000004'),
('7301051000003'),('7209170000004'),('7205309000006'),('7202108000006'),('7110237000005'), 
('7107056000009'),('7103175000004');

您可以使用游标遍历值,调用存储过程:

declare @ids table (id varchar(32) )

insert into @ids 
values 
('0002131000008'),('9910260000006'),('9907089000001'),('9903208000006'),('9811307000001'), 
('9808126000006'),('null'),
('9905292000002'),('9702081000004'),('9610210000003'),('9607039000008'),('9603158000002'), 
('9511267000005'),('9504205000005'),
('9412314000009'),('9409123000006'),('9405252000007'),('9310170000008'),('9306299000002'), 
('9303118000008'),('9211217000003'),
('9208036000008'),('9204155000002'),('9112274000003'),('9105212000002'),('9101311000001'), 
('9010130000003'),('9006259000006'),
('9003078000002'),('8911177000007'),('8907306000009'),('8904115000007'),('8809033000007'), 
('8805162000008'),('8801271000005'),
('8710090000007'),('8706219000001'),('8703038000007'),('8611137000002'),('8607266000003'), 
('8604075000001'),('8512184000004'),
('8508303000008'),('8505122000003'),('8501221000002'),('8413040000005'),('8406169000008'), 
('8402278000005'),('8311097000007'),
('8307226000009'),('8304035000007'),('8208263000003'),('8205082000008'),('8201181000007'), 
('8109300000008'),('8106129000003'),
('8102228000002'),('8011047000004'),('8007176000005'),('7912104000004'),('7908223000008'), 
('7905042000003'),('7901141000002'),
('7809260000002'),('7806089000007'),('7802188000006'),('7710317000005'),('7703255000004'), 
('7608173000004'),('7604292000009'),
('7601101000006'),('7509220000007'),('7506049000000'),('7502148000001'),('7407096000005'), 
('7312014000006'),('7304252000004'),
('7301051000003'),('7209170000004'),('7205309000006'),('7202108000006'),('7110237000005'), 
('7107056000009'),('7103175000004');

declare ids cursor for select id from @ids
open ids

declare @id varchar(32) 
declare @IsValid int

fetch next from ids into @id
while @@fetch_status = 0
  exec verifyRSAIDs @iNnumber = @id, @IsValid = @IsValid out

  if @IsValid <> 0 print 'The number ' + @id + ' is not valid'

  fetch next from ids into @id
end

close ids
deallocate ids

只需将其设为标量值函数,而不是存储过程。例如:\

CREATE or ALTER Function [dbo].[IsValueRSAIDs]( @idNumber VARCHAR (13) )               --ID number to be checked 
returns  INT  --Will return 0 if ID number is not valid and 1 otherwise
AS
BEGIN 

    DECLARE @isValid int = 0;

    if (ISNUMERIC(@idNumber) <> 1 or DATALENGTH(@idNumber) <> 13 )
      return 0;

    DECLARE @digit1 int,                    --holds the 1st digit
            @digit2 int,                    --holds the 2nd digit 
            @digit3 int,                    --holds the 3rd digit
            @digit4 int,                    --holds the 4th digit
            @digit5 int,                    --holds the 5th digit
            @digit6 int,                    --holds the 6th digit
            @digit7 int,                    --holds the 7th digit
            @digit8 int,                    --holds the 8th digit
            @digit9 int,                    --holds the 9th digit
            @digit10 int,                   --holds the 10th digit
            @digit11 int,                   --holds the 11th digit
            @digit12 int,                   --holds the 12th digit
            @digit13 int                    --holds the 13th digit

    SET @digit1 = substring(@idNumber, 1 , 1) --Extract all the digits
    SET @digit2 = substring(@idNumber, 2 , 1)
    SET @digit3 = substring(@idNumber, 3 , 1)
    SET @digit4 = substring(@idNumber, 4 , 1)
    SET @digit5 = substring(@idNumber, 5 , 1)
    SET @digit6 = substring(@idNumber, 6 , 1)
    SET @digit7 = substring(@idNumber, 7 , 1)
    SET @digit8 = substring(@idNumber, 8 , 1)
    SET @digit9 = substring(@idNumber, 9 , 1)
    SET @digit10 = substring(@idNumber, 10 , 1)
    SET @digit11 = substring(@idNumber, 11 , 1)
    SET @digit12 = substring(@idNumber, 12 , 1)
    SET @digit13 = substring(@idNumber, 13 , 1)

    --Multiple every second digit from the right most by 2
    --If the result is greater than 10 the new digit is the sum of the two digits 

    --Digit 12
    SET @digit12 = @digit12 * 2
    if @digit12 > 9 
        SET @digit12 = @digit12 - 9

    --Digit 10
    SET @digit10 = @digit10 * 2
    if @digit10 > 9 
        SET @digit10 = @digit10 - 9

    --Digit 8
    SET @digit8 = @digit8 * 2
    if @digit8 > 9
        SET @digit8 = @digit8 - 9

    --Digit 6
    SET @digit6 = @digit6 * 2
    if @digit6 > 9 
        SET @digit6 = @digit6 - 9

    --Digit 4
    SET @digit4 = @digit4* 2
    if @digit4 > 9 
        SET @digit4 = @digit4 - 9

    --Digit 2
    SET @digit2 = @digit2 * 2
    if @digit2 > 9 
        SET @digit2 = @digit2 - 9


    DECLARE @sum as int                 --Will hold the sum of all the digits
    DECLARE @result as int              --Will hold the result of modulo 10 division

    --Add all the new digits
    -- If the modulo 10 of the sum is zero then the ID number is valid
    SET @sum = @digit1 + 
               @digit2 +
               @digit3 + 
               @digit4 + 
               @digit5 + 
               @digit6 + 
               @digit7 + 
               @digit8 + 
               @digit9 + 
               @digit10 +
               @digit11 + 
               @digit12 + 
               @digit13
    SET @result = @sum % 10 

    if @result = 0
        SET @isValid = 1                    --Valid ID number
    else
        SET @isValid = 0                    --Invalid ID number

    return @isValid;

END


go

select val, dbo.IsValueRSAIDs(val)
from (values 
('0002131000008'),('9910260000006'),('9907089000001'),('9903208000006'),('9811307000001'), 
('9808126000006'),('null'),
('9905292000002'),('9702081000004'),('9610210000003'),('9607039000008'),('9603158000002'), 
('9511267000005'),('9504205000005'),
('9412314000009'),('9409123000006'),('9405252000007'),('9310170000008'),('9306299000002'), 
('9303118000008'),('9211217000003'),
('9208036000008'),('9204155000002'),('9112274000003'),('9105212000002'),('9101311000001'), 
('9010130000003'),('9006259000006'),
('9003078000002'),('8911177000007'),('8907306000009'),('8904115000007'),('8809033000007'), 
('8805162000008'),('8801271000005'),
('8710090000007'),('8706219000001'),('8703038000007'),('8611137000002'),('8607266000003'), 
('8604075000001'),('8512184000004'),
('8508303000008'),('8505122000003'),('8501221000002'),('8413040000005'),('8406169000008'), 
('8402278000005'),('8311097000007'),
('8307226000009'),('8304035000007'),('8208263000003'),('8205082000008'),('8201181000007'), 
('8109300000008'),('8106129000003'),
('8102228000002'),('8011047000004'),('8007176000005'),('7912104000004'),('7908223000008'), 
('7905042000003'),('7901141000002'),
('7809260000002'),('7806089000007'),('7802188000006'),('7710317000005'),('7703255000004'), 
('7608173000004'),('7604292000009'),
('7601101000006'),('7509220000007'),('7506049000000'),('7502148000001'),('7407096000005'), 
('7312014000006'),('7304252000004'),
('7301051000003'),('7209170000004'),('7205309000006'),('7202108000006'),('7110237000005'), 
('7107056000009'),('7103175000004') ) v(val);

使用下面的代码执行存储过程

declare @idcheck as table
(id varchar(15))

insert into @idcheck (id) values 

('0002131000008'),('9910260000006'),
('9907089000001'),('9903208000006'),('9811307000001'), 
('9808126000006'),('null'),
('9905292000002'),('9702081000004'),('9610210000003'),('9607039000008'),('9603158000002'), 
('9511267000005'),('9504205000005'),
('9412314000009'),('9409123000006'),('9405252000007'),('9310170000008'),('9306299000002'), 
('9303118000008'),('9211217000003'),
('9208036000008'),('9204155000002'),('9112274000003'),('9105212000002'),('9101311000001'), 
('9010130000003'),('9006259000006'),
('9003078000002'),('8911177000007'),('8907306000009'),('8904115000007'),('8809033000007'), 
('8805162000008'),('8801271000005'),
('8710090000007'),('8706219000001'),('8703038000007'),('8611137000002'),('8607266000003'), 
('8604075000001'),('8512184000004'),
('8508303000008'),('8505122000003'),('8501221000002'),('8413040000005'),('8406169000008'), 
('8402278000005'),('8311097000007'),
('8307226000009'),('8304035000007'),('8208263000003'),('8205082000008'),('8201181000007'), 
('8109300000008'),('8106129000003'),
('8102228000002'),('8011047000004'),('8007176000005'),('7912104000004'),('7908223000008'), 
('7905042000003'),('7901141000002'),
('7809260000002'),('7806089000007'),('7802188000006'),('7710317000005'),('7703255000004'), 
('7608173000004'),('7604292000009'),
('7601101000006'),('7509220000007'),('7506049000000'),('7502148000001'),('7407096000005'), 
('7312014000006'),('7304252000004'),
('7301051000003'),('7209170000004'),('7205309000006'),('7202108000006'),('7110237000005'), 
('7107056000009'),('7103175000004');

declare @result as table
(id varchar(15), check_result INT)

declare @id varchar(15)
DECLARE @check as INT

declare cur_check cursor for
select id from idcheck

open cur_check 
fetch cur_check into @id
while (@@FETCH_STATUS=0)
begin
Select @id

EXEC verifyRSAIDs 
@idNumber = @id, @isValid = @check OUTPUT

insert into @result 
SELECT @id as 'Identity Number',@check AS 'ID Valid'

fetch cur_check into @id
end

close cur_check
deallocate cur_check

select * from @result

不确定我是否正确理解了您的逻辑,但这里有一个选项,其中 OUTER APPLY 中的代码可以转换为 Table 值函数

例子dbFiddle

Declare @YourTable table (ID varchar(13))
Insert Into @YourTable values
('0002131000008'),('9910260000006'),('9907089000001'),('9903208000006'),('9811307000001'), ('9808126000006'),('null'),('9905292000002'),('9702081000004'),('9610210000003'),('9607039000008'),('9603158000002'), ('9511267000005'),('9504205000005'),('9412314000009'),('9409123000006'),('9405252000007'),('9310170000008'),('9306299000002'), ('9303118000008'),('9211217000003'),('9208036000008'),('9204155000002'),('9112274000003'),('9105212000002'),('9101311000001'), ('9010130000003'),('9006259000006'),('9003078000002'),('8911177000007'),('8907306000009'),('8904115000007'),('8809033000007'), ('8805162000008'),('8801271000005'),('8710090000007'),('8706219000001'),('8703038000007'),('8611137000002'),('8607266000003'), ('8604075000001'),('8512184000004'),('8508303000008'),('8505122000003'),('8501221000002'),('8413040000005'),('8406169000008'), ('8402278000005'),('8311097000007'),('8307226000009'),('8304035000007'),('8208263000003'),('8205082000008'),('8201181000007'), ('8109300000008'),('8106129000003'),('8102228000002'),('8011047000004'),('8007176000005'),('7912104000004'),('7908223000008'), ('7905042000003'),('7901141000002'),('7809260000002'),('7806089000007'),('7802188000006'),('7710317000005'),('7703255000004'), ('7608173000004'),('7604292000009'),('7601101000006'),('7509220000007'),('7506049000000'),('7502148000001'),('7407096000005'), ('7312014000006'),('7304252000004'),('7301051000003'),('7209170000004'),('7205309000006'),('7202108000006'),('7110237000005'), ('7107056000009'),('7103175000004')


Select A.ID
      ,B.*
 From  @YourTable A
 Outer Apply (
                Select IsValid = case when sum(v) % 10 = 1 then 'Valid' else 'Not Valid' end
                 from  (
                        Select p
                              ,v = v+iif(v*2>9 and p in (12,10,8,6,4,2) ,-9,0)
                         From  ( values (1 ,0+substring(ID, 1,1))
                                       ,(2 ,0+substring(ID, 2,1))
                                       ,(3 ,0+substring(ID, 3,1))
                                       ,(4 ,0+substring(ID, 4,1))
                                       ,(5 ,0+substring(ID, 5,1))
                                       ,(6 ,0+substring(ID, 6,1))
                                       ,(7 ,0+substring(ID, 7,1))
                                       ,(8 ,0+substring(ID, 8,1))
                                       ,(9 ,0+substring(ID, 9,1))
                                       ,(10,0+substring(ID,10,1))
                                       ,(11,0+substring(ID,11,1))
                                       ,(12,0+substring(ID,12,1))
                                       ,(13,0+substring(ID,13,1))
                               ) a(p,v)
                         Where try_convert(bigint,ID) is not null
                       ) a
             ) B

Returns

ID              IsValid
0002131000008   Not Valid
9910260000006   Not Valid
9907089000001   Not Valid
9903208000006   Not Valid
9811307000001   Valid
9808126000006   Not Valid
null            Not Valid
9905292000002   Valid
9702081000004   Not Valid
9610210000003   Not Valid
9607039000008   Not Valid
9603158000002   Not Valid
9511267000005   Not Valid
9504205000005   Valid
9412314000009   Not Valid
9409123000006   Not Valid
9405252000007   Not Valid
9310170000008   Not Valid
9306299000002   Not Valid
9303118000008   Not Valid
9211217000003   Not Valid
9208036000008   Not Valid
9204155000002   Not Valid
9112274000003   Not Valid
9105212000002   Not Valid
9101311000001   Not Valid
9010130000003   Not Valid
9006259000006   Not Valid
9003078000002   Not Valid
8911177000007   Not Valid
8907306000009   Not Valid
8904115000007   Not Valid
8809033000007   Not Valid
8805162000008   Valid
8801271000005   Not Valid
8710090000007   Not Valid
8706219000001   Not Valid
8703038000007   Not Valid
8611137000002   Not Valid
8607266000003   Valid
8604075000001   Not Valid
8512184000004   Not Valid
8508303000008   Not Valid
8505122000003   Not Valid
8501221000002   Not Valid
8413040000005   Not Valid
8406169000008   Not Valid
8402278000005   Not Valid
8311097000007   Not Valid
8307226000009   Not Valid
8304035000007   Not Valid
8208263000003   Not Valid
8205082000008   Not Valid
8201181000007   Not Valid
8109300000008   Not Valid
8106129000003   Valid
8102228000002   Not Valid
8011047000004   Not Valid
8007176000005   Not Valid
7912104000004   Not Valid
7908223000008   Valid
7905042000003   Not Valid
7901141000002   Not Valid
7809260000002   Not Valid
7806089000007   Not Valid
7802188000006   Not Valid
7710317000005   Not Valid
7703255000004   Not Valid
7608173000004   Not Valid
7604292000009   Valid
7601101000006   Not Valid
7509220000007   Not Valid
7506049000000   Not Valid
7502148000001   Not Valid
7407096000005   Not Valid
7312014000006   Not Valid
7304252000004   Not Valid
7301051000003   Valid
7209170000004   Not Valid
7205309000006   Not Valid
7202108000006   Not Valid
7110237000005   Not Valid
7107056000009   Not Valid
7103175000004   Not Valid