Sql Server 2008 r2在函数内部使用WHILE循环

时间:2014-02-12 19:34:10

标签: sql sql-server function loops while-loop

我读了一个答案,说你不想在SQL Server中使用WHILE循环。我不明白这种概括。我对SQL很新,所以我可能还不明白这个解释。我还读到,除非你必须,否则你真的不想使用游标。我发现的搜索结果对于提出的问题太具体了,我无法从中收集有用的技术,所以我把它呈现给你。

我要做的是获取客户端文件中的值并在必要时缩短它们。这里有几件事需要实现。我不能简单地破解提供的字段值。我的公司有标准缩写。我把这些放在表格中,缩写。该表包含LongNameShortName。我不想简单地缩写行中的每个LongName。只要字段长度太长,我只想应用更新。这就是我需要WHILE循环的原因。

我的思考过程是:

CREATE FUNCTION [dbo].[ScrubAbbrev]
(@Field nvarchar(25),@Abbrev nvarchar(255))
RETURNS varchar(255)
AS
BEGIN
    DECLARE @max int = (select MAX(stepid) from Abbreviations)
    DECLARE @StepID int = (select min(stepid) from Abbreviations)
    DECLARE @find varchar(150)=(select Longname from Abbreviations where Stepid=@stepid)
    DECLARE @replace varchar(150)=(select ShortName from Abbreviations where Stepid=@stepid)
    DECLARE @size int = (select max_input_length from FieldDefinitions where FieldName = 'title')
    DECLARE @isDone int = (select COUNT(*) from SizeTest where LEN(Title)>(@size))

    WHILE @StepID<=@max or @isDone = 0 and LEN(@Abbrev)>(@size) and @Abbrev is not null
    BEGIN
        RETURN
        REPLACE(@Abbrev,@find,@replace)
        SET @StepID=@StepID+1
        SET @find =(select Longname from Abbreviations where Stepid=@stepid)
        SET @replace =(select ShortName from Abbreviations where Stepid=@stepid)
        SET @isDone = (select COUNT(*) from SizeTest where LEN(Title)>(@size))
    END
END

显然RETURN应该在最后,但我需要将我的变量重置为下一个@stepID@find@replace

这是我必须使用游标(我从未编写过)的时间吗?

1 个答案:

答案 0 :(得分:1)

通常,您不希望在SQL中使用游标或while循环,因为它们一次只处理一行,因此执行效果非常差。 SQL的设计和优化是为了处理(可能非常大的)数据,而不是单个值。

您可以通过执行以下操作来分解while循环:

UPDATE t
SET t.targetColumn = a.ShortName
FROM targetTable t
INNER JOIN Abbreviations a
ON t.targetColumn = a.LongName
WHERE LEN(t.targetColumn) > @maxLength

这是概括性的,您需要调整它以适合您的特定数据模型,但这是正在发生的事情:

对于“targetTable”中的每一行,将“targetColumn”(您要缩写的内容)的值设置为相关缩写(在Abbreviations.ShortName中找到)iff:当前值具有标准化缩写(内部联接)并且当前值比期望值(where条件)更长。

您需要添加一个整数参数或局部变量@maxLength来指示“太长”的构成。此查询一次处理目标表,更新每个符合条件的行的目标列中的值,而函数一次只能找到单个项(一行和一列的交集)的缩写。

请注意,如果值太长但没有标准缩写,则不会执行任何操作。您现有的代码具有相同的限制,因此我认为这是期望的行为。

我还建议将其作为存储过程而不是函数。 SQL Server上的函数被视为黑盒子,可能严重损害性能,因为优化器通常不太了解它们正在做什么。