在SQL查詢中根據已知ID的集合來查詢結果我們通常會用到IN,直接在IN後面給出ID的集合或是在IN後面跟一個子查詢。如下:
SELECT * FROM OrdersWHERE OrderGUID IN('BC71D821-9E25-47DA-BF5E-009822A3FC1D','F2212304-51D4-42C9-AD35-5586A822258E')
可以看出直接在IN後面跟ID的集合需要將每一個ID都用單引號引起來。在實際應用中會遇到這麼一種情況,在介面中收集的是一串GUID的拼接字串,中間以逗號隔開,如果作為參數傳到一個預存程序中執行,最終產生的語句會是下面這樣:
SELECT * FROM OrdersWHERE OrderGUID IN('BC71D821-9E25-47DA-BF5E-009822A3FC1D,F2212304-51D4-42C9-AD35-5586A822258E')
這樣就不能查詢到正確的結果。 一般情況下我們解決此問題的思路是將傳入的字串用一個split函數來處理,最終處理的結果是一張表,然後將這個表做自查詢即可,如下:
DECLARE @IDs VARCHAR(4000)SET @IDs='BC71D821-9E25-47DA-BF5E-009822A3FC1D,F2212304-51D4-42C9-AD35-5586A822258E'DECLARE @temp TABLE(str VARCHAR(50))INSERT INTO @tempSELECT * FROM dbo.Split(@IDs,',')SELECT * FROM Orders WHERE OrderGUID IN (SELECT str FROM @temp)
當然split函數系統比不提供,需要我們自己寫:
CREATE FUNCTION Split( @SourceSql varchar(8000), @StrSeprate varchar(10))RETURNS @temp TABLE(F1 VARCHAR(100))ASBEGIN DECLARE @i INT SET @SourceSql=rtrim(ltrim(@SourceSql)) SET @i=charindex(@StrSeprate,@SourceSql) WHILE @i>=1 BEGIN INSERT @temp VALUES(left(@SourceSql,@i-1)) SET @SourceSql=substring(@SourceSql,@i+1,len(@SourceSql)-@i) SET @i=charindex(@StrSeprate,@SourceSql) END IF @SourceSql<>'' INSERT @temp VALUES(@SourceSql) RETURNEND
像這樣做非常麻煩,而且還需要藉助函數來實現,下面介紹一種簡單的方法,因為GUID是唯一的,所以在上面的例子中可以使用LIKE來代替IN也可以達到同樣的查詢效果:
SELECT * FROM OrdersWHERE 'BC71D821-9E25-47DA-BF5E-009822A3FC1D,F2212304-51D4-42C9-AD35-5586A822258E'LIKE '%'+convert(VARCHAR(40),OrderGUID)+'%'