SQL Server - 在函数中循环时UPDATE问题?

时间:2016-11-17 14:02:14

标签: sql sql-server function stored-procedures mdf

我有一个表,我愿意使用函数填充两列使用其他列值生成的值。

注意:我正在使用Visual Studio中的.mdf文件,而不是SQL Server。

如果EmployeeName是' XYZ'然后密码将是' XYZ @ 123'和mailid将是' XYZ@gmail.com'

这是程序

CREATE FUNCTION [dbo].[fnTempSetAllEmployeeMailIdAndEmployeePassword]()
RETURNS @OutputTable TABLE
(
    EmployeeName NVARCHAR(250),
    TempEmployeeMailId NVARCHAR(250),
    TempEmployeePassword NVARCHAR(250)
)
AS
BEGIN
    DECLARE @Initialiser INT = 1, @NumberOfRowsInTable INT, @TempEmployeeId INT, @TempEmployeeName NVARCHAR(250);

    SELECT @NumberOfRowsInTable = COUNT(*) 
    FROM tbEmployee;

    WHILE(@Initialiser <= @NumberOfRowsInTable)
    BEGIN
        SELECT 
            @TempEmployeeName = [EmployeeName], 
            @TempEmployeeId = [EmployeeId]
        FROM 
            (SELECT 
                 ROW_NUMBER() OVER(ORDER BY [EmployeeId] ASC) AS ROwNumber, 
                 [EmployeeId], [EmployeeName]
             FROM 
                 tbEmployee) AS TempTable
        WHERE 
            RowNumber = @Initialiser;

        UPDATE tbEmployee 
        SET [EmployeeMailId] = LOWER(@TempEmployeeName) + '@gmail.com', 
            [EmployeePassword] = LOWER(@TempEmployeeName) + '@123'
        WHERE [EmployeeId] = @TempEmployeeId;

        SET @Initialiser = @Initialiser + 1;
    END

    INSERT @OutputTable
        SELECT [EmployeeName], [EmployeeMailId], [EmployeePassword] 
        FROM tbEmployee;

    RETURN
END

问题是我执行新查询文件时上述语句有效。

但是当我输入功能并尝试更新它时。我不会保存,并说执行时出错了。

但是当我评论UPDATE命令时保存。

更新是否在while循环中有问题吗?

1 个答案:

答案 0 :(得分:3)

这里有几件事情。

首先,它在函数中不起作用的原因是因为在SQL Server函数中无法更改数据库中的任何内容。您正在尝试更改表中的数据,这是不允许的。它将被允许存储过程。

其次,它看起来是一种非常低效的更新方式。对于循环的每次迭代,此代码:

  1. 抓住所有员工,对他们进行排序
  2. 只需一行并对其进行更新
  3. 将该行插入表变量以便稍后输出
  4. 作为一个起点,尝试只需一次更新表格中的每一行:

    CREATE PROCEDURE dbo.TempSetAllEmployeeMailIdAndEmployeePassword AS
    BEGIN
        UPDATE tbEmployee 
        SET [EmployeeMailId] = LOWER(@TempEmployeeName) + '@gmail.com',
            [EmployeePassword] = LOWER(@TempEmployeeName) + '@123';
    
        SELECT EmployeeName, EmployeeMailID, EmployeePassword
        FROM tblEmployee;
    END
    

    如果事实证明你有问题,因为有太多的行你想要立即更新,那么也许你可以看看批处理,但这可能是一个单独的主题。