在CTE sql的select语句中更新局部变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在CTE sql的select语句中更新局部变量相关的知识,希望对你有一定的参考价值。

目前,我正在使用CTE语句,该语句为某些预定义的字母数字字符中的每个字符生成一个随机数。

我使用的是用户定义的随机函数。但是随机函数给了我重复的结果行。我不希望任何字符重复,所以我试图删除已经在CTE的select语句中使用的字符,因此相同的字符不能用作进一步即将到来的字符的替换。但我无法在CTE Select语句中更新字符集

DECLARE @characters VARCHAR(100) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
DECLARE @upperAlphabet VARCHAR(30) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';


DECLARE @lowerAlphabet VARCHAR(30) = 'abcdefghijklmnopqrstuvwxyz';


DECLARE @numbers VARCHAR(10) = '9876543210';
DECLARE @numbersCount int;

Declare @ReplacedCharacter varchar(2);
DECLARE @selectedUpperChar VARCHAR(1) ;

WITH CTE AS (
 SELECT
  1 as CharacterPosition,
  SUBSTRING(@alphas,1,1) as [Character]
  , (SELECT   RIGHT( LEFT(@upperAlphabet,dbo.RandomNumber(1,26) ),1)) AS replaceCharacter

  UNION ALL
   SELECT
  CharacterPosition + 1,
  SUBSTRING(@alphas,CharacterPosition + 1,1)
  , CASE 
   WHEN CharacterPosition < 26 
   THEN (SELECT RIGHT( LEFT(@upperAlphabet,dbo.RandomNumber(1,26)),1))
   WHEN CharacterPosition >= 26 AND CharacterPosition < 52
   THEN (SELECT RIGHT( LEFT(@lowerAlphabet,dbo.RandomNumber(1,26) ),1))
   ELSE (SELECT RIGHT( LEFT(@numbers,dbo.RandomNumber(1,10) ),1))

  END

 FROM
  CTE
 WHERE CharacterPosition < LEN(@alphas)
)

SELECT CharacterPosition, [Character], replaceCharacter
FROM CTE
答案

您可以通过简单地使用while并从剩余/可用的列表中删除replacedCharacter来获得预期结果。

请尝试以下代码:

DECLARE @alphas VARCHAR(100) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
DECLARE @upperAlphabet VARCHAR(30) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE @lowerAlphabet VARCHAR(30) = 'abcdefghijklmnopqrstuvwxyz';
DECLARE @numbers VARCHAR(10) = '9876543210';

Declare @ReplacedCharacter varchar(2);

declare @result table (CharacterPosition int, [Character] varchar(1), replaceCharacter varchar(1));
declare @position int = 1;
declare @characher varchar(1);
declare @remaining varchar(100);

while len(@alphas) > 0
 begin
    set @characher = SUBSTRING(@alphas,1,1)

    if @position <= 26
        begin
            set @replacedCharacter = RIGHT(LEFT(@upperAlphabet, CEILING(dbo.RandomNumber(1, len(@upperAlphabet) + 1))),1);
            set @upperAlphabet = replace(@upperAlphabet, @replacedCharacter, '');
        end
    else
        begin 
            if @position > 26 AND @position <= 52
                begin
                    set @replacedCharacter = RIGHT(LEFT(@lowerAlphabet, CEILING(dbo.RandomNumber(1,len(@lowerAlphabet) + 1)) ),1);
                    set @lowerAlphabet = replace(@lowerAlphabet, @replacedCharacter, '');
                end
            else
                begin
                    set @replacedCharacter = RIGHT(LEFT(@numbers, CEILING(dbo.RandomNumber(1,len(@numbers) + 1))),1);
                    set @numbers = replace(@numbers, @replacedCharacter, '');
                end
        end

    insert into @result (CharacterPosition, [Character], replaceCharacter)
    values (@position, @characher, @ReplacedCharacter)

    set @alphas = right(@alphas, len(@alphas) - 1)
    set @position = @position + 1
 end

 select * from @result;

结果:

CharacterPosition   Character   replaceCharacter
1   A   J
2   B   X
3   C   O
4   D   S
5   E   C
6   F   Z
7   G   V
8   H   N
9   I   P
10  J   K
11  K   G
12  L   T
13  M   W
14  N   F
15  O   I
16  P   Q
17  Q   U
18  R   B
19  S   H
20  T   E
21  U   L
22  V   M
23  W   D
24  X   A
25  Y   Y
26  Z   R
27  a   s
28  b   n
29  c   y
30  d   m
31  e   b
32  f   w
33  g   u
34  h   l
35  i   c
36  j   o
37  k   h
38  l   z
39  m   t
40  n   i
41  o   k
42  p   p
43  q   j
44  r   r
45  s   e
46  t   d
47  u   g
48  v   q
49  w   f
50  x   x
51  y   v
52  z   a
53  0   4
54  1   8
55  2   9
56  3   0
57  4   6
58  5   2
59  6   3
60  7   5
61  8   1
62  9   7

以上是关于在CTE sql的select语句中更新局部变量的主要内容,如果未能解决你的问题,请参考以下文章

SQL With (递归CTE查询)

SQL 中with的用法

在 case 语句中更新值并设置局部变量

sql server中的cte

T-SQL 之 公用表表达式(CTE)

Hive 公用表表达式 CTE 使用指南