2010-05-05 52 views
2
DECLARE @STR_IDS VARCHAR(15) 
SET @STR_IDS='7,15,18' 
UPDATE TBL_USERS WHERE ID IN @STR_IDS 

我知道update語句是行不通的ID是int類型的,我更換varachar值有我。如何能更改查詢,以便它會像這樣被執行?SQL:鑄造一個字符串IDS與IN子句

UPDATE TBL_USERS WHERE ID IN (7,15,18) 

感謝advace

+0

+1這對我也是有用的。感謝問! =) – 2010-05-05 13:25:22

回答

1

作品中沒有提到的數據庫,所以我就使用SQL Server,因爲問題的例子SQL看起來像TSQL。有很多方法可以在SQL Server中拆分字符串。本文介紹了幾乎每一個方法的優點和缺點:

"Arrays and Lists in SQL Server 2005 and Beyond, When Table Value Parameters Do Not Cut it" by Erland Sommarskog

你需要創建一個分裂的功能。這是一個分裂的功能如何使用:

SELECT 
    * 
    FROM YourTable        y 
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach to split a string in TSQL但也有許多方法來拆分在SQL Server中的字符串,見前面的鏈接,這說明各的優點和缺點。

對於數字表的方法來工作,你需要做的這一次表的設置,這將創建一個包含從1到10000行的表Numbers

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.objects s1 
    CROSS JOIN sys.objects s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

一旦Numbers表格設置,創建此分割功能:

CREATE FUNCTION [dbo].[FN_ListToTable] 
(
    @SplitOn char(1)  --REQUIRED, the character to split the @List string on 
    ,@List  varchar(8000)--REQUIRED, the list to split apart 
) 
RETURNS TABLE 
AS 
RETURN 
(

    ---------------- 
    --SINGLE QUERY-- --this will not return empty rows 
    ---------------- 
    SELECT 
     ListValue 
     FROM (SELECT 
        LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue 
        FROM (
          SELECT @SplitOn + @List + @SplitOn AS List2 
         ) AS dt 
         INNER JOIN Numbers n ON n.Number < LEN(dt.List2) 
        WHERE SUBSTRING(List2, number, 1) = @SplitOn 
      ) dt2 
     WHERE ListValue IS NOT NULL AND ListValue!='' 

); 
GO 

您現在可以輕鬆地拆分CSV字符串轉換成表格和加入或使用它,但是你所需要的,甚至從動態SQL內。這裏是如何使用它從你的問題:

UPDATE t 
    SET Col1=... 
    FROM dbo.FN_ListToTable(',','7,15,18') dt 
     INNER JOIN TBL_USERS    t ON CAST(dt.value AS INT)=t.id 
0

最近我更喜歡使用用戶定義的表類型來傳遞參數列表,但我用這個效用函數:

CREATE FUNCTION [dbo].[fn_CommasToIntTable] 
(
    @CommaList varchar(8000) 
) 
RETURNS @ParsedList TABLE 
(
    TokenID int 
) 
AS 
BEGIN 
    DECLARE @CurrentToken varchar(10) 
    DECLARE @Pos int 
    SET @CommaList = LTRIM(RTRIM(@CommaList))+ ',' 
    SET @Pos = CHARINDEX(',', @CommaList, 1) 
    IF REPLACE(@CommaList, ',', '') <> '' 
    BEGIN 
     WHILE @Pos > 0 
     BEGIN 
      SET @CurrentToken = LTRIM(RTRIM(LEFT(@CommaList, @Pos - 1))) 
      IF @CurrentToken <> '' 
      BEGIN 
       INSERT @ParsedList (TokenID) 
       VALUES (CAST(@CurrentToken AS int)) 
      END 
      SET @CommaList = RIGHT(@CommaList, LEN(@CommaList) - @Pos) 
      SET @Pos = CHARINDEX(',', @CommaList, 1) 
     END 
    END 

    RETURN 
END 

你會使用從here

SELECT (Columns) 
FROM (Table) 
WHERE ID IN (SELECT TokenID FROM dbo.fn_CommasToIntTable(@idList)) 
1

被盜:像這樣

CREATE FUNCTION fn_Split(@text varchar(8000), @delimiter varchar(20) = ' ') 
RETURNS @Strings TABLE 
( 
    position int IDENTITY PRIMARY KEY, 
    value varchar(8000) 
) 
AS 
BEGIN 
DECLARE @index int 
SET @index = -1 
WHILE (LEN(@text) > 0) 
    BEGIN 
    SET @index = CHARINDEX(@delimiter , @text) 
    IF (@index = 0) AND (LEN(@text) > 0) 
     BEGIN 
     INSERT INTO @Strings VALUES (@text) 
      BREAK 
     END 
    IF (@index > 1) 
     BEGIN 
     INSERT INTO @Strings VALUES (LEFT(@text, @index - 1)) 
     SET @text = RIGHT(@text, (LEN(@text) - @index)) 
     END 
    ELSE 
     SET @text = RIGHT(@text, (LEN(@text) - @index)) 
    END 
    RETURN 
END 

的只是做:

UPDATE tbl_users 
SET  ... 
FROM fn_split('7,15,18', ',') q 
JOIN tbl_users 
ON  id = CAST(q.value AS INT)