【问题标题】:SQL Server - Issue with UPDATE inside while loop in a function?SQL Server - 函数中的while循环内的UPDATE问题?
【发布时间】:2016-11-17 14:02:13
【问题描述】:

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

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

如果 EmployeeName 是“XYZ”,那么密码将是“XYZ@123”,邮件 ID 将是“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 命令时保存。

Update 在 while 循环中是否有问题?

【问题讨论】:

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


    【解决方案1】:

    这里发生了几件事。

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

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

    1. 抓取所有员工,对他们进行分类
    2. 获取单行并更新它
    3. 将该行插入到表变量中以供以后输出

    首先,尝试一次更新表中的每一行:

    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
    

    如果事实证明您遇到问题是因为您尝试一次更新的行太多,那么也许您可以查看批处理,但这可能是一个单独的主题。

    【讨论】:

    • 也许我应该使用一个临时表并用它来遍历每一行。如果 SQL Server 中还有其他可能性,请告诉我。
    • 你刚才描述的基本上是CURSORblog.sqlauthority.com/2007/01/01/…,但这不是通常推荐的在数据库中实现事物的方法。
    猜你喜欢
    • 1970-01-01
    • 2016-01-04
    • 2011-06-19
    • 2021-07-31
    • 2015-08-06
    • 2014-03-11
    • 2020-03-01
    • 2014-08-22
    • 1970-01-01
    相关资源
    最近更新 更多