发送 SQL 一个布尔值并将 table 更新为 1 或 -1 以及如何 "update" 初始值的空行

Sending SQL a boolean and update a table as 1 or -1 and how to "update" an empty row for the initial values

我有一个 Songs table 和一个 likes 列,其中包含用户发送的点赞数。每个用户通过添加到 likes 列的 C# 应用程序发送一个布尔值(1 或 0)。

关于我的程序:

  1. 我想知道是否有更高效、更简短的方法来编写函数的第 1 部分?
    我必须第一次手动插入“0”而不是 NULL 才能使该功能正常工作。它不起作用,因为 Likes 列的初始值为 NULL。有没有什么办法可以在第一次有 NULL 的时候影响该行?

  2. 对于带有 [Users_Likes_Songs] table 的函数的第 2 部分,如果用户发送了一个赞 (true = 1) 或删除了它 (false = 0),我想更新).

    当用户 'like' 的行完全为空时,我如何第一次更新此 table?

如果你能帮助我,我非常感谢。

程序:

CREATE PROCEDURE Songs_Likes
    @User_ID INT,
    @SongID INT,
    @Song_like BIT
AS
BEGIN
    --- part 1 of the function
    IF (@Song_like = 1)
    BEGIN
        UPDATE [Songs] 
        SET [Likes] = [Likes] + @Song_like
        WHERE [Song_ID] = @SongID
    END

    IF (@Song_like = 0)
    BEGIN
        UPDATE [Songs] 
        SET [Likes] = [Likes] - 1
        WHERE [Song_ID] = @SongID
    END

    --- part 2 of the function with the second table
    UPDATE [Users_Likes_Songs]
    SET [LikeSong] = @Song_like 
    WHERE ([UserID] = @User_ID) AND ([SongID] = @SongID)
END

您可以在您的程序中尝试这个查询

UPDATE [songs] 
SET    [likes] = Isnull ([likes], 0) + ( CASE WHEN @Song_like THEN 1 ELSE -1 END) 
WHERE  [song_id] = @SongID 

对于 1) 这更清晰、更短且更有效。

UPDATE [Songs] 
    SET [Likes] = COALESCE([Likes], 0) + CASE WHEN @Song_like = 1 THEN 1
                                WHEN @Song_like = 0 THEN -1
                                ELSE 0 END
    WHERE [Song_ID] = @SongID;

对于第二部分,您可以这样做:

IF NOT EXISTS (SELECT 1 
    FROM [Users_Likes_Songs] 
    WHERE [UserID] = @User_ID 
    AND [SongID] = @SongID) 

  INSERT INTO [Users_Likes_Songs] (User_ID, SongID, [LikeSong]) 
    VALUES (@User_ID, @SongID, @Song_like)
ELSE
  UPDATE [Users_Likes_Songs]
    SET [LikeSong] = @Song_like WHERE ([UserID] = @User_ID) AND ([SongID] = @SongID)

我认为更好的方法是更改​​您的设计以计算点赞数,并使用 table 为每个用户存储点赞数。简单来说,类似于:

USE Sandbox;
GO

CREATE SCHEMA music;
GO

CREATE TABLE music.song (SongID int IDENTITY(1,1),
                         Artist nvarchar(50) NOT NULL,
                         Title nvarchar(50) NOT NULL,
                         ReleaseDate date);

CREATE TABLE music.[User] (UserID int IDENTITY(1,1),
                           [Login] nvarchar(128));

CREATE TABLE music.SongLike (LikeID bigint IDENTITY(1,1),
                             SongID int,
                             UserID int,
                             Liked bit);

CREATE UNIQUE NONCLUSTERED INDEX UserLike ON music.SongLike(SongID, UserID); --Stops multiple likes
GO

--To add a LIKE you can then have a SP like:

CREATE PROC music.AddLike @SongID int, @UserID int, @Liked bit AS
BEGIN

    IF EXISTS (SELECT 1 FROM music.SongLike WHERE UserID = @UserID AND SongID = @SongID) BEGIN
        UPDATE music.SongLike
        SET Liked = @Liked
        WHERE UserID = @UserID
          AND SongID = @SongID
    END ELSE BEGIN
        INSERT INTO music.SongLike (SongID,
                                    UserID,
                                    Liked)
        VALUES (@SongID, @UserID, @Liked);
    END
END
GO

--And, if you want the number of likes:

CREATE VIEW music.SongLikes AS

    SELECT S.Artist,
           S.Title,
           S.ReleaseDate,
           COUNT(CASE SL.Liked WHEN 1 THEN 1 END) AS Likes
    FROM music.Song S
         JOIN music.SongLike SL ON S.SongID = SL.SongID
    GROUP BY S.Artist,
             S.Title,
             S.ReleaseDate;
GO