我们必须识别来自错误导入的一些数据,并且将不胜感激任何帮助。 例如,下面的字符串和charindex的标识符char。
SET @InputString = 'The quick brown fox jumped "over" or "under" the log'
SET @IdentifierChar = '"'
我们遇到的问题是,我们可以针对上面的硬编码字符串运行测试,并得到“结果”的结果。我们已尝试将其置于while循环中,然后我们会在'以及'或'或'''我们的预期结果只会返回'在''而不是或。
我们第一次参加测试就像下面的内容,只是看看尝试和分裂:
DECLARE @InputString Nvarchar(MAX)
DECLARE @IdentifierChar NCHAR(1)
SET @InputString = 'The quick brown fox jumped "over" or "under" the log'
SET @IdentifierChar = '"'
declare @FirstID int
declare @SecondID int
declare @Length int
declare @TargetString Nvarchar(MAX)
Set @FirstID = CHARINDEX(@IdentifierChar,@InputString,1)
Set @SecondID = CHARINDEX(@IdentifierChar,@InputString,@FirstID+1)
Set @Length = @SecondID-@FirstID
Set @TargetString = SUBSTRING(@InputString,@FirstID+1,@Length-1)
就像我说的那样,我们只是把它扔进一个硬编码循环中,并将子字符串的值设置为特殊字符标识符的最后位置,以便测试并查看charindex如何在引号之间拆分字符串我们没有想到它会得到“或”#39;同样。
所以这里是脏循环:
Set @COUNT = 0
Set @Length = 0
WHILE(@COUNT)<3
BEGIN
Set @FirstID = CHARINDEX(@IdentifierChar,@InputString,@Length)
Set @SecondID = CHARINDEX(@IdentifierChar,@InputString,@FirstID+1)
Set @Length = @SecondID-@FirstID
Set @TargetString = SUBSTRING(@InputString,@FirstID+1,@Length-1)
SET @COUNT = @COUNT+1
Set @Length =@SecondID
END
答案 0 :(得分:0)
可能有更好的方法来解析这个问题,但这是我对代码的最小修改,以使其正常工作,并通过评论我改变了一些内容:
DECLARE @InputString Nvarchar(MAX)
DECLARE @IdentifierChar NCHAR(1)
SET @InputString = 'The quick brown fox jumped "over" or "under" the log'
SET @IdentifierChar = '"'
declare @FirstID int
declare @SecondID int
declare @Length int
declare @TargetString Nvarchar(MAX)
declare @COUNT int -- added this missing from your code above
Set @COUNT = 0
Set @Length = 0
WHILE(@COUNT)<2 -- only need 2 here now
BEGIN
Set @FirstID = CHARINDEX(@IdentifierChar,@InputString,@Length)
Set @SecondID = CHARINDEX(@IdentifierChar,@InputString,@FirstID+1)
Set @Length = @SecondID-@FirstID
Set @TargetString = SUBSTRING(@InputString,@FirstID+1,@Length-1)
SET @COUNT = @COUNT+1
Set @Length =@SecondID+1 -- added one
print @TargetString -- so we can see what it finds
END
你的主要问题是在你的循环底部更新@Length - 当你认为你在&#34;&#34;之后指向PAST双引号时,你实际上正指向它并找到它时间作为开放报价之前&#34;或&#34;。
答案 1 :(得分:0)
根据数据集的大小和整体查询的复杂程度,您可以使用递归CTE:
$filepathname = 'valid file path and name'
$dest = '\DoesntExist\'
try
{
Copy-Item $filepathname $dest -errorAction stop
Write-Host "Success"
}
catch
{
Write-Host "Failure"
}
答案 2 :(得分:0)
这是我编写并保存在工具箱中的用户定义函数。这是一个略带标签的用法,但它应该适合你。
如果我们认为这个字符串是五个子字符串,由四个双引号字符分隔,那么我们可以拆分那些只需要获取子字符串2和4.(获得第三或第四个引用值就像获取子字符串一样简单6或8)尝试获取不存在的元素只会返回NULL。
执行下面的CREATE语句后会创建dbo.SPLIT_LIST函数,你可以这样调用它:
declare @InputString varchar(255)
SET @InputString = 'The quick brown fox jumped "over" or "under" the log'
select dbo.SPLIT_LIST(@InputString, '"', 2, ''),
dbo.SPLIT_LIST(@InputString, '"', 4, '')
你将获得两个输出值。这样的函数有什么好处,你可以把它放在你的select语句中,一次操作多条记录,而不是每条记录。
CREATE function dbo.SPLIT_LIST(
@string nvarchar(max),
@delimiter nvarchar(50),
@i int,
@text_qualifier nvarchar(1)
)
returns nvarchar(max)
/*
returns a selected element from a delimited list
select dbo.SPLIT_LIST_w_Qualifier('"twenty,one","twenty,two","twenty,three"', ',', 2,'"')
returns: 'twenty,two'
Note: can ignore embedded text qualifiers
*/
as
BEGIN
declare @value nvarchar(max),
@d_length int,
@next_delimiter nvarchar(51),
@q_length int, --length of the text qualifier
@trim int,
@using_qualifier int
set @d_length = len(@delimiter)
set @q_length = len(@text_qualifier)
set @string = ltrim(rtrim(@string))
--works by chopping off the leading value from the string each round
while @i > 0 and @string is not null and len(@string) > 0
begin
--if the remaining @string starts with the text qualifier,
--then the currently parsed value should end with the text qualifier+delimiter
if left(@string,1) = @text_qualifier
begin
set @using_qualifier = 1
--chop off leading qualifier
set @string = ltrim(right(@string,(len(@string)-len(@text_qualifier))))
end
else
begin
set @using_qualifier = 0
end
if (@using_qualifier = 0) -- If we are NOT using a text qualifier for this element
begin
if (charindex(@delimiter, @string) > 0) --If there is a remaining delimiter
begin
set @value = ltrim(rtrim(left(@string, charindex(@delimiter, @string)-1)))
set @string = ltrim(rtrim(right(@string, len(@string)-charindex(@delimiter, @string) - @d_length + 1)))
end
else --no remaining delimiters
begin
set @value = @string
set @string = null
end
end
else -- If we ARE using a text qualifier for this element
begin
if (charindex((@text_qualifier+@delimiter), @string) > 0) --If there is a remaining qualifier+delimiter
begin
set @value = ltrim(rtrim(left(@string, charindex((@text_qualifier+@delimiter), @string)-1)))
set @string = ltrim(rtrim(right(@string, len(@string)-charindex((@text_qualifier+@delimiter), @string) - @d_length - @q_length + 1)))
end
else --no remaining qualifier+delimiters
begin
--Does the remaining string END with the text qualifier?
if (charindex(REVERSE(@text_qualifier), REVERSE(@string)) = 1)
begin
set @value = ltrim(rtrim(left(@string, len(@string)-@q_length)))
set @string = null
end
else if (charindex((@text_qualifier), @string) > 0) --Is there a remaining qualifier at all?
begin
set @value = ltrim(rtrim(left(@string, charindex((@text_qualifier), @string)-1)))
set @string = null
end
else --no final closing qualifier
begin
set @value = @string
set @string = null
end
end
end
set @i = @i - 1
--print @value
end
if @i = 0 return @value --should exit here
return NULL --a parse too far exists here
END
答案 3 :(得分:0)
只想更新。我继续玩弄代码并得到一些工作,以防将来有人想要使用类似的逻辑。这就是我们上面讨论过的。
DECLARE @TargetString NVARCHAR(MAX)
DECLARE @stringLen int
DECLARE @splitTbl TABLE(siteId NVARCHAR(MAX))
DECLARE @idChar NCHAR(1)
SET @TargetString = 'The quick brown fox jumped "over" or "under" the "log"'
SET @stringLen = CHARINDEX(' ', @TargetString)
SET @idChar = '"'
WHILE CHARINDEX(' ', @TargetString) > 0
BEGIN
SET @stringLen = CHARINDEX(' ', @TargetString);
INSERT INTO @splitTbl
SELECT SUBSTRING(@TargetString,1,@stringLen - 1);
SET @TargetString = SUBSTRING(@TargetString, @stringLen + 1,
LEN(@TargetString));
END
DECLARE @buildResults NVARCHAR(MAX)
INSERT INTO @splitTbl
SELECT @TargetString
DECLARE @buildLike NVARCHAR(MAX)
SET @buildLike = '%'+@idChar+'%'
SELECT @buildResults = COALESCE(@buildResults + ', ', '')
+SUBSTRING(siteId, 2, lEN(siteId) - 2)
FROM @splitTbl
WHERE siteId LIKE @buildLike