C# sql server:如何在存储过程中使用查询结果

C# sql server:如何在存储过程中使用查询结果,c#,sql-server,stored-procedures,C#,Sql Server,Stored Procedures,我有一个三列的表关联 相关性 user1 user2 corr 此表包含所有用户对的相关值 我需要更新另一个表中所有对的corr值 我使用的查询是: UPDATE correlation SET corr = (SELECT ROUND((COUNT(*) * SUM(x.rating * y.rating) - SUM(x.rating) * SUM(y.rating)) / (SQRT(COUNT(*) * SUM(SQUARE(x.rati

我有一个三列的表关联

相关性

user1   user2   corr 
此表包含所有用户对的相关值

我需要更新另一个表中所有对的corr值

我使用的查询是:

UPDATE correlation
SET corr = (SELECT ROUND((COUNT(*) * SUM(x.rating * y.rating) - SUM(x.rating) * SUM(y.rating)) /
                   (SQRT(COUNT(*) * SUM(SQUARE(x.rating)) - SQUARE(SUM(x.rating))) * SQRT(COUNT(*) 
                     * SUM(SQUARE(y.rating)) - SQUARE(SUM(y.rating)))), 2) 
            FROM            users AS x INNER JOIN
                     users AS y ON x.itemID = y.itemID
            WHERE        (x.userID = @user1) AND (y.userID = @user2)))
WHERE user1 = @user1 and user2 = @user2
如何使用过程执行此查询

我首先从相关表中检索所有用户对

SELECT user1, user2 from correlation 
如何使用此查询的结果,并对返回的每一行执行更新查询

相关表中约有200万行


我试着用SqlDataReader在C代码中实现这一点(没有任何存储过程),但时间太长了。SqlDataReader将读取所有行,对于读取的每一行,它将执行更新查询

你可以做三件事:

  • 使用大容量插入/更新或来自的其他技术

  • 使用CLR SP(这样,您就可以在c#中编写它,然后将它作为存储过程插入数据库,您就可以运行它了)。请参阅有关的详细信息

  • 使用普通的老SQL,但由于我不是SQL大师,我将把这个选项留给其他人来回答


  • 是否要更新关联表中的所有记录?像这样:

    UPDATE correlation
       SET corr = (SELECT ROUND((COUNT(*) * SUM(x.rating * y.rating) - SUM(x.rating) * SUM(y.rating)) /
                          (SQRT(COUNT(*) * SUM(SQUARE(x.rating)) - SQUARE(SUM(x.rating))) * SQRT(COUNT(*) 
                          * SUM(SQUARE(y.rating)) - SQUARE(SUM(y.rating)))), 2) 
                     FROM users AS x
               INNER JOIN users AS y
                       ON x.itemID = y.itemID
                    WHERE (x.userID = user1) AND (y.userID = user2)))
    


    若您正在从数据库表中检索数据并将其发送回数据库,那个么我建议您创建SP,SP将为您执行相同的操作

     CREATE PROCEDURE [Procedure_Name]
    
     AS
    
     BEGIN
    
     declare @user1  int
     declare @user2 int
     declare cur CURSOR LOCAL for
    
     SELECT user1, user2 from correlation 
    
     open cur
    
     fetch next from cur into @user1, @user2
    
     while @@FETCH_STATUS = 0 BEGIN
    
     UPDATE correlation
     SET corr = (SELECT ROUND((COUNT(*) * SUM(x.rating * y.rating) - SUM(x.rating) *         SUM(y.rating)) /
                   (SQRT(COUNT(*) * SUM(SQUARE(x.rating)) - SQUARE(SUM(x.rating))) * SQRT(COUNT(*) 
                     * SUM(SQUARE(y.rating)) - SQUARE(SUM(y.rating)))), 2) 
            FROM            users AS x INNER JOIN
                     users AS y ON x.itemID = y.itemID
            WHERE        (x.userID = @user1) AND (y.userID = @user2)))
            WHERE user1 = @user1 and user2 = @user2
    
     --If you have Sp to perform above put your SP 
     --execute your SP with user1, user2 on each row
     --For example exec uspYourSP @user1, @user2
    
     fetch next from cur into @user1, @user2
    END
    
    close cur
    deallocate cur
    
    END
    

    现在,SP就位后,只需从C#调用SP,无需任何参数。这也将提高您的性能,因为我们正在从游标获取记录

    是,我想更新相关表中的所有记录。谢谢你的查询@EduardoS看起来这个查询可以帮我解决问题。在“SET corr=“我没有错过”(选择)之后,您错过了“(选择)”,这是一种有效的更新语法,关于性能,通常这种更新比在所有记录上使用光标更快,但最好的选择是测试这两个选项,并根据实际数据进行选择,而不是猜测。这会产生错误:在UPDATE语句的集合列表中可能不会出现聚合。此外,似乎与is query。它更新整个表,但只使用一个值。我假设的原因是缺少WHERE子句。我的错误是,我完成了忽略了聚合,加起来您需要一个子查询来更新工作,或者:第一个查询工作正常,第二个查询需要一些修改,我已经完成了。再次感谢您的时间。Tha谢谢您的代码Dnyanesh。@上面的EduardoS优化了我的查询,使之能够通过一个查询执行任务,尽管是通过一个联接。从性能角度看,我不确定SP或带有联接的单个查询哪一个更快(考虑到表有约200万元组)感谢您的反馈。在性能方面,您认为哪一个最适合涉及大型表的事务。在SQL中没有太多的批量操作,所以不能说。我想说,尝试使用较小的记录子集进行基准测试,但EduardoS似乎给了您一个答案:)
     CREATE PROCEDURE [Procedure_Name]
    
     AS
    
     BEGIN
    
     declare @user1  int
     declare @user2 int
     declare cur CURSOR LOCAL for
    
     SELECT user1, user2 from correlation 
    
     open cur
    
     fetch next from cur into @user1, @user2
    
     while @@FETCH_STATUS = 0 BEGIN
    
     UPDATE correlation
     SET corr = (SELECT ROUND((COUNT(*) * SUM(x.rating * y.rating) - SUM(x.rating) *         SUM(y.rating)) /
                   (SQRT(COUNT(*) * SUM(SQUARE(x.rating)) - SQUARE(SUM(x.rating))) * SQRT(COUNT(*) 
                     * SUM(SQUARE(y.rating)) - SQUARE(SUM(y.rating)))), 2) 
            FROM            users AS x INNER JOIN
                     users AS y ON x.itemID = y.itemID
            WHERE        (x.userID = @user1) AND (y.userID = @user2)))
            WHERE user1 = @user1 and user2 = @user2
    
     --If you have Sp to perform above put your SP 
     --execute your SP with user1, user2 on each row
     --For example exec uspYourSP @user1, @user2
    
     fetch next from cur into @user1, @user2
    END
    
    close cur
    deallocate cur
    
    END