我有一个由逗号分隔的分隔数字的varchar字符串,我想在我的SQL脚本中使用但我需要与数据库中的bigint字段进行比较。需要知道转换它:
DECLARE @RegionID varchar(200) = null
SET @RegionID = '853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
SELECT a.ClassAdID, -- 1
a.AdURL, -- 2
a.AdTitle, -- 3
a.ClassAdCatID, -- 4
b.ClassAdCat, -- 5
a.Img1, -- 6
a.AdText, -- 7
a.MemberID, -- 9
a.Viewed, -- 10
c.Domain, -- 11
a.CreateDate -- 12
FROM ClassAd a
INNER JOIN ClassAdCat b ON b.ClassAdCAtID = a.ClassAdCAtID
INNER JOIN Region c ON c.RegionID = a.RegionID
AND a.PostType = 'CPN'
AND DATEDIFF(d, GETDATE(), ExpirationDate) >= 0
AND a.RegionID IN (@RegionID)
AND Viewable = 'Y'
此操作失败,并显示以下错误:
Error converting data type varchar to bigint.
RegionID在数据库中是一个bigint字段..需要将varchar转换为bigint ..任何想法..?
非常感谢,
neojakey
答案 0 :(得分:3)
创建此功能:
CREATE function [dbo].[f_split]
(
@param nvarchar(max),
@delimiter char(1)
)
returns @t table (val nvarchar(max), seq int)
as
begin
set @param += @delimiter
;with a as
(
select cast(1 as bigint) f, charindex(@delimiter, @param) t, 1 seq
union all
select t + 1, charindex(@delimiter, @param, t + 1), seq + 1
from a
where charindex(@delimiter, @param, t + 1) > 0
)
insert @t
select substring(@param, f, t - f), seq from a
option (maxrecursion 0)
return
end
更改此部分:
AND a.RegionID IN (select val from dbo.f_split(@regionID, ','))
更改此选项可获得更好的整体效果:
AND DATEDIFF(d, 0, GETDATE()) <= ExpirationDate
答案 1 :(得分:1)
您的查询不知道那些是单独的值,您可以使用动态sql:
DECLARE @RegionID varchar(200) = null
SET @RegionID = '853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
declare @sql nvarchar(Max)
set @sql = 'SELECT a.ClassAdID, -- 1
a.AdURL, -- 2
a.AdTitle, -- 3
a.ClassAdCatID, -- 4
b.ClassAdCat, -- 5
a.Img1, -- 6
a.AdText, -- 7
a.MemberID, -- 9
a.Viewed, -- 10
c.Domain, -- 11
a.CreateDate -- 12
FROM ClassAd a
INNER JOIN ClassAdCat b ON b.ClassAdCAtID = a.ClassAdCAtID
INNER JOIN Region c ON c.RegionID = a.RegionID
AND a.PostType = ''CPN''
AND DATEDIFF(d, GETDATE(), ExpirationDate) >= 0
AND a.RegionID IN ('+@RegionID+')
AND Viewable = ''Y'''
exec sp_executesql @sql
答案 2 :(得分:1)
我有时使用这个apporach并且发现它非常好。 它将逗号分隔的字符串转换为AUX表(称为#ARRAY),然后根据AUX表查询主表:
declare @RegionID varchar(50)
SET @RegionID = '853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
declare @S varchar(20)
if LEN(@RegionID) > 0 SET @RegionID = @RegionID + ','
CREATE TABLE #ARRAY(region_ID VARCHAR(20))
WHILE LEN(@RegionID) > 0 BEGIN
SELECT @S = LTRIM(SUBSTRING(@RegionID, 1, CHARINDEX(',', @RegionID) - 1))
INSERT INTO #ARRAY (region_ID) VALUES (@S)
SELECT @RegionID = SUBSTRING(@RegionID, CHARINDEX(',', @RegionID) + 1, LEN(@RegionID))
END
select * from your_table
where regionID IN (select region_ID from #ARRAY)
它避免了你连接查询字符串然后使用EXEC执行它,我不认为这是一个非常好的方法。
如果您需要运行代码两次,则需要删除临时表
答案 3 :(得分:0)
我认为答案应该保持简单 尝试使用CHARINDEX:
DECLARE @RegionID VARCHAR(200) = NULL
SET @RegionID =
'853,834,16,467,841,460,495,44,859,457,437,836,864,434,86,838,458,472,832,433,142,154,159,839,831,469,442,275,840,299,446,220,300,225,227,447,301,450,230,837,441,835,302,477,855,411,395,279,303'
SELECT 1
WHERE Charindex('834', @RegionID) > 0
SELECT 1
WHERE Charindex('999', @RegionID) > 0
当CHARINDEX
找到大字符串变量中的值时,它将返回它的位置,否则返回0。
将其用作搜索工具。
答案 4 :(得分:0)
更改此查询的最简单方法是使用字符串函数替换IN
函数。以下是我认为使用LIKE
(在数据库中可移植)最安全的方法:
AND ','+@RegionID+',' like '%,'+cast(a.RegionID as varchar(255))+',%'
或CHARINDEX
:
AND charindex(','+cast(a.RegionID as varchar(255))+',', ','+@RegionID+',') > 0
但是,如果您明确地将列表放在代码中,为什么不使用临时表?
declare @RegionIds table (RegionId int);
insert into @RegionIds
select 853 union all
select 834 union all
. . .
select 303
然后您可以使用IN
子句中的表:
AND a.RegionId in (select RegionId from @RegionIds)
或JOIN
条款。
答案 5 :(得分:0)
我喜欢迭戈的答案,但我认为我的修改更好一些,因为你声明了一个表变量而没有创建一个实际的表。我知道“in”语句可能有点慢,所以我做了内连接,因为我还需要公司表中的一些信息。
declare @companyIdList varchar(1000)
set @companyIdList = '1,2,3'
if LEN(@companyIdList) > 0 SET @companyIdList = @companyIdList + ','
declare @CompanyIds TABLE (CompanyId bigint)
declare @S varchar(20)
WHILE LEN(@companyIdList) > 0 BEGIN
SELECT @S = LTRIM(SUBSTRING(@companyIdList, 1, CHARINDEX(',', @companyIdList) - 1))
INSERT INTO @CompanyIds (CompanyId) VALUES (@S)
SELECT @companyIdList = SUBSTRING(@companyIdList, CHARINDEX(',', @companyIdList) + 1, LEN(@companyIdList))
END
select d.Id, d.Name, c.Id, c.Name
from [Division] d
inner join [Company] c on d.CompanyId = c.Id
inner join @CompanyIds cids on c.Id = cids.CompanyId