我在IN SQL語句有一個小問題。我只是想知道有人能幫助我嗎?TSQL聲明IN
@Ids = "1,2,3,4,5"
SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (CONVERT(VARCHAR,@Ids))
這回來了,下面的錯誤,我相信這很簡單!
Conversion failed when converting the varchar value '1,' to data type int.
我在IN SQL語句有一個小問題。我只是想知道有人能幫助我嗎?TSQL聲明IN
@Ids = "1,2,3,4,5"
SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (CONVERT(VARCHAR,@Ids))
這回來了,下面的錯誤,我相信這很簡單!
Conversion failed when converting the varchar value '1,' to data type int.
SQL IN子句不接受單個變量來表示值列表 - 沒有使用動態SQL,數據庫沒有。否則,可以使用use a Table Valued Function(SQL Server 2000+)將值從列表中提取出來。&將它們返回爲您可以加入的表。
動態SQL例如:
EXEC('SELECT *
FROM Nav
WHERE NavigationID IN ('+ @Ids +')')
我建議使用SQL Server上的動態SQL之前閱讀The curse and blessings of dynamic SQL。
您正在做的事情對於SQL IN
語句不可行。您無法將字符串傳遞給它,並期望該字符串被解析。 IN用於特定的硬編碼值。
傑森:
首先創建這樣
Create FUNCTION [dbo].[ftDelimitedAsTable](@dlm char, @string varchar(8000))
RETURNS
--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
declare @dlm char, @string varchar(1000)
set @dlm=','; set @string='t1,t2,t3';
-- tHIS FUNCION RETUNRS IN THE ASCENDING ORDER
-- 19TH Apr 06
------------------------------------------------------------------------*/
--declare
@table_var TABLE
(id int identity(1,1),
r varchar(1000)
)
AS
BEGIN
declare @n int,@i int
set @n=dbo.fnCountChars(@dlm,@string)+1
SET @I =1
while @I <= @N
begin
insert @table_var
select dbo.fsDelimitedString(@dlm,@string,@i)
set @I= @I+1
end
if @n =1 insert @TABLE_VAR VALUES(@STRING)
delete from @table_var where r=''
return
END
一個函數,然後
set quoted_identifier off
declare @ids varchar(max)
select @Ids = "1,2,3,4,5"
declare @nav table (navigationid int identity(1,1),theother bigint)
insert @nav(theother) select 10 union select 11 union select 15
SELECT * FROM @Nav WHERE CONVERT(VARCHAR,NavigationID) IN (select id from dbo.ftDelimitedAsTable(',',@Ids))
select * from dbo.ftDelimitedAsTable(',',@Ids)
+1:對於表值函數示例 – 2010-12-18 20:47:07
有兩種方法可以做到你想在這裏做什麼。 一個是創建一個'動態sql'查詢並執行它,代入IN列表後。
DECLARE @query varchar(max);
SET @query = 'SELECT * FROM Nav WHERE CONVERT(VARCHAR,NavigationID) IN (' + @Ids + ')'
exec (@query)
這會產生性能影響和其他併發症。通常我會盡量避免它。
另一種方法是使用用戶定義函數(UDF)將字符串拆分爲其組成部分,然後對其進行查詢。 有一個帖子詳細介紹瞭如何一旦函數存在創建功能here
,是微不足道的加入到它
SELECT * FROM Nav
CROSS APPLY dbo.StringSplit(@Ids) a
WHERE a.s = CONVERT(varchar, Nav.NavigationId)
NB-的「作爲」字段引用基於鏈接的功能,哪些商店名爲's'的列中的拆分值。這可能會因您的字符串分割函數的實現而有所不同
這很好,因爲它使用基於集合的方法查詢而不是IN子查詢,但CROSS JOIN可能有點複雜,所以如果你想保持IN語法,那麼下面的應該工作:
SELECT * FROM Nav
WHERE Nav.NavigationId IN
(SELECT CONVERT(int, a.s) AS Value
FROM dbo.StringSplit(@Ids) a
作爲一個側面說明,動態查詢不能很好地處理查詢優化器,但這不是問題。 – 2010-12-18 20:39:14
@PulsarBlow:「處理得好」是模糊的,而且不正確 - 動態和非動態查詢與優化器沒有區別。但是'EXEC'已知不會緩存查詢計劃,而'sp_executesql'確實不會。我建議你閱讀關於動態sql的詛咒和祝福的鏈接。 – 2010-12-18 20:44:21