替换值中的文本而不知道下一个字符

时间:2013-06-26 13:31:47

标签: sql sql-server sql-server-2008

我正在尝试替换我的一个SQL列中的文本。通过找到/*REPLACE*/的所有引用,下一个字符是一个必须被5000填充的数字值,可以很容易地找到要替换的文本。

原始值的示例显示如下。

var checkIn = moment(FIELD(/*REPLACE*/4,/*REPLACE*/9).GET());  
var checkOut = moment(FIELD(/*REPLACE*/4,/*REPLACE*/10).GET());    
if (checkIn > checkOut) {      
    FIELD(/*REPLACE*/4,/*REPLACE*/10).SET(checkIn.format("DD MMM YYYY"));      
    checkOut = moment(FIELD(/*REPLACE*/4,/*REPLACE*/10).GET());  
}    
FIELD(/*REPLACE*/4,/*REPLACE*/11).SET(parseFloat(checkOut.diff(checkIn, "days")).toFixed(2));

我需要查找/*REPLACE*/的所有引用,并将以下字符增加为5000。

下面显示了新值的示例。

var checkIn = moment(FIELD(5004,5009).GET());  
var checkOut = moment(FIELD(5004,5010).GET());    
if (checkIn > checkOut) {      
FIELD(5004,5010).SET(checkIn.format("DD MMM YYYY"));      
checkOut = moment(FIELD(5004,5010).GET());  
}    
FIELD(5004,5011).SET(parseFloat(checkOut.diff(checkIn, "days")).toFixed(2));

我已经从基本开始但是在文本后面找到了数字字符而迷路了。

SELECT column.REPLACE(column, '/*REPLACE*/',

请帮忙吗?

3 个答案:

答案 0 :(得分:2)

假设您的列是varchar或类似类型(不是文本),您可以使用T-SQL脚本预先替换该替换。

您将需要迭代每个/ REPLACE / string,然后使用另一个嵌套循环来搜索下一个下面的数字。一旦知道最后一个数字的位置,就可以将这些数字转换为数字,并用该数字+ 5000替换所需的字符串。

我给你发了一个例子。您可以立即运行此脚本进行测试,但需要将其调整为表/列。

此外,如果您的列是Text类型,也可以执行相同的操作,但它需要将文本拆分为varchar块并迭代每个块。如果您需要帮助,请告诉我。

以下是代码:

-- table variable, simulating the table to be modified, for testing purposes
-- all references to @tbl and col should be replaced by the intended table/column
declare @tbl table (col varchar(max))
insert into @tbl values ('var checkIn = moment(FIELD(/*REPLACE*/4,/*REPLACE*/9).GET());  
var checkOut = moment(FIELD(/*REPLACE*/4,/*REPLACE*/10).GET());    
if (checkIn > checkOut) {      
    FIELD(/*REPLACE*/4,/*REPLACE*/10).SET(checkIn.format("DD MMM YYYY"));      
    checkOut = moment(FIELD(/*REPLACE*/4,/*REPLACE*/10).GET());  
}    
FIELD(/*REPLACE*/4,/*REPLACE*/11).SET(parseFloat(checkOut.diff(checkIn, "days")).toFixed(2));')

declare @col_txt varchar(max),
        @replace_at int, @digit_start int, @digit_end int, @number int

select @col_txt = col from @tbl -- TODO add a where clause, and consider using a cursor for each row

set @replace_at = 0
-- loop for each /*REPLACE*/ string
while (1=1) begin
    set @replace_at = charindex('/*REPLACE*/', @col_txt, @replace_at + 1)
    if (@replace_at = 0) break

    set @digit_start = @replace_at + len('/*REPLACE*/')
    set @digit_end = @digit_start
    -- loop while the next char is a number, and save its position
    while (ascii(substring(@col_txt, @digit_end, 1)) between ascii(0) and ascii(9)) set @digit_end = @digit_end + 1
    set @number = cast(substring(@col_txt, @digit_start, @digit_end - @digit_start) as int) + 5000
    -- replace current /*REPLACE*/ and number with the found number + 5000 in the current text chunk
    set @col_txt = stuff(@col_txt, @replace_at, @digit_end - @replace_at, @number)
end

-- update the original table with the value
update @tbl set col = @col_txt -- TODO add a where clause

-- only for test purposes
select col from @tbl

答案 1 :(得分:0)

您真的需要在SQL Server上执行此操作,并使用T-SQL吗?第三代编程语言(例如C ++,C#,VB.NET等)支持更强大的字符串操作方法;例如,您可以使用正则表达式,这些表达式本身并未在SQL Server中实现。

您可以设计一个SQL CLR函数或过程来解决此限制,但更合适的替代方法是使用客户端应用程序。您还可以将SQL Server Integration Services与脚本转换一起使用(您可以使用C#或VB.NET)。

ML

答案 2 :(得分:0)

您可以创建一个简单的CLR函数来为您执行正则表达式操作。具有可用于SQL查询的正则表达式函数非常有用。

看一下这篇文章:Regular Expressions Make Pattern Matching And Data Extraction Easier