在SQL查询中使用为每个返回记录更改的变量

时间:2015-08-12 20:30:06

标签: sql-server

开始 - 我是SQL新手;要温柔。

我在学区工作,最近获得了访问数据库的“钥匙”。我有兴趣获取学生列表,然后为他们生成密码列表。我找到了一些代码,它允许我生成随机密码,我想将其合并到一个从我们的学生数据库收集信息的SQL查询中。 (谢谢你这个代码是你的!)

我的问题是我无法使用这些变量为每条记录创建不同的密码。我为每个学生提供了相同的随机生成的密码。 (好的一点是,每次执行查询时密码都会更改。)

我应该提一下,我为数据库访问设置了两个帐户;一个是简单地读取信息,另一个是完全编辑权限。 (当我按下大红色按钮来更新一些琐碎的信息时,我只使用过一次并闭上眼睛。)

首次运行的结果:

Name    Password
JACEK   mtwsz2ybu      
CARL    mtwsz2ybu      
LARS    mtwsz2ybu      

第二轮的结果:

Name    Password
JACEK   je4tm5ptw      
CARL    je4tm5ptw      
LARS    je4tm5ptw 

这是我正在运行的查询:

USE XXTableXX
DECLARE @position int, @string char(100), @length int, 
@rand int, @newstring char(15), @newchar char(15);
SET @position = 1;
SET @string = 'abcdefghijkmnopqrstuvwxyz23456789';
SET @length = 9;
SET @newstring = ''
SET @newchar = ''
WHILE @position <= @length
BEGIN
SET @rand = FLOOR(RAND()*(33-1)+1);
SET @newchar = SUBSTRING(@string,@rand,1);
SET @newstring = STUFF(@newstring,len(@newstring)+1,1,@newchar)
SET @position = @position +1;
END;

SELECT DISTINCT s.firstname, @newstring AS [Password]
FROM XXStudentTableXX s

4 个答案:

答案 0 :(得分:1)

将查询上方的所有内容放在函数中,然后在查询中调用该函数。旁注,它将针对每一行执行,这意味着对于大型集合会有一点性能损失。

这是一种方法。

首先,您需要将RAND()放入其自己的视图中,因为您无法从函数中调用它

CREATE VIEW [dbo].[NewRandom]
AS
SELECT RAND() AS [RandSeed]
GO

现在您必须创建使用该视图的函数。此函数接受一个整数,因此您可以执行可变密码长度。您可以在查询中对其进行硬编码,也可以取出参数并在函数中对其进行硬编码。

    CREATE FUNCTION [dbo].[ufn_GeneratePassword] ( @PasswordLength INT )
RETURNS VARCHAR(20)
AS
BEGIN


 DECLARE @position int, @string char(100), @length int, 
    @rand int, @newstring char(15), @newchar char(15);
    SET @position = 1;
    SET @string = 'abcdefghijkmnopqrstuvwxyz23456789';
    SET @length = @PasswordLength;
    SET @newstring = ''
    SET @newchar = ''
    WHILE @position <= @length
    BEGIN
    SET @rand = FLOOR((SELECT RandSeed FROM dbo.[NewRandom])*(33-1)+1);
    SET @newchar = SUBSTRING(@string,@rand,1);
    SET @newstring = STUFF(@newstring,len(@newstring)+1,1,@newchar)
    SET @position = @position +1;
    END

    RETURN @newstring

END

现在您可以在表格的每一行调用该函数

SELECT DISTINCT s.firstname, [dbo].[ufn_GeneratePassword](9)  AS [Password]
FROM XXStudentTableXX s

答案 1 :(得分:0)

我认为你需要做的是创建一个表或表变量,然后选择make it insert into the table。另外,为每个学生ID添加一个循环1x的循环。然后,这将为每个学生插入1行并运行随机发生器1次。

答案 2 :(得分:0)

首先将您的过程转换为标量SQL函数。

CREATE VIEW dbo.RandomNumberView 
AS
SELECT RandomNumber = RAND(); 
GO  


CREATE FUNCTION dbo.GeneratePassword()
RETURNS char(15)
AS 
-- Generates and Returns a random password
BEGIN
    DECLARE @position int, @string char(100), @length int, 
    @rand int, @newstring char(15), @newchar char(15);
    SET @position = 1;
    SET @string = 'abcdefghijkmnopqrstuvwxyz23456789';
    SET @length = 9;
    SET @newstring = ''
    SET @newchar = ''
    WHILE @position <= @length
    BEGIN
        SELECT @rand = FLOOR(RandomNumber *(33-1)+1) FROM RandomNumberView;
        SET @newchar = SUBSTRING(@string,@rand,1);
        SET @newstring = STUFF(@newstring,len(@newstring)+1,1,@newchar)
        SET @position = @position +1;
    END;
    RETURN @newstring;
END;
GO

然后你可以随心所欲地使用它。

SELECT DISTINCT s.firstname,     dbo.GeneratePassword() AS [Password]
FROM XXStudentTableXX s

请注意,每次运行此查询时,您都会针对同一记录获得不同的密码。我更喜欢使用此函数仅在表中生成和插入密码,而不是直接选择语句。

答案 3 :(得分:0)

要从随机表中获取数据,SQL Server提供了NEWID()函数。正如其名称所示,每次执行都会生成一个新的GUID(全局唯一标识符),这些GUID是唯一的,因此订单的值永远不会相同。

因此,您无需为自己创建随机函数。因此,您可以使用简单的SQL获得答案。

CREATE TABLE STUDENT (
    [ID]     INT            IDENTITY (1, 1) NOT NULL,
    [NAME]   NVARCHAR (100) NULL
);

INSERT INTO STUDENT (NAME) VALUES ('John');
INSERT INTO STUDENT (NAME) VALUES ('Carl');
INSERT INTO STUDENT (NAME) VALUES ('Mary');
INSERT INTO STUDENT (NAME) VALUES ('Joan');

select
    ID
    ,NAME
    ,CONCAT(
      CAST((ABS(CHECKSUM(NEWID()))%10) as varchar(1))
      , CHAR(ASCII('a') + (ABS(CHECKSUM(NEWID())) % 25))
      , CHAR(ASCII('A') + (ABS(CHECKSUM(NEWID())) % 25))
      , LEFT(LOWER(NEWID()),2)
      , LEFT(NEWID(),2)
      , LEFT(LOWER(NEWID()),2)
    ) AS PASSWORD
from STUDENT

SQL Fiddle

但是,您可能希望自己的生成器考虑到高度复杂的生成密码。

https://www.simple-talk.com/blogs/2009/09/30/strong-password-generator/