在sql server 2005中获取for循环内每一行的主键

发布于 2025-01-05 04:40:45 字数 1250 浏览 4 评论 0原文

我想在 SQL Server 2005 中编写一个触发器,在 for 循环内我想根据主键更新特定表的每一行。问题是我应该如何获取for循环内每一行的主键?

请帮助

抱歉没有提及上述详细信息

  Table  UserPersonalInfo

   UserId       varchar(50) Primary Key                 
   FirstName    varchar(50)         
   MiddleName   varchar(50)         
   LastName         varchar(50)
   UserName         varchar(50)
   Password         varchar(50)
   ContactNo    bigint  
   Verified         bit 
   Address      varchar(100)    
   EmailId      varchar(100)    
   RoleId       int 
   CurrentFine  money   
   Photo        image   

   Table CurrentlyIssuedBook

   Userid   varchar(50) Primary Key
   BookId   varchar(50) 
   IssuedDate   datetime    
   ExpectedReturnDate   datetime    
   ISBN varchar(50) 

 Table CurrentDate

     date datetime

上面是两个表现

在我想做的是...

每次运行我的 C# 应用程序时,我都会尝试用实际的当前日期更新 CurrentDate 表中的日期。如果更新成功,则触发器将运行。

在触发器内部,我想为 UserPersonalInfo 表中的每个用户进行精细更新。为此,我考虑过使用循环,但是如何从 UserInfo 表中获取每行的主键值?

我的精细计算逻辑如下

totalfine = 0
x =  currentdate - ExpectedReturnDate
y = x/30
z = x%30

for(int i=0; i <y; i++)
{
   totalfine = totalfine + (2^i * 4 * 30);
}

totalfine = totalfine + (2^i * 4 * z);

现在请建议我该怎么办?

I want to write a trigger in SQL Server 2005 in which inside the for loop I want to update every row of a particular table based on its primary key. The problem is how should I get primary key of each row inside for loop?

Please Help

sorry for not mentioning above details

  Table  UserPersonalInfo

   UserId       varchar(50) Primary Key                 
   FirstName    varchar(50)         
   MiddleName   varchar(50)         
   LastName         varchar(50)
   UserName         varchar(50)
   Password         varchar(50)
   ContactNo    bigint  
   Verified         bit 
   Address      varchar(100)    
   EmailId      varchar(100)    
   RoleId       int 
   CurrentFine  money   
   Photo        image   

   Table CurrentlyIssuedBook

   Userid   varchar(50) Primary Key
   BookId   varchar(50) 
   IssuedDate   datetime    
   ExpectedReturnDate   datetime    
   ISBN varchar(50) 

 Table CurrentDate

     date datetime

Above are the two tables

Now what I am trying to do is...

Everytime I run my C# application I will try to update date in CurrentDate table with actual current date. If the update is successful then the trigger will run.

Inside trigger I want to update fine for each user in the UserPersonalInfo table. For that I have thought of using a loop but how will get primary key value of each row from UserInfo table?

My Fine Calculation logic is a follows

totalfine = 0
x =  currentdate - ExpectedReturnDate
y = x/30
z = x%30

for(int i=0; i <y; i++)
{
   totalfine = totalfine + (2^i * 4 * 30);
}

totalfine = totalfine + (2^i * 4 * z);

Now please suggest me what should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

姜生凉生 2025-01-12 04:40:45

不要使用循环。

您只需使用不带 where 子句的 update 语句即可更新表中的每一行,例如:

declare @currentdate datetime
select @currentdate = date from currentdate

update userinfo
set fine = case when @currentdate < getdate() then 100 else 0 end

当然,我不知道您的精细计算是什么,所以上面只是一个简单的例子。

可以将涉及其他表等的复杂计算放入上面的更新语句中,并且它会比循环快得多。话虽如此,如果您确实想使用循环,则需要使用游标。也许是这样的:

declare @ID int
declare cur_loop cursor fast_forward for 
    select UserId from UserInfo

open cur_loop
fetch next from cur_loop into @ID
while @@FETCH_STATUS=0 begin
    -- your code here
    update UserInfo set fine = (calculation result) where UserID=@ID
    fetch next from cur_loop into @ID
end
close cur_loop
deallocate cur_loop

Don't use a loop.

You can update every row in the table just by using an update statement with no where clause, eg:

declare @currentdate datetime
select @currentdate = date from currentdate

update userinfo
set fine = case when @currentdate < getdate() then 100 else 0 end

Of course, I don't know what your fine calculation is, so the above is just a trivial example.

It's possible to put complex calculations involving other tables and so on into an update statement as above, and it will be much faster than a loop. Having said that, if you really want to use a loop, you need to use a cursor. Maybe something like:

declare @ID int
declare cur_loop cursor fast_forward for 
    select UserId from UserInfo

open cur_loop
fetch next from cur_loop into @ID
while @@FETCH_STATUS=0 begin
    -- your code here
    update UserInfo set fine = (calculation result) where UserID=@ID
    fetch next from cur_loop into @ID
end
close cur_loop
deallocate cur_loop
甜心 2025-01-12 04:40:45

你不能做这样的事情吗:

 CREATE TRIGGER tr_CurrentDateUpdate
   ON  CurrentDate
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    UPDATE  UserInfo
    SET     fine = 6
    WHERE   userid like '%foo%'

    UPDATE  UserInfo
    SET     fine = 7
    WHERE   userid like '%baa%'

END
GO

其中“where”子句是你选择要更改的用户的标准,罚款=你的计算?

另外,我没有对此进行测试,但是,如果您在 UDF 中进行计算,我认为您可以在我的更新语句中放置类似的内容:

DECLARE @InsertedDate Datetime

SELECT  @InsertedDate = date
FROM inserted   

UPDATE  u
SET     u.fine = cf.FineResult
FROM    UserInfo u
cross apply dbo.CalculateFine(u.UserId, @InsertedDate) cf

其中CalculateFine UDF 包含有关如何将用户详细信息转换为罚款的逻辑。

使用 UDF 是这样的:

 CREATE FUNCTION CalculateFine (@UserId varchar(50), @CurrentDate datetime)
 RETURNS money
 AS
 BEGIN

--TODO  get expected return date ExpectedReturnDate from CurrentlyIssuedBook for that @UserId

--TODO Do you need all these delcarations?
DECLARE @x AS INT
DECLARE @fine AS MONEY
DECLARE @y AS INT
DECLARE @z AS INT

SET @x = DATEDIFF(dd, @CurrentDate, ExpectedReturnDate)
SET @y = @x/30
SET @z = @x%30
-- TODO  convert your logic here....

--Return your answer
RETURN @fine
END

Cant you do something like this:

 CREATE TRIGGER tr_CurrentDateUpdate
   ON  CurrentDate
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    UPDATE  UserInfo
    SET     fine = 6
    WHERE   userid like '%foo%'

    UPDATE  UserInfo
    SET     fine = 7
    WHERE   userid like '%baa%'

END
GO

Where the "where" clauses are your criteria for selecting which users you want to change and the fine = your calculations?

Also, I didnt test this but, if you have your calculation in a UDF I think you could just put something like this where i had my update statements:

DECLARE @InsertedDate Datetime

SELECT  @InsertedDate = date
FROM inserted   

UPDATE  u
SET     u.fine = cf.FineResult
FROM    UserInfo u
cross apply dbo.CalculateFine(u.UserId, @InsertedDate) cf

Where CalculateFine UDF contains the logic on how to convert the user details into their fine.

With a UDF something like this:

 CREATE FUNCTION CalculateFine (@UserId varchar(50), @CurrentDate datetime)
 RETURNS money
 AS
 BEGIN

--TODO  get expected return date ExpectedReturnDate from CurrentlyIssuedBook for that @UserId

--TODO Do you need all these delcarations?
DECLARE @x AS INT
DECLARE @fine AS MONEY
DECLARE @y AS INT
DECLARE @z AS INT

SET @x = DATEDIFF(dd, @CurrentDate, ExpectedReturnDate)
SET @y = @x/30
SET @z = @x%30
-- TODO  convert your logic here....

--Return your answer
RETURN @fine
END
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文