je dois tirer une sous-chaîne spécifique à partir d'une chaîne de la forme:Trouver une sous-chaîne spécifique en utilisant Transact-SQL
foo=abc;bar=def;baz=ghi
Par exemple, comment pourrais-je obtenir la valeur de « bar » de cette chaîne?
je dois tirer une sous-chaîne spécifique à partir d'une chaîne de la forme:Trouver une sous-chaîne spécifique en utilisant Transact-SQL
foo=abc;bar=def;baz=ghi
Par exemple, comment pourrais-je obtenir la valeur de « bar » de cette chaîne?
Vous pouvez utiliser charindex et substring. Par exemple, pour rechercher la valeur de « baz »:
declare @str varchar(128)
set @str = 'foo=abc;bar=def;baz=ghi'
-- Make sure @str starts and ends with a ;
set @str = ';' + @str + ';'
select substring(@str,
charindex(';baz=',@str) + len(';baz='),
charindex('=',@str,charindex(';baz=',@str)) - charindex(';baz=',@str) - 1)
Ou pour la valeur de « foo » au début de la chaîne:
select substring(@str,
charindex(';foo=',@str) + len(';foo='),
charindex('=',@str,charindex(';foo=',@str)) - charindex(';foo=',@str) - 1)
Voici une UDF pour ce faire (plus version lisible inspirée par la réponse de BlackTigerX):
create function dbo.FindValueInString(
@search varchar(256),
@name varchar(30))
returns varchar(30)
as
begin
declare @name_start int
declare @name_length int
declare @value_start int
declare @value_end int
set @search = ';' + @search
set @name_start = charindex(';' + @name + '=',@search)
if @name_start = 0
return NULL
set @name_length = len(';' + @name + '=')
set @value_start = @name_start + @name_length
set @value_end = charindex(';', @search, @value_start)
return substring(@search, @value_start, @value_end - @value_start)
end
Comme vous pouvez le voir, ce n'est pas facile dans le Better Sql Server faire dans la langue du client, ou normaliser votre base de données pour les sous-chaînes vont dans leurs propres colonnes .
Je suis d'accord, mais j'ai juste besoin de quelque chose qui fonctionne maintenant. –
Je devrais mentionner, cependant, que "barre" pourrait tout aussi bien être au début ou à la fin de cette chaîne. Je ne pense pas que votre solution explique cela. –
La solution est longue, mais cela devrait fonctionner? Même maintenant. :) – Andomar
Regardez dans la fonction PATINDEX. Il a caractère générique correspondant qui devrait vous aider ..
vous pouvez utiliser cette fonction
alter function FindValue(@txt varchar(200), @find varchar(200))
returns varchar(200)
as
begin
declare
@firstPos int,
@lastPos int
select @firstPos = charindex(@find, @txt), @lastPos = charindex(';', @txt, @firstPos+5)
select @lastPos = len(@txt)+1 where @lastPos = 0
return substring(@txt, @firstPos+len(@find)+1, @[email protected](@find)-1)
end
select dbo.FindValue('foo=abc;bar=def;baz=ghi', 'bar')
mise à jour: n'a pas été en utilisant la longueur de @find
J'ai une solution générale qui fonctionne pour ce problème:
CREATE FUNCTION [dbo].[fn_StringBetween]
(
@BaseString varchar(max),
@StringDelim1 varchar(max),
@StringDelim2 varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
DECLARE @at1 int
DECLARE @at2 int
DECLARE @rtrn varchar(max)
SET @at1 = CHARINDEX(@StringDelim1, @BaseString)
IF @at1 > 0
BEGIN
SET @rtrn = SUBSTRING(@BaseString, @at1
+ LEN(@StringDelim1), LEN(@BaseString) - @at1)
SET @at2 = CHARINDEX(@StringDelim2, @rtrn)
IF @at2 > 0
SET @rtrn = LEFT(@rtrn, @at2 - 1)
END
RETURN @rtrn
END
si vous courez (il suffit d'envelopper votre chaîne d'origine à rechercher avec ';' au début et à la fin):
PRINT dbo.fn_StringBetween(';foo=abc;bar=def;baz=ghi;', ';bar=', ';')
vous obtiendrez 'def' retourné.
ceci suppose que la chaîne aura le même format de chaîne de substitution juste le nom de la colonne pour le 'foo = abc, bar = def; baz = ghi'
select substring('foo=abc;bar=def;baz=ghi',patindex('%bar=%','foo=abc;bar=def;baz=ghi')+4, len('foo=abc;bar=def;baz=ghi')-patindex('%;baz=%','foo=abc;bar=def;baz=ghi')-4)
Cela peut atteindre de manière simple
DECLARE @str VARCHAR(30)
DECLARE @start INT
SET @str='foo=abc;bar=def;baz=ghi'
SET @start=CHARINDEX('bar',@str)
PRINT SUBSTRING(@str,@start,3)
est la chaîne d'une valeur de ligne ou quelque chose est passé? – Josh
avez-vous votre mot à dire dans le schéma db? stocker de telles valeurs va à l'encontre de la façon dont les bases de données sql sont supposées fonctionner. –
Je suis d'accord. Je ne l'aurais pas conçu de cette façon, mais je dois travailler avec du code existant. –