2

我有下表

create table MBR_IDS
(
    MBR_SLNO int identity(1,1),
    MBR_ID int
)
GO

ALTER TABLE MBR_IDS 
    ADD CONSTRAINT UNIQUE_MBR_ID 
    UNIQUE NONCLUSTERED (MBR_ID)

和下面的存储过程来创建一个随机数

CREATE PROCEDURE USP_RANDOM_6
AS 
BEGIN
    DECLARE @chars NCHAR(36)
    SET @chars = N'0123456789'

    DECLARE @result NCHAR(6)
    SET @result = SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
            + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
            + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
            + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
            + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
            + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)

    SELECT @result
END
GO

当我通过存储过程插入一个值时:

declare @row int
set @row =1

while (@row <= 1000)
begin
    insert into MBR_IDS 
    values(USP_RANDOM_6)

    set @row = @row + 1
end
GO

我收到此错误:

在此处输入图像描述

4

2 回答 2

4

一种选择是创建函数而不是存储过程。

您可以通过在表中捕获返回值来对存储过程执行您想要的操作:

create table #retval (val nchar(6));
declare @row int = 1;
while (@row <= 1000)
begin
    truncate table #retval;

    insert into #retval
        exec USP_RANDOM_6;

    insert into MBR_IDS
        select val
        from #retval; 
    set @row=@row + 1
end;

实际上,如果将其存储在表中,则可以将所有内容放入临时表中,然后只进行一次插入:

create table #retval (val nchar(6));
declare @row int = 1;
while (@row <= 1000)
begin
    insert into #retval
        exec USP_RANDOM_6;

    set @row = @row + 1;
end;

insert into MBR_IDS
    select val
    from #retval; 

编辑:

我不知道哪个更快,这个操作是存储过程还是函数。但是,我两者都不会使用。我会简单地做:

declare @row int = 1;
while (@row <= 1000)
begin
    insert into MBR_IDS
        select replace(str(checksum(newid())%1000000, 6, 0), ' ', '0')
    set @row=@row + 1
end;

这用于newid()计算新的长字符串。然后它需要checksum(),它应该是一个以一百万为模的随机 4 字节数。剩下的只是格式化它,所以它是一个以 '0' 开头的 6 位字符串。

另外,当我在上述构造中引入临时表时,我不知道我在想什么。更简单的方法很简单:

declare @row int = 1;
while (@row <= 1000)
begin
    insert into MBR_IDS
        exec USP_RANDOM_6;; 
    set @row=@row + 1
end;
于 2013-07-21T12:26:03.127 回答
2

如果你想使用过程,你可以定义输出参数

CREATE PROCEDURE USP_RANDOM_6
(
    @result NCHAR(6) = null output
)
AS
BEGIN
    DECLARE @chars NCHAR(36)
    SET @chars = N'0123456789'

    SET @result = SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
                + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
                + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
                + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
    + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
    + SUBSTRING(@chars, CAST((RAND() * LEN(@chars)) AS INT) + 1, 1)
END
GO

然后使用它

declare @row int, @rand nchar(6)
set @row =1
while (@row <= 1000)
begin
    exec USP_RANDOM_6 @result = @rand output

    insert into MBR_IDS 
    values(@rand)
set @row=@row + 1
end
于 2013-07-21T12:14:43.403 回答