|
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 |
|