MSSQL:使用参数的内部值的子字符串值
我有两个变量。 第一个变量@where子句包含以下值: c1='v111'和c2='v222'以及c3='v333'和c4='v444' 第二个变量@ConditionFields包含值:c2,c4 现在,我怎样才能得到c2和c4的值。MSSQL:使用参数的内部值的子字符串值,sql,sql-server,Sql,Sql Server,我有两个变量。 第一个变量@where子句包含以下值: c1='v111'和c2='v222'以及c3='v333'和c4='v444' 第二个变量@ConditionFields包含值:c2,c4 现在,我怎样才能得到c2和c4的值。 像@newwhere子句一样,值将是:c2='v222'和c4='v444'。请帮助。这似乎是一种奇怪的方法,但它很有效-我相信这也可以优化,有几种不同的方法可以分割字符串,我只是觉得这是一种非常酷的方法 DECLARE @WhereClause varchar
像@newwhere子句一样,值将是:c2='v222'和c4='v444'。请帮助。这似乎是一种奇怪的方法,但它很有效-我相信这也可以优化,有几种不同的方法可以分割字符串,我只是觉得这是一种非常酷的方法
DECLARE @WhereClause varchar(MAX)
DECLARE @NewWhereClause varchar(MAX)
DECLARE @ConditionFields varchar(MAX)
DECLARE @Delimiter char(1)
DECLARE @X xml
DECLARE @TempCondition varchar(MAX)
DECLARE @TempWhereClause varchar(MAX)
SET @WhereClause = 'c1=''v111'' and c2=''v222'' and c3=''v333'' and c4=''v444'''
SET @ConditionFields = 'c2,c4'
SET @Delimiter = ','
SET @NewWhereClause = ''
SELECT @X = CONVERT(xml,'<root><s>' + REPLACE(@ConditionFields,@Delimiter,'</s><s>') + '</s></root>')
DECLARE ColCursor CURSOR FOR
SELECT [Value] = T.c.value('.','varchar(20)')
FROM @X.nodes('/root/s') T(c)
WHERE T.c.value('.','varchar(20)') <> ''
OPEN ColCursor
FETCH NEXT FROM ColCursor INTO @TempCondition
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @TempWhereClause = SUBSTRING(@WhereClause, CHARINDEX(@TempCondition, @WhereClause), CHARINDEX(' ', @WhereClause))
IF @NewWhereClause = ''
BEGIN
SET @NewWhereClause = @TempWhereClause
END
ELSE
BEGIN
SET @NewWhereClause += ' and ' + @TempWhereClause
END
FETCH NEXT FROM ColCursor INTO @TempCondition
END
CLOSE ColCursor
DEALLOCATE ColCursor
SELECT @NewWhereClause
以下是:首先,我同意帖子上的评论;这个实现非常难看。也就是说,我很无聊,给你
/*
This will work assuming your variable formats are always consistent with no leading or trailing spaces:
@WhereClause format (SingleValue:"c1='v111'"; MultipleValues:"c1='v111' and c2='v222' and x#='...' and 'c156='anything'"
@ConditionFields format (SingleValue:"c2"; MultipleValues:"c2,c4,c7,...,c156"
*/
Create Function dbo.ApplyConditionFields (@WhereClause Varchar(Max), @ConditionFields Varchar(Max))
Returns Varchar(Max)
With Execute As Caller
As
Begin
Declare @output Varchar(Max)
If @WhereClause Like '%=%'
Begin
;With parsedWhere As
(
Select Left(@WhereClause,CharIndex('=',@WhereClause)-1) As parsedVar,
Substring(@WhereClause,CharIndex('=',@WhereClause)+1,CharIndex(' ',@WhereClause+' ')-CharIndex('=',@WhereClause)-1) As parsedVal,
LTrim(Replace(Right(@WhereClause+' and ',Len(@WhereClause+' and ')-CharIndex(' and ',@WhereClause + ' and ')+2),' and ',' ')) As rest
Union All
Select Left(rest,CharIndex('=',rest)-1) As parsedVar,
Substring(rest,CharIndex('=',rest)+1,CharIndex(' ',rest)-CharIndex('=',rest)-1) As parsedVal,
Right(rest,Len(rest)-CharIndex(' ',rest)+1) As rest
From parsedWhere
Where rest <> ' '
), parsedFields As
(
Select Left(@ConditionFields+',',CharIndex(',',@ConditionFields + ',')-1) As parsedVar,
Right(@ConditionFields+',',Len(@ConditionFields+',')-CharIndex(',',@ConditionFields+',')) As rest
Union All
Select Left(rest,CharIndex(',',rest + ',')-1) As parsedVar,
Right(rest,Len(rest)-CharIndex(',',rest+',')) As rest
From parsedFields
Where rest <> ''
)
Select @output = Coalesce(@output+' and ','')+pw.parsedVar+'='+pw.parsedVal
From parsedWhere pw
Join parsedFields pf
On pw.parsedVar = pf.parsedVar
End
Return(@output)
End
您是否正在尝试解析@where子句字符串中的值?如果是,为什么?你说只得到c2和c4的值是什么意思?请发布整个查询。如果这些查询是从外部代码传递的,我建议用表值参数替换它们。如果它们是您正在处理的代码的内部代码,我建议用表变量替换它们。无论哪种方式,我都建议尝试使用结构化数据,而不是每次都尝试进行复杂的字符串操作。这非常好。我尝试过的所有用例都有效,除了您在where子句中不存在条件值的场景。当我这样做时,它包括第一个节点,而不管我放了什么。试试‘c1,c4,c6,c8’,看看我的意思。您可以进行任何更改来修复此问题吗?