Rock, Paper, Scissors, Lizard and Spock - Relational Paradigm
Validate actions

The Action table could use some validation logic:
WinsId and LosesId should be unique together.
You could enforce this with a unique constraint.

But there's more for the game to make sense:


WinsId should not be equal to LosesId
Each WinsId and LosesId should have the same count.
That is, each action should beat and be beaten by the same number of other actions.


Although these conditions are not possible to enforce with constraints,
it would be good to add a helper function that can be used to perform a sanity check easily.

Handling ties

Instead of this:


INSERT INTO @Result
SELECT 'Player 1 Wins!', ...
UNION
SELECT 'Player 2 Wins!', ...

IF NOT EXISTS(SELECT * FROM @Result)
INSERT INTO @Result VALUES ('Tie!','')



I don't have an SQL Server with me to test,
but I think this simpler alternative or similar should work:

INSERT INTO @Result
SELECT 'Player 1 Wins!', ...
UNION
SELECT 'Player 2 Wins!', ...
UNION
SELECT 'Tie', '' WHERE @Player1 = @Player2


Highlight SQL keywords

The common practice is to capitalize SQL keywords, like this:

CREATE TABLE [Hand]
(
     Id INT PRIMARY KEY NOT NULL
    ,Name VARCHAR(20) NOT NULL
)


Use indentation effectively

Good indentation goes a long way to helping readers understand the code.
A block of code like this, overindented and practically flat at the same,
is not really helpful:


insert into @Result
         select 'Player 1 Wins!' as Result, w.Name + ' ' + a.ActionText + ' ' + l.Name as [Text]
         from [Action] a
         join [Hand] w on w.Id = a.WinsId
         join [Hand] l on l.Id = a.LosesId
         where w.Id = @Player1
         and l.Id = @Player2
         UNION
         select 'Player 2 Wins!' as Result, w.Name + ' ' + a.ActionText + ' ' + l.Name as [Text]
         from [Action] a
         join [Hand] w on w.Id = a.WinsId
         join [Hand] l on l.Id = a.LosesId
         where w.Id = @Player2
         and l.Id = @Player1



It would be better this way:

INSERT INTO @Result
SELECT 'Player 1 Wins!' AS Result, w.Name + ' ' + a.ActionText + ' ' + l.Name AS [Text]
    FROM [Action] a
        JOIN [Hand] w ON w.Id = a.WinsId
        JOIN [Hand] l ON l.Id = a.LosesId
    WHERE w.Id = @Player1 AND l.Id = @Player2
UNION
SELECT 'Player 2 Wins!' AS Result, w.Name + ' ' + a.ActionText + ' ' + l.Name AS [Text]
    FROM [Action] a
        JOIN [Hand] w ON w.Id = a.WinsId
        JOIN [Hand] l ON l.Id = a.LosesId
    WHERE w.Id = @Player2 AND l.Id = @Player1


Naming

Single letter table aliases like w, l, a are not very helpful.
It would help understanding this code if you spelled out winner, loser, action.