2012-03-10 3 views
14

У меня есть база данных структурирована следующим образом:INSERT INTO, если не существует SQL сервер

пользователи

userid (Primary Key) 
username 

группа

groupid (PK) 
groupName 

user_groups

userid (Foreign Key) 
groupid (Foreign Key) 

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

if (//users table does not contain username) 
{ 
INSERT INTO users VALUES (username); 
} 

Как я могу сделать это разумно с помощью SQL Server/C#?

ответ

19

Или использовать новый синтаксис MERGE:

merge into users u 
using ( 
    select 'username' as uname 
) t on t.uname = u.username 
when not matched then 
    insert (username) values (t.uname); 
+0

Ницца (хотя, вероятно, не требуется, когда рассматривается только одно действие) –

+1

@Damien_The_Unbeliever - Стоит учитывать, когда у вас [высокий параллелизм] (http://dba.stackexchange.com/a/13384/2103). Наверное, не здесь, а у меня +1. –

+0

@MikaelEriksson - вы указываете, что ему все еще нужно «сериализовать», чтобы избежать некоторых проблем. Существует ли какая-то явная разница между этим и другими подходами? –

10

В принципе вы можете сделать это следующим образом:

if NOT exists (select * from user where username = @username) 
    insert into users values (username) 

Но если серьезно, как вы будете знать, если пользователь посетил ваш сайт в первый раз? Вам нужно вставить записи в пользователя таблицы, если кто-то зарегистрируется на вашем сайте, а не в системе.

+0

@Damien_The_Unbeliever, спасибо! – user194076

+4

На полностью боковой ноте - вы заработали более 1 000 оборотов до сих пор - не пора ли выбрать достойное имя? –

+0

Я буду знать, если они регистрируются в первый раз, так как их имя будет в базе данных! На моем сайте нет регистрации; Я использую внешнюю аутентификацию с другого сайта :). Спасибо за ответ! –

3
IF NOT EXISTS (select * from users where username = 'username') 
BEGIN 
    INSERT INTO ... 
END 
0

Вот (наверное, упрощенно) пример, который решает проблему. Обратите внимание, что всегда лучше использовать параметры для предотвращения инъекционных атак, особенно при проверке пользователей.

CREATE PROCEDURE AddUser 
    @username varchar(20) 
AS 
    IF NOT EXISTS(SELECT username FROM users WHERE [email protected]) 
    INSERT INTO users(username) VALUES (@username) 
1

Следующий код представляет собой метод, который возвращает 0, если пользователь уже существует, и возвращает новый пользователь ID который только что добавил:

private int TryToAddUser(string UserName) 
     { 
      int res = 0; 
      try 
      { 
       string sQuery = " IF NOT EXISTS (select * from users where username = @username) \n\r" + 
       " BEGIN \n\r" + 
       "  INSERT INTO users values (@username) \n\r" + 
       " SELECT SCOPE_IDENTITY() \n\r " + 
       " END \n\r " + 
       " ELSE SELECT 0"; 
       using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand()) 
       { 
        cmd.CommandText = sQuery; 
        cmd.Parameters.AddWithValue("@username",UserName); 
        cmd.Connection = new System.Data.SqlClient.SqlConnection("SomeSqlConnString"); 
        cmd.Connection.Open(); 
        res = (int)cmd.ExecuteScalar(); 
        cmd.Connection.Close(); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      return res; 
     } 
3

Я бы сначала создать хранимую процедуру на дБ сделать чек и вставить при необходимости:

CREATE PROCEDURE AddNewUserProc 
(
@username  VarChar(50) -- replace with your datatype/size 
) 

AS 

    IF NOT EXISTS (SELECT * FROM users WHERE username = @username) 
    BEGIN 
     INSERT INTO users 
     VALUES (@username) 
    END 

Затем метод на приложение, которое будет вызывать эту процедуру

public void AddNewUserMethod(string userName) 
{ 
    SqlConnection connection = new SqlConnection("connection string"); 
    SqlCommand command = new SqlCommand("AddNewUserProc", connection); 

    command.CommandType = CommandType.StoredProcedure; 
    command.Parameters.Add("username", SqlDbType.VarChar, 50).Value = userName; 

    try 
    { 
     connection.Open(); 
     command.ExecuteNonQuery(); 
    } 
    finally 
    { 
     if (connection.State == ConnectionState.Open) { connection.Close(); } 
    } 
} 
1

@gbn Ответ на SQL Server 2008 или выше. Я пробовал использовать метод слияния. Уродливо, возможно, но это работает.

declare @user varchar(50) 
set @user = 'username' 
insert into users (username) 
select @user 
where not exists (
select username 
from users 
where username = @user 
); 

Если вы хотите протестировать любой из ответов, вот SQL для таблицы -

CREATE TABLE [dbo].[users](
    [userid] [int] NULL, 
    [username] [varchar](50) NULL 
) 

INSERT [dbo].[users] ([userid], [username]) VALUES (1, N'John') 
INSERT [dbo].[users] ([userid], [username]) VALUES (2, N'David') 
INSERT [dbo].[users] ([userid], [username]) VALUES (3, N'Stacy') 
INSERT [dbo].[users] ([userid], [username]) VALUES (4, N'Arnold') 
INSERT [dbo].[users] ([userid], [username]) VALUES (5, N'Karen') 
Смежные вопросы