Отправка SQL логического значения и обновление таблицы как 1 или -1 и как «обновить» пустую строку для начальных значений - PullRequest
0 голосов
/ 02 января 2019

У меня есть таблица Songs со столбцом likes, который содержит количество лайков, отправленных пользователями. Каждый пользователь отправляет логическое значение (1 или 0) через приложение C #, которое добавляет в столбец likes.

О моей процедуре:

  1. Я хочу знать, есть ли более эффективный и короткий способ написания первой части функции?
    Мне пришлось вручную вставить '0' вместо NULL, чтобы функция заработала. Это не работало, потому что начальное значение для столбца Likes NULL. Есть ли способ повлиять на строку в первый раз, когда она имеет значение NULL?

  2. Для части 2 функции с таблицей [Users_Likes_Songs] я хочу обновить, если пользователь отправил лайк (true = 1) или удалил его (false = 0).

    Как я могу обновить эту таблицу в первый раз, когда «лайк» пользователя должен оцениваться как «1», когда его строки полностью пусты?

Я очень благодарен вам, если вы можете мне помочь.

Процедура:

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

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Для 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)
0 голосов
/ 02 января 2019

Я думаю, что лучшим способом было бы изменить ваш дизайн, чтобы вычислять лайки и иметь таблицу, в которой хранятся лайки для каждого пользователя. Проще говоря, что-то вроде:

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
0 голосов
/ 02 января 2019

Вы можете попробовать этот запрос в вашей процедуре

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