2012-03-10 26 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 into users u 
using ( 
    select 'username' as uname 
) t on t.uname = u.username 
when not matched then 
    insert (username) values (t.uname); 
+0

不錯(儘管只考慮一個動作可能不需要) – 2012-03-10 18:32:23

+1

@Damien_The_Unbeliever - 當[高併發](http://dba.stackexchange.com/a/13384/2103)時,值得考慮。這裏可能不是這種情況,而是來自我的+1。 – 2012-03-10 18:38:23

+0

@MikaelEriksson - 你指出它仍然需要'serializable'來避免一些問題 - 那麼這和其他方法之間有一些明顯的區別嗎? – 2012-03-10 18:50:14

10

基本上你可以做這樣的:

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

但嚴重的是,你怎麼會知道,如果用戶訪問您的網站是第一次? 如果有人在您的網站上註冊,而不是登錄,您必須在表格用戶中插入記錄。

+0

@Damien_The_Unbeliever,謝謝! – user194076 2012-03-10 18:21:35

+4

完全側記 - 迄今爲止您已經贏得了超過1K的代表 - 是不是應該選擇一個體面的名字? – 2012-03-10 18:29:27

+0

我會知道他們是否第一次登錄,因爲他們的名字將在數據庫中!我的網站上沒有註冊;我從另一個站點使用外部認證:)。感謝您的迴應! – 2012-03-10 18:32:49

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

以下代碼是如果用戶已經存在並返回新的用戶ID該剛添加的返回0的方法:

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')