回答

收藏

SQL:使用IN子句将字符串投射到IDS

技术问答 技术问答 136 人阅读 | 0 人回复 | 2023-09-13

DECLARE @STR_IDS VARCHAR(15)  |+ `! m4 q2 D) `; [8 m0 r
SET @STR_IDS='7,15,18'! p! _" ?1 C& [$ y
UPDATE TBL_USERS WHERE ID IN  @STR_IDS: M- [/ K8 E# ]
我知道更新语句将不起作用,因为ID是INT类型,并且我正在那里替换varachar值。我如何更改查询,以便它实际上像这样执行?
5 v7 Y8 S7 |2 V# i) [) p UPDATE TBL_USERS WHERE ID IN (7,15,18)
) ~5 F4 }) A! j3 A3 }谢谢你# i' y% j7 z  n. E0 D
                / ^* [9 U7 L) k
解决方案:+ F+ T8 K6 n! i9 U/ O) p
               
5 G4 H- x& m4 u4 I7 S, d. R0 S  Z6 B
1 B: s# L5 i# |
                Op没有提到数据库,因此我将仅使用SQL Server,因为问题中的示例SQL看起来像TSQL。在SQL  ?  `5 `* d. f3 y
Server中有很多分割字符串的方法。本文介绍了几乎每种方法的优点和缺点:
/ K6 z0 N: d9 W0 H1 L0 x7 nErland Sommarskog撰写的“当表值参数无法剪切时,SQL Server- Y/ l/ q1 L7 {5 X* W4 b
2005及更高版本中的数组和列表”
% a2 Q9 }' L( Y您需要创建一个拆分功能。这是分割函数的使用方式:7 x; ^) F0 T( e9 H" {3 z, [( }
SELECT) C+ S, m8 P5 p
    *
% |+ Q9 M8 V! _7 C+ V" @    FROM YourTable                               y
7 }1 O3 B1 G* P* M    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
! r# x, ^' ?$ Z! Z2 J4 L我更喜欢使用数字表方法在TSQL中拆分字符串,但是在SQL Server中拆分字符串的方法有很多,请参见前面的链接,其中解释了每种方法的优点和缺点。
. G5 [. b! |; j) _为了使Numbers Table方法起作用,您需要进行一次时间表设置,这将创建一个Numbers包含1至10,000行的表:: |. a9 P- ~9 v2 |; T( O+ X
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
( U( v( [9 f$ G! f    INTO Numbers
4 k! w. G) n2 `! A8 i    FROM sys.objects s11 i) |' K3 u+ k) Y. L
    CROSS JOIN sys.objects s2
  q$ e( A1 |; E8 s$ d1 LALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)7 c& K- @# b0 v" M
设置号码表后,请创建以下拆分功能:
, f' a) d* \+ @$ J8 wCREATE FUNCTION [dbo].[FN_ListToTable]
: l9 N' o. T3 [1 U; v(
1 C$ \; o. b5 O& k1 }( `* M/ c     @SplitOn  char(1)      --REQUIRED, the character to split the @List string on
, B/ ^4 m, G0 I$ Q4 b/ @    ,@List     varchar(8000)--REQUIRED, the list to split apart
: v& z! g, D+ c6 w$ L' D4 O)7 [# y5 [9 v0 B- K( }: Z& b
RETURNS TABLE- W, u2 L+ P/ j  s. f* T& W
AS; y3 T, K% }6 y! P2 b1 P5 T
RETURN
+ j( L/ z% G5 w6 R6 K) H9 G(, c" T$ @: ~" A. v
    ----------------
& z$ D# `! O7 ^! W- [& @    --SINGLE QUERY-- --this will not return empty rows) h$ i0 J$ g. k5 {! Y
    ----------------2 ^/ c4 |; a7 B- M  L- d
    SELECT; k' K4 b$ @7 O2 P- M' Z
        ListValue5 X. k1 N$ m8 a2 [0 W+ A
        FROM (SELECT# M3 b( [/ V7 v/ R# D0 y
                  LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
- l: L4 F; r& a) v) e6 k' M                  FROM (5 @8 h/ Z2 t: e/ |
                           SELECT @SplitOn + @List + @SplitOn AS List2! s+ G/ `8 b( p! }
                       ) AS dt
8 a" z1 X* X2 K: C  V                      INNER JOIN Numbers n ON n.Number 现在,您可以轻松地将CSV字符串拆分为一个表,然后在表上进行联接或根据需要使用它,甚至可以在动态sql中使用它。这是从您的问题中使用它的方法:
2 Z- `9 |. ]" i% f& W# a: C  {  BUPDATE t8 Y% j$ H: `$ ]1 s! d# I
    SET Col1=...3 i: E) j  B* d6 r; o7 e
    FROM dbo.FN_ListToTable(',','7,15,18') dt
3 @, M; A( ^) S2 L' q4 V8 i* p0 R/ C        INNER JOIN TBL_USERS                t ON  CAST(dt.value AS INT)=t.id
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则